Yeah. I have one physicist friend, and as I far I know from casual conversion with them, the whole team at his lab don't even know if they are writing C or C++. And explaining python to him, because he's required to teach a bit of it, was a rabbit hole of explaining fractal things.
My impression is that at least a number of scientists don't know and don't care.
This of course ignores that a bunch of the underlying code for both the R and Python things people use is written in other languages, because they'll never really look at that code.
Are they? I worked with bioinformaticians and now physicists and rust has never come up.
> Köster, now at the University of Duisburg-Essen in Germany, was looking for a language that offered the “expressiveness” of Python but the speed of languages such as C and C++. In other words, “a high-performance language that is still, let’s say, ergonomic to use”, he explains. What he found was Rust.
He must not have looked very far. There are much better options if you're looking for the expressiveness of Python. Personally I'm very fond of Nim.
Nim seems to have adopted a lot of the trappings of rust in the last few years. Sort of weird he didn't see Julia first, as it's explicitly aimed at this group.
Speaking as someone who has built things in python, rust and Julia,I have to say that while I love multiple dispatch and the possibilities the Julia ecosystem offers, I'm not surprised he went to Rust over Julia: it's not much slower to hack in (as in, change some code, try running things, see what breaks, fix) because cargo check will catch a lot of errors before actually running things and you can stub things with "todo!()", but it manages complexity much better (if you lean on the typesystem and your code compiles, it's usually almost done), integrates easier into other ecosystems (cbindgen, pyo3)and the finished product will start up faster
Nim is very niche and doesn't have nearly the reach or possibilities that Rust does. In terms of expressiveness it's not all that different in practice.
Yeh, that tracks with my experience.
I'd imagine nim to be a somewhat nice learning experience if one already is used to python and the indentation. And with nimpy the integration into existing python codebases is pretty smooth sailing.
This article describes pretty much exactly why I turned to Rust for my scientific computing - high speed, far easier to use than C or C++, less bug prone.
Rust has tch-rs - quite descent PyTorch binding. But I still switched to Python due to poor debugging experience in Rust (expression evaluation especially with traits is impossible).
Good question then: how is the "occasianal's programmer" experience compare between Rust and C++?
I used to write games in C++ as a teenager, and using it daily was fine. Now I find, every time I try to write something in it, it's a massive pain, as I forget the myriad of tiny rules, the very specific ways to write types etc. And that's before I even think about dependency management.
Is Rust substantially better at this? When I read frustrations about Rust, it seems to be mostly about the Borrow Checker... does that affect "pedestrian" code, like "take this 4-dimensional array and munge it with an arcane for-loop"? Or, here's a basic immutable class with some fields and some methods, make it available in Python?
I'm liking the look of Nim because it is concise, safe and fast-ish, so a good companion to Python. I dislike C++ as that companion because, even though once you've written your code, it integrates very well with Python, it's a lot of pain to get there. Where would Rust fit in this picture?
Rust users are very enthusiastic about Rust, because it fixes so much annoying shit you have to deal with in C/C++. It really brings back a lot of joy to programming.
The borrow checker is an issue when you are a beginner and have to unlearn all the bad practices you were doing in C/C++.
I would say the borrow checker is an issue if you come from most other mainstream languages, because Rust's approach of trying to automate memory management without having a garbage collector is quite unique.
Also, as a person interested in Rust, but who hasn't yet found the time (and strength of mind) to really commit to learning it: the main difference between C++ and Rust is the cruft that C++ has accumulated over the decades, which Rust doesn't have because it's much younger. But seeing the pace of new features introduced into Rust, I'm a bit worried that some of the older features will soon be declared "non-best practice" and turn into C++-style cruft.
> But seeing the pace of new features introduced into Rust, I'm a bit worried that some of the older features will soon be declared "non-best practice" and turn into C++-style cruft.
Is it just because you see additions of new features in general or there are some specific issues? For me new features do not make 'bad practice' from old ways. As example in older versions you had to be more explicit with lifetimes, but that is just convenience.
Rust's Edition system allows it to deprecate and eventually remove syntax that's now considered a mistake, yet that syntax still exists (forever!) for anybody who doesn't want to learn the modern way to write it.
Let's take two serious C++ proposals I've looked at over the past years and imagine if it had Editions (it doesn't, Vittorio's similar Epochs proposal was shot down and won't be coming back). First a try operator. C++ doesn't have one of these, it would be usual to spell it ? but that's prohibited in C++ by the existence of a ? character as part of the ternary operator ?:. If you had Editions you could abolish ?: in a new Edition or change the way it is parsed so that some weird utterances now don't work because ? is the try operator, without them the proposers instead reluctantly suggest ?? (which is already an operator in some languages and it isn't try...)
Second, pattern matching with _ as a wildcard in the pattern. C++ doesn't do that today. Unfortunately _ is a valid identifier in C++ and people use it. Not a lot of people, but enough for it to be a real pain if this stopped working. So the proposers reluctantly suggest you could write __ in this case. If you had Editions you could forbid _ in a new Edition and in that Edition have the nicer _ while __ is provided in older Editions if they want new pattern matching.
Editions only cover syntax (they're actually mutating the Abstract Syntax Tree at compile time) but because this affords some great opportunities for backward compatible changes, it encourages people to get creative and do even more. For example Rust's arrays learned to be IntoIterator. But that's not a syntax change, so how did that remain compatible? Well, there's a hack, if you have an edition prior to 2021 Edition, then one function from IntoIterator is hidden from resolution by the hack, so that array.into_iter() does what it did in your edition before arrays were IntoIterator. But every other feature works, so you can write "for thing in array", you can pass arrays to functions which need an iterator, and so on, and in newer editions the hack isn't used so array.into_iter() does what you'd expect given arrays are now IntoIterator.
> the main difference between C++ and Rust is the cruft that C++ has accumulated over the decades,
The pace of change in C++ considerably higher. Rust has regular releases, but the changes to the language tend to make it simpler to use as they remove limitations and improve the std.
Also it is not just cruft even if you ignore all the safety that Rust provides by default. The package system and ease of compilation alone makes the jump worthwhile.
> Is Rust substantially better at this? When I read frustrations about Rust, it seems to be mostly about the Borrow Checker... does that affect "pedestrian" code, like "take this 4-dimensional array and munge it with an arcane for-loop"? Or, here's a basic immutable class with some fields and some methods, make it available in Python?
I think language complexity in general is not a problem; language consistency is. I find Rust complex, but not inconsistent or surprising (with exceptions). I'd say that yes, it is substantially better in this regard.
Regarding the "pedestrian code", it depends. Rust is very unergonomic for algorithms, due to its handling of bidirectional references. However, some algorithms/data structures may work fine; the matrix operation you refer to can be very easy to work with, if the elements are Clone/Copy, which numbers are.
I'm a Rust fan, but the article seems to be a puff piece; it takes one case and generalizes it. I also think that Rust is not productive [than other easy, compiled, languages] for generic programming, at least, without significant experience. Relatively small programs (I don't know the size of the typical scientific programs in academia) may be easier, but once a program grows, it definitely requires an amount of design (due to ownership) that other languages don't require.
> I think language complexity in general is not a problem; language consistency is.
With C++ I do find human medium-term cache capacity to be an issue. By the time I use C++ again, I forget some of the many little things I need just to compile a glorified "fizz-buzz". Things like, is this a pointer to a const or a const pointer? What's the syntax for a move/copy constructor? Keeping headers and cpp files in sync. What's the flag to enable modern C++ extensions? How do I write this lambda? Or make a pointer to a function? And so on...
> the article seems to be a puff piece; it takes one case and generalizes it.
Agreed. I write mostly in Rust, but I don't recommend it unless you have a hard problem. If you need C/C++ speed, and there's enough complicated state coordination that you need safe threading and allocation control, Rust is useful. For typical webcrap, use Go. That's the job for which Google created Go.
Python sort of suffers from a lack of reliable fast companions. Here's a rough look of the field:
- Things like Cython... let's just say experience is mixed. IME it is very hard to reason with its performance, and quickly it gets about-as-complex as writing your tight loop in a "natively fast" language.
- C++ is the standard Python companion, and frankly it can integrate amazingly well. You can define types in C++, native C++ functions, and define conversions between C++/Python. Then you can seamlessly make a C++ object in Python, pass it to the function and get the type back. It's not just about the speed, but also about the ability to really merge two languages together. BUT getting to that point is a massive pain of template errors.
- You could do it all in C, manually incrementing and decrementing refcounters. I'll leave it there.
- Other languages like Nim, Fortran and who knows what else seem to offer a limited ability to merge the codebases. You can use them, it seems, as a crutch to patch up some Python slowness here and there, but not as a comprehensive "here's two codebases that live side by side".
- Rust..? Might it be a replacement for C++ here? And is its complexity manageable.
I do not have any experience with C++ and thus none about its python interop, which makes it hard for me to compare it to nim's python interop which I do have some experience with.
Given that, I'm curious what bits of C++/python interop are easier.
I'm mostly asking because my experience of nim-python interop consisted of:
Compile nim module with nimpy imported.
Put compiled nim module somewhere where your python can find it.
write `import <Name_of_module>` in the python file
Done, you now have access to the exported functions and symbols defined in the nim module.
Is it that C++ wouldn't need any additional imports to make it work that makes it more seamless?
Well, I certainly wouldn't call C++/Python interop easy. It is, IMO, verbose, arcane and complex. BUT, once it works, you have truly seamless integration of Python and C++ code. It feels as magical as, say, two languages interacting on JVM or .NET (not that I used either). Or different languages talking through a REST API.
In C++, you'd write your C++ code as if you don't care about Python. Then, you add the "glue" code, which tells C++ how to convert objects to and from Python (there's more options than that but let's leave it here). That, plus a lot of boilerplate. Then, in effect, you can pass objects back and forth between Python and C++, create objects in C++, return them to Python, pass them back to more C++ functions, and so on.
I haven't used Nim+Python; but looking at Nimpy documentation, it looks like, for example, to export a class from Nim to Python, it needs to inherit from a special underlying class. You can't just take a class and make it available in Python. And even then, can you pass that back to Nim to call a function with?
Maybe yes, and if so, that bumps Nim higher up my priority list.
Thanks for the Infos! For context: I used nimpy for a bit for a reimplementation on how Django hashes passwords, making use of one of python's std lib modules.
In terms of seamlessness, I can not confirm that it is exactly like having a python class, merely "fairly close".
If you define a type, you can pass it to python, python can instantiate (with the typical way of Type() ) or even receive instances (if you define e.g. a constructor proc yourself). It can pass the instances back to nim to work with no problem (see e.g. quick example I whipped up: https://pastebin.com/v5wAqGxZ).
However, I have found that there are differences of a nim-type to a pythonclass:
1) In python you do not have direct access to the fields of an instance of a nim-type. You can access them via getters and setters, but you'll get runtime errors if you try to access them directly. To make that behave seamlessly you'd need to define a python wrapper class and hide stuff with @property decorators. Without such a wrapper class you could also not add a field to an instance of a nim-type like you could a normal python object.
2) An imported nim-type can not be inherited from in python (not sure if that works in C++, but at least it's a nim-python-interop limitation).
If you wanted to make a library in nim available in python that wasn't originally intended for the export, you'd likely also need to write a glue-layer in nim. The efffort there would consist mostly in copy pasting the proc signatures you want to make available and annotating them with the export-pragma, copy pasting the nim-type to make it inherit from the type needed for exporting and converting from the exported nim-type to the imported nim-type or vice-versa when jumping from python to nim or vice versa.
Further, to hide the short-comings (that you can't inherit and that you don't have access to fields or can add fields) you'd need to wrap the nim-type in a python-class as described in 1).
My conclusion from what I heard from you so far and what I know of nimpy would be, that nimpy is 90% of the way there, workable but not as seamless, given that exported nim types and their instances aren't functioning exactly like python classes and their instances. Further the fact you'd need to wrap them in a Python class to hide that means, in comparison, extra work to C++ (though that may balance out with if the glue layer in C++ is more involved than the one in nim, I don't know).
> the Borrow Checker... does that affect "pedestrian" code
Unfortunately, the reason why you hear complaints is because it does affect even normal code. Writing code in a setting where you have a strict type system is like writing a mathematical proof. You know that the thing you want to do is safe/correct/valid, but you have to find a way to write it formally, which is itself kind of a puzzle.
Don't get me wrong, I think stricter type systems are the future of programming, except maybe for very high level stuff like Python and Js, but there's definitely some friction involved when the language is a "puzzle language" that insists you do things in a specific way.
With Python or C++, most experienced programmers will be able to bang out just about anything.
With Haskell, Rust, Idris, OCaml and the like, there's this additional step of writing a very detailed math proof that your code is actually allowed. Which makes a lot of sense when you think about those languages' goals.
> Where would Rust fit in this picture?
There's PyO3, not as stable as pybind11 but it's getting there. Honestly Python is just great for stuff like this. You have a lot of ways to gradually speed it up (types -> cython, C++, Rust). It's about as elegant as an octopus made stapling extra legs to a dog, but it's hard to argue it's not effective.
> With Python or C++, most experienced programmers will be able to bang out just about anything.
I think the trade off you often get with Rust compared to C++ is that easy things get harder to do and harder things get easier to do correctly. This won't be true for every problem or person but I think it's a fine rule of thumb. Python is a lot more straightforward than either for most problems of any complexity but of course you don't get the same performance potential where you're not grafting it onto a different language.
I'd say that Rust is better in many regards (the kinds of things you described will mostly Just Work), but there's still enough surface area that you might forget bits if you haven't touched it in a while.
One notable difference, though: in C++, if you forget a detail, you might get a compilation error or you might get a runtime crash and need to pull out something like valgrind. In Rust, if you forget a detail, you're extremely likely to get a compilation error, not a runtime crash.
If you want to hack something fast without frustrations and don't need performance yet, and still use rust, there is a way: just declare your variable mutable, clone() a lot and return values.
Tbh most of the time the borrow checker was easy to use, and at the time (circa 2014) it was allegedly harder to use than it is now, according to a friend who still use it professionally.
>>“No other mainstream languages really have these concepts, and they’re really core to understanding a lot of how you have to write code in Rust,” Nichols says.
I tried Rust, but I am using SPARK2014/Ada for my needs. Easier to learn and has the formal methods/software integrity checks and other niceties. I started learning SPARK2014 while reading the book, "Building High Integrity Applications with SPARK". It was used by the CubeSat lab in Vermont [1], which the book ties in nicely. I can see programmers flocking to Rust, but scientists are not typically computer scientists, and mainstream shouldn't be a highly-weighted metric. I find Rust a lot more heavy than SPARK/Ada. I've tried Julia too, but you can write systems level code in SPARK/Ada too. The adacore site has a lot of great projects and articles on embedded software, drone low-level code rewrite in SPARK, etc.
The partnership between AdaCore and Ferrous Systems is very exciting [2]. I hope to be able to stay with SPARK and gradually learn Rust with this partnership when Rust has a bit more under its belt with real world embedded, high-integrity software like Ada's legacy.
Yeah no, "scientists", this wonderful general category that means nothing and everything, in general, are not turning to Rust.
Programming is a niche. Rust is a, albeit amazing and gaining traction at a fast pace, niche in this niche.
99% of mathematicians, physicists and biologists I have worked with have not even tried programming yet. And if they do, they will start with the stuff their friends are already using: python, fortran, etc.
Hell, 99% of the dev have not heard of rust yet. I go from companies to companies, every time I talk about rust, I have to explain what it is.
It's not even living in a bubble if you think that, it's living in an bubble from another dimension.
Having generalization from anecdotal evidence in nature.com is kinda ironic if you think about it.
Full agreement here. My past experience in the bioinformatics field taught me pretty much that "scientists" at large are just as afraid of the terminal as the average person. The science-folks more specialized on informatics typically are folks focusing on being able to use one language. Not use it well, mind you, just able to produce functional, untested code.
Given that, I highly doubt any of them are even aware of languages beyond python and java and maybe they're aware that C and C++ exists but are scary.
Must be scientists out of school in the past 15 years with the remark about C and C++ being scary, since engineering and science curriculums in the 80s taught Fortran, C, and C++. 'Numerical Recipes: The Art of Scientific Programming', and books like it, were books I turned to do science or engineering. But, I guess you're right, since I learned to program in 1978 on a Commodore PET 2001, computer science and web development have made pushed friendlier languages like Python, Ruby, JavaScript, and so C, C++, and now Rust (I prefer SPARK2014 or Zig), are considered 'scary' for scientists. BLAS (Fortran) and CBLAS (C) are under the hood of all the dressed up Python code up front (Numpy -> CBLAS).
Real Scientists use assembler, C, and Frink! ;)
Sad to say the engineering firm I worked at for 6 years was filled with 20-something and 30-something engineers with only one of 15 of them able to code. Excel use, sure. Coding, no. It wasn't that way 25 years ago.
Agree that "Scientist" means nothing. I assume that they're basically saying "people who used Python already to solve some sort of problem, but are not programmers".
Which is a very small part of the overall "scientist" world I think, who are probably not programming, or who may use matlab or python.
I would expect that new graduates in more or less any numerate subject do some programming these days.
I just looked, we (a major UK university) as well as having a Computer Science department to teach programming to obviously Computer Science and Electronics students as well as related disciplines such as Mathematics, other departments have their own staff teach programming for Physicists, Chemists, Psychologists, Geographers, and a bunch of social scientists who need Statistics. I just asked the API for courses about "programming" and then checked they didn't mean some other type of programming. So if say Law has a course named like "Coding in Javascript" for some reason I wouldn't have seen it.
The most obvious numerate discipline I thought of which doesn't teach programming was Medicine, and I guess they just couldn't find time to add yet another entire discipline's knowledge into the timetable.
A couple of years ago when checking out Rust for scientific work I started looking for familiar ground, e.g. Jupyter notebook support. I was happy to find google/evcxr's Jupyter kernel [1] and started writing an early access book on Rust for data analysis [2].
I still check _Are we learning yet_ [3] to see their recommendation on the state of ML in Rust. It still lists "the ecosystem isn't very complete yet.", which is how I felt at the time!
For everything high-performance in some scientific areas (like bioinformatics in the article), all the heavy number crunching isn't done by Python or R, but by underlying C/C++ libraries. And from having seen some of those libraries, my impression is that many are riddled with memory problems (even more so than other C/C++ code due to the FFI boundary to the wrapping language) and could benefit from being written in Rust.
I worked as a Research Software Engineer, and while I saw the topic come up as a 'that's cool', I never met anyone using it. People writing HPC code are still overwhelmingly using C++ or Fortran, and everyone else is using Python or R. I didn't even come across more than about 2 people in my institution using Julia, despite the hype that it gets.
>But for many Rustaceans, the human element is equally compelling. Hauck, a member of the LGBT+ community, says that Rust users have gone out of their way to make her feel welcome.
Because, when interacting with a programming language community, it's so vitally important to know that they accept what you choose to do with your genitals, in your spare time.
I don't think most straight people are aware just how much of everyday life is peppered with aspects of their sexuality - holding hands, kissing their spouse or partner goodbye, even just referring to them in a gendered way. Growing up closeted, this is something I was acutely aware of every moment of every day.
A welcoming environment for LGBTQ+ people has nothing to do with their genitals, and everything to do with them being able to be genuine and open about themselves without consequence.
I remember many years ago people would start building a scientific ecosystem around Go, but where are all the scientists/engineers using Go now? Eventually people would also realize that Rust is just a bad language choice for building some things, like making games, scientific computing, etc. I expect all this effort to become abandoned. Not everyone wants to invest learning hard to explain memory management concepts and especially engineers are just not interested. For them programming is a tool, not something to be sucked in. I believe Nim on the other hand is a much more realistic choice, with a vibrant scientific community and many fast, high quality and easy to use libraries.
I know someone working on a materials science PhD. He might have to learn python. I could more easily recommend Rust if there were, say, different flavors of Rust, that allow learning the "hard stuff" in stages, but starting with one that uses garbage collection by default. Then, instead of learning python and maybe having to re-learn Rust later--I realize this is less likely, but still--to save time overall, he could learn the "intro level" of Rust now, and expand his Rust skills as need arises, without ever having to restart from scratch to learn a new language, new libraries, etc.
In other words, a step-by-step developer growth process from simple to hard, maybe 2-4 levels, governed by a Cargo.toml setting probably (comparable to a compiler switch), and you never have to throw away what you already learned. Like maybe "learn once, do anything".
(Yes, compatibility with peer group is probably a larger factor. But as an option for some where it fits.)
Is the lack of GC that much of a showstopper for novice learners? If all they're writing is toy programs, they might as well use Rc<...> and accept that cycles will leak.
My general impression is that it is, for many. Rust definitely has a reputation for being harder to learn than Python, for example, which is what I'm suggesting be fixed for one "step" of Rust. The ownership, borrowing, and lifetimes are a hurdle for someone who is almost certainly not going to be a full-time programmer, but needs to program sometimes, and more than toy programs.
I think even Rc might be a barrier, because it looks like more complexity than Pythonistas expect.
54 comments
[ 3.5 ms ] story [ 88.5 ms ] threadIt's a weird article. It seems more like a Rust sales pitch than anything.
My impression is that at least a number of scientists don't know and don't care.
R >>>>>>> Python >> Julia > Everything Else
This of course ignores that a bunch of the underlying code for both the R and Python things people use is written in other languages, because they'll never really look at that code.
> Köster, now at the University of Duisburg-Essen in Germany, was looking for a language that offered the “expressiveness” of Python but the speed of languages such as C and C++. In other words, “a high-performance language that is still, let’s say, ergonomic to use”, he explains. What he found was Rust.
He must not have looked very far. There are much better options if you're looking for the expressiveness of Python. Personally I'm very fond of Nim.
Edit: others mentioned Julia, and it indeed looks like a valid choice since they don’t seem to program embedded or safety-critical stuff.
I like Rust but all the scientists I know work with C++/Python (PyTorch) nowadays due to that.
I used to write games in C++ as a teenager, and using it daily was fine. Now I find, every time I try to write something in it, it's a massive pain, as I forget the myriad of tiny rules, the very specific ways to write types etc. And that's before I even think about dependency management.
Is Rust substantially better at this? When I read frustrations about Rust, it seems to be mostly about the Borrow Checker... does that affect "pedestrian" code, like "take this 4-dimensional array and munge it with an arcane for-loop"? Or, here's a basic immutable class with some fields and some methods, make it available in Python?
I'm liking the look of Nim because it is concise, safe and fast-ish, so a good companion to Python. I dislike C++ as that companion because, even though once you've written your code, it integrates very well with Python, it's a lot of pain to get there. Where would Rust fit in this picture?
The borrow checker is an issue when you are a beginner and have to unlearn all the bad practices you were doing in C/C++.
Also, as a person interested in Rust, but who hasn't yet found the time (and strength of mind) to really commit to learning it: the main difference between C++ and Rust is the cruft that C++ has accumulated over the decades, which Rust doesn't have because it's much younger. But seeing the pace of new features introduced into Rust, I'm a bit worried that some of the older features will soon be declared "non-best practice" and turn into C++-style cruft.
Is it just because you see additions of new features in general or there are some specific issues? For me new features do not make 'bad practice' from old ways. As example in older versions you had to be more explicit with lifetimes, but that is just convenience.
Let's take two serious C++ proposals I've looked at over the past years and imagine if it had Editions (it doesn't, Vittorio's similar Epochs proposal was shot down and won't be coming back). First a try operator. C++ doesn't have one of these, it would be usual to spell it ? but that's prohibited in C++ by the existence of a ? character as part of the ternary operator ?:. If you had Editions you could abolish ?: in a new Edition or change the way it is parsed so that some weird utterances now don't work because ? is the try operator, without them the proposers instead reluctantly suggest ?? (which is already an operator in some languages and it isn't try...)
Second, pattern matching with _ as a wildcard in the pattern. C++ doesn't do that today. Unfortunately _ is a valid identifier in C++ and people use it. Not a lot of people, but enough for it to be a real pain if this stopped working. So the proposers reluctantly suggest you could write __ in this case. If you had Editions you could forbid _ in a new Edition and in that Edition have the nicer _ while __ is provided in older Editions if they want new pattern matching.
Editions only cover syntax (they're actually mutating the Abstract Syntax Tree at compile time) but because this affords some great opportunities for backward compatible changes, it encourages people to get creative and do even more. For example Rust's arrays learned to be IntoIterator. But that's not a syntax change, so how did that remain compatible? Well, there's a hack, if you have an edition prior to 2021 Edition, then one function from IntoIterator is hidden from resolution by the hack, so that array.into_iter() does what it did in your edition before arrays were IntoIterator. But every other feature works, so you can write "for thing in array", you can pass arrays to functions which need an iterator, and so on, and in newer editions the hack isn't used so array.into_iter() does what you'd expect given arrays are now IntoIterator.
The pace of change in C++ considerably higher. Rust has regular releases, but the changes to the language tend to make it simpler to use as they remove limitations and improve the std.
Also it is not just cruft even if you ignore all the safety that Rust provides by default. The package system and ease of compilation alone makes the jump worthwhile.
I think language complexity in general is not a problem; language consistency is. I find Rust complex, but not inconsistent or surprising (with exceptions). I'd say that yes, it is substantially better in this regard.
Regarding the "pedestrian code", it depends. Rust is very unergonomic for algorithms, due to its handling of bidirectional references. However, some algorithms/data structures may work fine; the matrix operation you refer to can be very easy to work with, if the elements are Clone/Copy, which numbers are.
I'm a Rust fan, but the article seems to be a puff piece; it takes one case and generalizes it. I also think that Rust is not productive [than other easy, compiled, languages] for generic programming, at least, without significant experience. Relatively small programs (I don't know the size of the typical scientific programs in academia) may be easier, but once a program grows, it definitely requires an amount of design (due to ownership) that other languages don't require.
With C++ I do find human medium-term cache capacity to be an issue. By the time I use C++ again, I forget some of the many little things I need just to compile a glorified "fizz-buzz". Things like, is this a pointer to a const or a const pointer? What's the syntax for a move/copy constructor? Keeping headers and cpp files in sync. What's the flag to enable modern C++ extensions? How do I write this lambda? Or make a pointer to a function? And so on...
Agreed. I write mostly in Rust, but I don't recommend it unless you have a hard problem. If you need C/C++ speed, and there's enough complicated state coordination that you need safe threading and allocation control, Rust is useful. For typical webcrap, use Go. That's the job for which Google created Go.
- Things like Cython... let's just say experience is mixed. IME it is very hard to reason with its performance, and quickly it gets about-as-complex as writing your tight loop in a "natively fast" language.
- C++ is the standard Python companion, and frankly it can integrate amazingly well. You can define types in C++, native C++ functions, and define conversions between C++/Python. Then you can seamlessly make a C++ object in Python, pass it to the function and get the type back. It's not just about the speed, but also about the ability to really merge two languages together. BUT getting to that point is a massive pain of template errors.
- You could do it all in C, manually incrementing and decrementing refcounters. I'll leave it there.
- Other languages like Nim, Fortran and who knows what else seem to offer a limited ability to merge the codebases. You can use them, it seems, as a crutch to patch up some Python slowness here and there, but not as a comprehensive "here's two codebases that live side by side".
- Rust..? Might it be a replacement for C++ here? And is its complexity manageable.
Given that, I'm curious what bits of C++/python interop are easier.
I'm mostly asking because my experience of nim-python interop consisted of: Compile nim module with nimpy imported. Put compiled nim module somewhere where your python can find it. write `import <Name_of_module>` in the python file Done, you now have access to the exported functions and symbols defined in the nim module.
Is it that C++ wouldn't need any additional imports to make it work that makes it more seamless?
In C++, you'd write your C++ code as if you don't care about Python. Then, you add the "glue" code, which tells C++ how to convert objects to and from Python (there's more options than that but let's leave it here). That, plus a lot of boilerplate. Then, in effect, you can pass objects back and forth between Python and C++, create objects in C++, return them to Python, pass them back to more C++ functions, and so on.
I haven't used Nim+Python; but looking at Nimpy documentation, it looks like, for example, to export a class from Nim to Python, it needs to inherit from a special underlying class. You can't just take a class and make it available in Python. And even then, can you pass that back to Nim to call a function with?
Maybe yes, and if so, that bumps Nim higher up my priority list.
In terms of seamlessness, I can not confirm that it is exactly like having a python class, merely "fairly close". If you define a type, you can pass it to python, python can instantiate (with the typical way of Type() ) or even receive instances (if you define e.g. a constructor proc yourself). It can pass the instances back to nim to work with no problem (see e.g. quick example I whipped up: https://pastebin.com/v5wAqGxZ).
However, I have found that there are differences of a nim-type to a pythonclass:
1) In python you do not have direct access to the fields of an instance of a nim-type. You can access them via getters and setters, but you'll get runtime errors if you try to access them directly. To make that behave seamlessly you'd need to define a python wrapper class and hide stuff with @property decorators. Without such a wrapper class you could also not add a field to an instance of a nim-type like you could a normal python object.
2) An imported nim-type can not be inherited from in python (not sure if that works in C++, but at least it's a nim-python-interop limitation).
If you wanted to make a library in nim available in python that wasn't originally intended for the export, you'd likely also need to write a glue-layer in nim. The efffort there would consist mostly in copy pasting the proc signatures you want to make available and annotating them with the export-pragma, copy pasting the nim-type to make it inherit from the type needed for exporting and converting from the exported nim-type to the imported nim-type or vice-versa when jumping from python to nim or vice versa. Further, to hide the short-comings (that you can't inherit and that you don't have access to fields or can add fields) you'd need to wrap the nim-type in a python-class as described in 1).
My conclusion from what I heard from you so far and what I know of nimpy would be, that nimpy is 90% of the way there, workable but not as seamless, given that exported nim types and their instances aren't functioning exactly like python classes and their instances. Further the fact you'd need to wrap them in a Python class to hide that means, in comparison, extra work to C++ (though that may balance out with if the glue layer in C++ is more involved than the one in nim, I don't know).
Unfortunately, the reason why you hear complaints is because it does affect even normal code. Writing code in a setting where you have a strict type system is like writing a mathematical proof. You know that the thing you want to do is safe/correct/valid, but you have to find a way to write it formally, which is itself kind of a puzzle.
Don't get me wrong, I think stricter type systems are the future of programming, except maybe for very high level stuff like Python and Js, but there's definitely some friction involved when the language is a "puzzle language" that insists you do things in a specific way.
With Python or C++, most experienced programmers will be able to bang out just about anything.
With Haskell, Rust, Idris, OCaml and the like, there's this additional step of writing a very detailed math proof that your code is actually allowed. Which makes a lot of sense when you think about those languages' goals.
> Where would Rust fit in this picture?
There's PyO3, not as stable as pybind11 but it's getting there. Honestly Python is just great for stuff like this. You have a lot of ways to gradually speed it up (types -> cython, C++, Rust). It's about as elegant as an octopus made stapling extra legs to a dog, but it's hard to argue it's not effective.
I think the trade off you often get with Rust compared to C++ is that easy things get harder to do and harder things get easier to do correctly. This won't be true for every problem or person but I think it's a fine rule of thumb. Python is a lot more straightforward than either for most problems of any complexity but of course you don't get the same performance potential where you're not grafting it onto a different language.
One notable difference, though: in C++, if you forget a detail, you might get a compilation error or you might get a runtime crash and need to pull out something like valgrind. In Rust, if you forget a detail, you're extremely likely to get a compilation error, not a runtime crash.
Tbh most of the time the borrow checker was easy to use, and at the time (circa 2014) it was allegedly harder to use than it is now, according to a friend who still use it professionally.
I tried Rust, but I am using SPARK2014/Ada for my needs. Easier to learn and has the formal methods/software integrity checks and other niceties. I started learning SPARK2014 while reading the book, "Building High Integrity Applications with SPARK". It was used by the CubeSat lab in Vermont [1], which the book ties in nicely. I can see programmers flocking to Rust, but scientists are not typically computer scientists, and mainstream shouldn't be a highly-weighted metric. I find Rust a lot more heavy than SPARK/Ada. I've tried Julia too, but you can write systems level code in SPARK/Ada too. The adacore site has a lot of great projects and articles on embedded software, drone low-level code rewrite in SPARK, etc.
The partnership between AdaCore and Ferrous Systems is very exciting [2]. I hope to be able to stay with SPARK and gradually learn Rust with this partnership when Rust has a bit more under its belt with real world embedded, high-integrity software like Ada's legacy.
[1] http://cubesatlab.org/
[2] https://ferrous-systems.com/blog/ferrous-systems-adacore-joi...
Programming is a niche. Rust is a, albeit amazing and gaining traction at a fast pace, niche in this niche.
99% of mathematicians, physicists and biologists I have worked with have not even tried programming yet. And if they do, they will start with the stuff their friends are already using: python, fortran, etc.
Hell, 99% of the dev have not heard of rust yet. I go from companies to companies, every time I talk about rust, I have to explain what it is.
It's not even living in a bubble if you think that, it's living in an bubble from another dimension.
Having generalization from anecdotal evidence in nature.com is kinda ironic if you think about it.
Given that, I highly doubt any of them are even aware of languages beyond python and java and maybe they're aware that C and C++ exists but are scary.
Real Scientists use assembler, C, and Frink! ;)
Sad to say the engineering firm I worked at for 6 years was filled with 20-something and 30-something engineers with only one of 15 of them able to code. Excel use, sure. Coding, no. It wasn't that way 25 years ago.
Which is a very small part of the overall "scientist" world I think, who are probably not programming, or who may use matlab or python.
I just looked, we (a major UK university) as well as having a Computer Science department to teach programming to obviously Computer Science and Electronics students as well as related disciplines such as Mathematics, other departments have their own staff teach programming for Physicists, Chemists, Psychologists, Geographers, and a bunch of social scientists who need Statistics. I just asked the API for courses about "programming" and then checked they didn't mean some other type of programming. So if say Law has a course named like "Coding in Javascript" for some reason I wouldn't have seen it.
The most obvious numerate discipline I thought of which doesn't teach programming was Medicine, and I guess they just couldn't find time to add yet another entire discipline's knowledge into the timetable.
I still check _Are we learning yet_ [3] to see their recommendation on the state of ML in Rust. It still lists "the ecosystem isn't very complete yet.", which is how I felt at the time!
[1] https://github.com/google/evcxr/tree/main/evcxr_jupyter
[2] https://datacrayon.com/shop/product/data-analysis-with-rust-...
[3] https://www.arewelearningyet.com
Rust is totally irrelevent in this context.
A welcoming environment for LGBTQ+ people has nothing to do with their genitals, and everything to do with them being able to be genuine and open about themselves without consequence.
In other words, a step-by-step developer growth process from simple to hard, maybe 2-4 levels, governed by a Cargo.toml setting probably (comparable to a compiler switch), and you never have to throw away what you already learned. Like maybe "learn once, do anything".
(Yes, compatibility with peer group is probably a larger factor. But as an option for some where it fits.)
I think even Rc might be a barrier, because it looks like more complexity than Pythonistas expect.