5 ms·
Rust is certainly not the last word in systems programming languages, but it's an huge leap forward from C and C++. To be honest, it's a sad reflection of our i
by noelwelsh 2y ago
Rust is certainly not the last word in systems programming languages, but it's an huge leap forward from C and C++. To be honest, it's a sad reflection of our industry that it's taken this long to get basic safety + ML circa 1975 language features into this niche. If things had turned out a little bit different we could all have been using OCaml for the past few decades.
- fire_lake 2y agoPeople reject OCaml for these use cases due to the GC, but I wonder if this actually matters in practice. The optimizations that can be applied to ML languages (see MLTon for example) are very advanced and the ability to do multi core with ease (I know this is more recent to OCaml) can be a big performance unlock that is very hard to get right in C.
- pornel 2y agoGC is perfectly fine for ~99% of applications, which is why all the languages in the last few decades adopted it, and eliminated themselves from being direct C/C++ competitors. Lack of GC isn't a requirement for most programs. However, it is a requirement for a language meant to actually replace C and C++, because these two are mostly used in the remaining fraction of programs and libraries where any GC or any fat runtime is undesirable. Even where some GC could be made to work, it makes it a tough sell for C/C++ users.
- dgrunwald 2y agoThe GC does matter. Most applications are completely fine with having a garbage collector, but they are not fine with having multiple garbage collectors! Mixing multiple garbage collected languages is a recipe for complex bugs. At a minimum, reference cycles across the languages will result in memory leaks. Thus every garbage collected language tends to grow its own ecosystem of libraries, with the whole world having to be re-implemented in that language. The only exception are the C/C++/Rust libraries, as these can be used (through C FFI interface) by almost every other language. This is precisely because these languages do not introduce their own heavy-weight runtime (especially: no GC), allowing them to be combined with another language's runtime. Thus widely used libraries must be written in one of the non-GC languages, even if 100% of the applications using them are fine with having a garage collector.
- bryanlarsen 2y agoI see this same situation playing out with async executors. tokio is taking over, but it doesn't play well with other async executors. I just wrote a program that mixed tokio & glib and it wasn't fun. This does feel like a soluble problem, so I hope they do figure it out. I think the first step might be something like without.boats' proposal to add something like https://github.com/zesterer/pollster https://github.com/zesterer/pollster to the standard library to establish a minimum common denominator.
- begueradj 2y ago> it's a sad reflection of our industry that it's taken this long to get basic safety + ML circa 1975 language features into this niche. That's true. Could it be that's because we are expert at nitpicking every programming language, every framework and stack which appears to the point it takes time to make steps forward ? Some sort of paralysis, insecurity and confusion ?
- jltsiren 2y agoMy favorite hypothesis here is that programming language enthusiasts are too different. They are incapable of convincing the average programmer of the merits of their favorite language, because their way of thinking is different. Arguments they find convincing are not convincing to the average programmer. Progress happens incrementally with small steps. Existing languages get new features. New languages get popular, because they look familiar but contain some small meaningful improvements. And familiarity is important. Languages like OCaml never become popular, because they are too different. Even the syntax looks unfamiliar.
- DEADMINCEDOS 2y agoI think you're right. The same way people have strong preference for Systemd, MacOS, KDE, Gnome, I3, Nix, Debian, Gentoo, Arch, etc. So many different solutions. Most are preferred because of subjective reasons (although sometimes just poor reasoning period), because people think so drastically differently.
- throwawaymaths 2y ago> Existing languages get new features That's how you wind up with C++
- jltsiren 2y agoOr English. A lot of people used to advocate for using their favorite ancient / artificial languages in international contexts and for communicating important matters. But somehow the C++ of natural languages became dominant.
- falcolas 2y ago> Arguments they find convincing are not convincing to the average programmer I think one problem is believing there exists an "average programmer". It's easy to think in averages (or medians), but the reality is that there is no average person, and exactly one median person. Realizing that every single person is different is important, because you then start to work in more discrete niches. It's going to be much easier to appeal to "programmers who write X in Y with the following constraints" than it will ever be "programmers who write in Y". Or to bring this closer to the topic of discussion, you'll never convince game developers to drop C++ in favor of rust using the same arguments as you'd use to convince a service developer to drop C++ for rust.
- fxtentacle 2y agoSadly, Rust is only a "huge leap forward from C and C++" for some use-cases. Simple things like returning a const reference to a slot in an immutable array are easily 10x the amount of source code in Rust when compared to C. And all the standard libraries for embedded systems are C, so to get into embedded development, you definitely need to be good at reading C code. Rust is an additional skill, but if you only know Rust and no C, you're of no use in embedded land. I think that's the main reason why we don't move away from C: You still need a firm grasp of C if you want to be a capable higher-level developer. C++ is then the logical upgrade because it's compatible with C and looks very similar. Java also did OK because it looks and feels very similar. And there's good automated C to Java converters. So you get the benefits of Java over C almost for free. Rust, on the other hand, throws away most of the C conventions and that makes it feel foreign and "incompatible". Rust also suffers from a serious "not invented here" problem, in my opinion. It's super easy to re-use C code in C++ or Java. It's significantly more difficult to re-use C in Rust unless you go unsafe and abandon most of the Rust advantages. That means most dependencies need to be re-implemented in Rust if you want to have all the advantages that Rust offers. Go had the same problem, but they had Google's weight behind them to push out tons of libraries. Who is doing that for Rust? In the end, I agree with the article: Rust is great! when it fits. But there are still plenty of situations left where Rust is worse than old-school C.
- goku12 2y ago> Rust also suffers from a serious "not invented here" problem, in my opinion. It's super easy to re-use C code in C++ or Java. It's significantly more difficult to re-use C in Rust ... It feels like a mischaracterization of Rust and I strongly disagree. Both the language and tooling are designed from the beginning for interop with C code. It isn't very hard to do if you have tried it. > ... unless you go unsafe and abandon most of the Rust advantages. That means most dependencies need to be re-implemented in Rust if you want to have all the advantages that Rust offers. This 'Rust is useless if you use unsafe' is a stance that is well debunked, but still gets repeated like this. Ensuring safety using Rust semantics across an FFI with a language like C is impossible - making unsafe necessary. But just because you use unsafe doesn't mean that the language lost most of its advantages. In fact, almost every Rust program uses unsafe code, if you care to look at the code in the standard library. Yet, that never seems to be a problem. What unsafe does is to cordon off a small code area where certain invariants have to be asserted manually, instead of relying on the borrow checker. You still get the safety for the rest of the code. In case you do get safety violations, there is much less code to debug. This is a significant advantage over languages like C++, considering that unsafe blocks are usually less than 5% of the code, even in the worst case. But to take it further, C libraries often have corresponding Rust wrapper libraries that create safe wrappers over C FFI calls. In addition to the small unsafe blocks to verify manually, these wrappers have the additional advantage of being widely used and debugged by a wider community. There are innumerable such wrappers on crates.io and it's uncharitable to accuse the language of NIH syndrome.