Ask HN: Why do you use Rust, when D is available?
D supports Ownership and Borrowing, just like Rust. DMD, D's reference compiler, can compile itself in less than 5 seconds, thanks to a fast frontend and fast backend. D is easy to metaprogram through traits and templates. You can make your own JIT in D with dynamicCompile.
I'd love to hear some reasons why so D and Rust can learn from each other.
264 comments
[ 3.2 ms ] story [ 287 ms ] threadThis is not criticism of the D language, programming languages are like startups, success often has little to do with the product itself but more the ecosystem, funding, and luck.
Eh, I would describe go's tooling as "minimalist" or, less charitably, as "barely adequate." Pre-modules the global GOPATH approach was hacky and ugly, and post-modules the go command is a mess of contradictions straining against the backwards compatibility guarantee. And editor integration back in the day wasn't much more than running go fmt and go build.
If I want to pick a subset of features, I'd probably pick C++. Or, if I'm willing to use a GC and runtime, then there's lots of languages to choose from.
I use Rust if I want "safety" and no GC and that's all I get.
This is my impression. But I know very little of D so do not judge the language based on my impressions.
Granted, I'm not very familiar with D. I didn't even know it had a borrow checker.
Rust took a lot of great features from Haskell, while keeping itself reasonably approachable from a C/C++/D/Java programmer's perspective.
Rust put type names after variable/function/parameter names, which really cleans up the syntax nicely.
Rust has very nice syntax for pattern matching, monads, and a slew of other really helpful functional language features.
Even if rust didn't have a borrow checker, it would still be a wonderful systems programming language.
Type names after variable or before? When you think about declaring a variable, do you think about its type of name first? I can't imagine you do the latter because "Hmm, I need an array of doubles to represent my tensor" is double[][] tensor; and not tensor: double[][]. Besides the types after names end up being more verbose in the languages which adopt the scheme (hello Scala).
I invite you to get familiar with D syntax to see a wider picture.
The borrow checker in D is WIP and given how much stir it created, I don't see it's happening any time soon.
In any case, as a Scala dev, I wish the compile times were as short as in Rust!
I completely disagree with your opinion on this subject, though I recognize that it's mostly subjective. I think types after the variable are completely better except for my muscle memory from C.
Since I am not familiar with Scalia, I am not sure why the types after the name would end up being more verbose, as far as I can tell the only difference is the : between the variable and its type. Would you mind expanding on that?
Personally although Rust definitely does not have the elegance of Haskell or Python, I definitely would not call it ugly. There aren’t that many symbols and once you actually spend the time to learn the language the semantics for each syntax element are pretty easy to remember. I also have looked at D, but the lack of algebraic data types makes it a non-starter for me.
You can just as equally think of it as, "I need my tensor to be an array of doubles".
That works much more cleanly with type inference, because the type is more of an annotation, and you can drop it without adding the boilerplate word "auto".
> Subjectively ugly and polluted with punctuation symbols that tell you little about their semantics.
Like what?
Also, having "let" at the beginning of the line makes it immediately clear that it's a variable definition, whereas if it starts with some arbitrary type I haven't seen before I have to spend more time figuring out what's happening. Good syntax highlighting helps, but I think starting with types like C/C++/D is less elegant than starting off with a keyword that clearly identifies what the line does.
Similar applies for function definitions. It's nice when the function names are all lined up and not buried halfway across the screen because it has some long return type.
double[] arr;
bam! Simple and clear.
What about functions? It has input, name and output and D nicely presents you with
double[] createArray(int size) {...}
This is as little typing as you can get while keeping readability.
And here is a basic Rust function
fn add_one(x: i32) -> i32 {...}
What kind of type is i32 btw? oh, there is u32 as well. integer 32bit and unsigned 32bit? What on earth are these? Ah, this is just D's size_t, the same size_t as in C/C++. So that C/C++ ppl have zero overhead reading D code and for Rust they will google. To top that, you have also -> because of the type after the definition scheme. Needless verbosity, same thing in Scala.
What about Rust unable to drop parenthesis after a function?
self.host_addr.clone()
Should I mention Rust's UFCS?
But I am nitpicking, right. This doesn't make a language bad in any way. However, as I said, Rust readability is pretty subpar in addition to already steep language learning curve.
Also, I find i32 and u32 types much cleaner than D's "unsigned int" and "int". What is the difference between "unsigned int" and "unsigned long" in D? It's still better than C++, but I'd rather write i32 and i64 rather than "int" and "long".
Rust has usize [0] as a size_t equivalent.
[0]: https://doc.rust-lang.org/std/primitive.usize.html
Usually, the reason is to make parsing easier. C++ is infamous for having undecidable grammar. Ruby is extremely pleasing to the eye, but its grammar is a clusterfuck. Newer languages have learned from that, so they try to have simpler grammars.
Another reason for those small syntax markers is to avoid implicit language decisions. In Rust, having to write one of "let/let mut/const" means forcing the programmer to make an explicit choice regarding mutability and memory usage. In Scala, "val/lazy val/var/lazy var/def" means having to think about mutability and evaluation times.
> What about Rust unable to drop parenthesis after a function?
In the case of Rust, the reason is uniformity. Even Scala, of all languages, is walking back on the optional parentheses, because the language allows to define functions with multiple argument lists, and optional parentheses introduce ambiguity between functions with empty argument lists and functions with no argument lists.
"optional parentheses introduce ambiguity" -- true, they do. However, I am struggling to understand why it is necessarily a bad thing? For a user I see a clear convenience of being able to write "double[] zeroArr = arr.zeros;" or "double[] newArr = 6.iota.sliced(3, 2).array.reverse.dropOne.join;". And if that is not enough, you can also inject your custom method into this chain and it will just work. Don't know about Rust but Scala simply refuses to compile in such cases which for a functional language looks like a limitation.
These are the D features that I really enjoy.
I think this is where Rust falls apart. In things like C, more features requires writing more C code. In Rust, more features requires learning more syntax features.
My opinion is generally the opposite, that simple decisions like putting type annotations after names, etc. make it so each unavoidable complexity in syntax has its own home, instead of piling together like C++/Java/etc.
In the tutorial, the language looks quite nice, comparable to Python. But in production level code, there are {.pragmas.} in a lot of places and they are not just advice for the compiler that can be ignored: they are important keywords that don't pollute the identifier space.
Another beef I had is that slice ranges and for loops are closed intervals by default. This is contrary to both Python and C, and while there is a syntax a..<b to be open on the right, it seems like a bad decision to be different from C and Python by default. It reminded me of Julia arrays starting at 1 by default. I guess I can see that if your audience is Fortran programmers, but arrays haven't started at 1 in a new language for a long time afaik.
I wish Nim had a goal of being a typed, compiled Python. But I don't think that ever was a main goal and now it's sort of too late because the language has a very wide scope (my opinion) and has compatibility concerns with all of its previous design choices.
As a programmer who first used Python than C++, I don't find types after or before any nicer or worse.
As for Monads, you could write a template that wraps a pure function that creates side effects through its arguments into a Monad rather easily.
As for pattern matching, you can do that by writing your own template too.
The fact that Firefox uses Rust for the browser engine or that Dropbox uses Rust for the sync engine is the kind of thing that gets me interested.
Is that actually true?
I'm not trying to knock you, but your comment reminds me of the type of exchanges where one person says says "men do a lot of work", and the other person replies "are you saying women are lazy?"
I took that as saying D could compile itself in 5 seconds too. I was impressed. Bubble bursted.
If it's been around for 2 decades and hardly has any adoption by large companies[0] I personally am not willing to learn it (unless that changes).
I'm not necessarily using adoption as a proxy for quality either. If there isn't any meaningful adoption it's not like I can join a company to write it or have an easy time convincing my manager to try it. It could be the greatest language on earth but if I can't write it then it doesn't matter.
[0]: https://dlang.org/orgs-using-d.html
There's always people that are fascinated by new languages but I feel this is likely a minority. I think people want to learn languages they know will be useful.
The financial industry makes heavy use of K, which is closely related to J. It's not open source or free to use for commercial use, however.
In general, they all had a big institution. I presume these provided a a few ingredients, like
* A strong urge to solve a real-world problem
* A cradle, where smart people had time and resources to build a basic core
* A broadcast platform as others would look up to the institution, and notice what they were doing
From the top of my head, perl and python don't fit in this pattern, so its not universal, but I would dare to call it common.
With that being said fast compilation times are amazing and must be a default in new languages. If not they should follow an approach like Dart where there is a VM for development and also a AOT compilation support for producing binaries.
Explained further here - https://jason-williams.co.uk/a-possible-new-backend-for-rust
People who use Rust aren't using it to solve real world problems, they're using it to scratch a novelty itch.
D is a tragedy in my opinion. It's an excellent language that just doesn't fit the political needs of any of the big players.
We have Swift which is a worse version of C#, we have Go, we have Java. Why don't we have a single language so that we can do cross platform development and abandon web browsers and javascript? Because politics. Every company needs to toot its own horn and suck up smart intelligent people so that they don't create a real competitor, and so we have a dozen languages that share 95% of the features and are all incompatible with one another and no one sane enough to say this is crazy, I'm going to take my FAANG money, move to a place with cheap rent and put an end to this madness.
It's only a game developer of all people, Jonathan Blow, that's doing it and his creation is a C++ replacement for games, not general purpose software. Sigh.
I think if it wasn't tied to the JVM ecosystem, it probably would have seen a lot more success outside of server side stuff. The long bootstrapping startup really is a killjoy. Then again, a lot of the type that made it popular in the first place came from being a part of the JVM ecosystem.
What does that even mean? What do you lack in regards to cross-platform from Java / Rust / Nim / Go / Python / Ruby / Haxe / ...? (I'm assuming cross-platform here means desktops, not microprocessors)
Specifically, yes, there are things that you may miss in every one of them, but it's not like we don't have the option to use them. What's the point in complete unification in the first place?
Just like Zig not parsing tabs or carriage returns or V being broken on windows and never fixed, I don't think it is corporate sponsorship that is the problem, but more basic utility.
Plenty of people are trying these new languages, the demand is there, but there is usually some huge blind spot that they don't deal with until it is too late and they have already burned a lot of people that gave them their attention.
We do, we have dozens of them, C, C++, java, ruby, python, c# to name a few. We have at least a half dozen cross platform GUI toolkits to go with them, Qt, Gtk, swing, wxWidgets, tk. Pick whatever poison you want, they're all much better than electron.
I suspect you're right about rust though, something newer and shinier will come along soon, if it hasn't already.
Like a browser? Or google's fuchsia?
Have some fun: https://www.rust-lang.org/production/users
You know what WASM is?
There are precisely 0 job openings looking for Rust developers in my city, and I live in a city with millions of people.
To me, that's the real world where real people solve real world problems.
To me, when 0 people are hiring for Rust in a city in North America where there are maybe 10 other cities bigger than the one I live in, real problems aren't being solved using this language.
Sorry, that's empirical evidence, not opinion.
I understand that in a few places, people are using Rust and some are even getting paid to do it. I call that scratching the novelty itch - I'm sorry if my use of language offends your sensibilities, we'll have to learn to live with that somehow :)
Problems are technical, hiring is something completely different.
I live in a really small city and found 3 offers for Rust and 7 for Go (some of them are 'bonus points')...in Europe..and none of them are GAFA related.
But yes, it's a new language, java c/c++ is not.
here's one notable one https://onesignal.com/blog/rust-at-onesignal/
That would still be huge. C++ keeps being used because of games. There's little to no C++ software being written nowadays that's not games.
And games are a gigantic industry, bigger than the film and music industries combined.
Many game developers would love the simplicity of D if there was a framework like Unreal but in D.
You need to look around more, because you are totally wrong on this point. It's true that C++ isn't used a lot in web programming, and web programming is what a lot of people see these days. But there is a lot more software being written than web programming and games, and C++ is still in fairly significant use.
So please, instead of being snarky, do something useful and show me some of this software!
But embedded is maybe 10% of code. Where else is it used? I'm not as sure of that, but the TIOBE index indicates that it's used pretty heavily.
I'm outside of that world, but I think that high-performance computing sometimes uses C++, because controlling memory alignment is a big deal there, and C++ does that pretty well.
The origin story of Go says that Google has a lot of C++, but that was a decade ago. I can't speak to how much new C++ is being written there.
Perhaps one way of looking at it would be to look at the membership of the C++ standards committee, and subtracting the language vendors. The rest are users.
Rather we get to write the applications in some managed language, and C++ only gets used for some performance critical libraries, or GPGPU programming.
And naturally their own build tool, debugging representations and IDE plugins.
The same goes for go-lang. It throws away years of research into programming languages. While rust is a great language and deserve the popularity, do you think go would have peaked in popularity if there weren't rob-pike-san and google behind it.
It's not a matter of features for programming languages popularity. It's who is backing them and doing the work to unite the community.
Programming communities also need to be aggressively cultish to take off in the beginning. You must be able to bite everyone's same repeated rehashed argument about lacking ecosystem, bad tooling and so on. You must be able to survive that and still shill the language.
It's reality. Everyone will tell you I don't care about your language when I can use my favourite language. People have invested more money than one can imagine into fixing php, js etc.
You can't easily get someone to switch from their single threaded language when they can scale it through AWS lambdas or other layers of abstractions.
This is why you don't see wide use of ML. All those communities are passive. They write their tutorials and papers in pure html on a weird forgettable domain name. They don't tell people to use the language because they are conscious of the lacking ecosystem but how would you get a good ecosystem without someone adopting it? OSS doesn't pay enough. Tooling require money. They don't focus on marketing or sponsorship.
Same applies for dlang.
I think it's good for thought leaders to rally people around new ecosystems: excitement breeds innovation. I don't think programming languages need to move to the scientific method and double-blind testing.
That said, you never outright said that it's bad. I'm inferring that from your choice of words.
This is dismissing the fact that Go is the way it is because of Pike, Griesemer and Thompson and their common design process. You have to go out of your way to not appreciate the inherent simplicity and readability of the language and its minimalist, orthogonal features.
But I agree with you on the general sentiment, that a new language needs a lot of convincing. Rightfully so.
Sure, there are people who rave about how great awk is. I've read them here on HN. When you've got the right kind of problem, it's a great tool. But there are very few people for whom it is their main everyday language.
My point: Author/designer and organization can only take a language so far. At some point, the actual usefulness of the language determines how much it is actually used.
I deny you the right to put words in my mouth. That is not remotely what I am saying.
> C ate the world. awk... um... ... got used for some things.
> the actual usefulness of the language determines how much it is actually used.
you didn't mean something like
> Awk isn't "actually useful" which is why it's hardly used
then what did you mean? What are you saying? Because it really seems to me like that's the impression you meant to convey.
It sounds like you are genuinely trying to understand, so my response may have been inappropriate. I apologize.
To me, it seems that awk is less used than C. As I said, "C ate the world" - it became an incredibly dominant language. If you believe the TIOBE index, C is currently (June 2020) the most popular language in the world. By comparison, awk is somewhere in the 51-100 range. So, yes, by comparison to C, awk is not used nearly as much.
My larger point was this: C and awk both came from Bell Labs, both had famous people from that group involved in their creation, and both got distributed with Unix. And yet C saw (and sees) much wider use. This disproves the thesis that a language's popularity is a function only of famous people and organizational support. If those were the only factors, awk should be used as much as C, but it isn't.
Why isn't awk used as much as C? Because C is useful for a wider range of things. You don't write embedded systems or operating systems in awk. awk is still quite useful. What it does, it does well. But it's less useful than C (when you consider the entire universe of programming tasks, it's useful for fewer of them), and therefore it is used less.
My overall point: Fitness to the task matters for programming language use. Programmers are not just lemmings, led around by the nose to pick languages based on the fame of the author and the organization supporting the language. They actually pay some attention to whether the language is good for writing the kind of program they're trying to write. Languages that are good for writing a wider range of programs get used more than languages that are good for writing a narrower range of programs. That doesn't make the narrower languages bad or useless. It just means they will mostly be used on a smaller range of tasks.
D as of now is a worthy competitor to Rust, it wasn't always the case, it was more like Go, with the GC. I hit some snags and moved on and didn't go back. I am sticking with Rust.
I think a question with closer alignment is, "Why use Go when D is available" ? D feels like a 5x better Go, not a Rust competitor.
Selling a Turbo Pascal/Modula-2 like compilation speed from MS-DOS days as novelty?
Or was using IDE code refactoring tools as UNIX CLI?
* We don't have templates. Hm. Let's bad mouth them. Let's say templates are too difficult. Agreed.
* We don't have exceptions. Hm. Let's bad mouth them as well. Agreed. That one is easy.
* We don't have much abstractions. Hm. Let's convince new college graduates that they can't handle abstractions anyway. Mwahaha. But waait! New college graduates are actually smarter than us. I know... But we will convince them that they are not. Mwahaha.
There is more but I think I've just earned enough down votes with that much already. :)
But there is one sales sentence I will never forget. Go people said "No major systems language has emerged in over a decade"[1] As a person who was very much into D at that time (and I still am), and as a person who knows how "major" D is, that sentence from the Go people make me see them as either ignorant of the programming language scene or deceitful. Cheap sales tactic at best...
Disclaimer: I used Go professionally for 1 year for a product in the microservices space in 2017-2018. The only thing Go had going for it was the libraries that were already written at least for that space. Whatever we needed was already written for us; we had to wait at most 2 weeks for something that we needed to pop up. There was nothing else in the language that made me want to write in Go.
[1] https://web.archive.org/web/20091114043443/http://golang.org...
I've been following D since early 2000s. 2 decades. It took it a long time to get good: make it open source, make it community driven instead of one-man show, add some really important features and focus on important things (ownership, memory-safety), get the tools to be good.
It just missed the boat, and never really had a right niche for itself. It was kind Java/C++ mix, and it wasn't all that better to dethrone anyone in that space.
Rust swooped in and executed everything perfectly in a really short time. It's a C++-killer: same strengths, none of the weaknesses. Normal people don't want to touch C++ anymore. Only people that think that CVEs are "just fault of bad developers" (LOL) can still be considering C++ a good language to start new projects in. Industry really, really needed C-like language that was memory safe, and all-round good: both low and high level. And Rust quickly delivered that, borrowing all the great aspects of other languages and addressing a lot of problems.
D is great, and I like it far more than e.g. Go, but it was an ambitious project by one individual for a long time, while Go had a whole Google behind it. There's no shame that it didn't "took over the world". Rust would possibly not do so well if it wasn't for Mozilla support. The marketing, credibility and traction a big backing company like this gives a new language is probably the single bigger reason for different outcomes.
Rust, culturally, comes from the web. That's why it has the most traction in the web server/WASM space for now. It's starting to poke its head into Systems use-cases because of the sheer weight of its memory safety benefits there. Maybe in a few years it'll get some real use in the games industry (real industry; not just enthusiasts), though Unreal remains a bastion of C++ that isn't going anywhere anytime soon. But then there are some dark corners of C/C++'s territory that move even more slowly, and where the cultural shift will take a long time. I think to a great extent, embedded falls into that category.
WASM as a target is actually a great indication that it's a system language -- performance is a primary consideration.
Which is very different than "web people", which in my mind implies webdev -- html/css/js + API server/db/caching backend.
Which also further explains why WASM is so far along (sandbox, security), much better than any association with webdev itself; but not kernel-level system development. (But if the web browser is an userspace OS... then it's probably not that far from it)
https://www.redox-os.org/
Building ecosystem just takes time.
The community lives in a bubble and is out of touch with mainstream software development.
I consider Rust more pragmatic at this point. Perhaps it's because I code in C++ as my dayjob and have to deal with the consequences.
In theory, C++ is perfect given perfect developers. In practice, it's more sensible and realistic to write tricky, like multithreaded, code in Rust.
One rarely mentioned important factor: fear. It's much less scary to modify something written in Rust than in C++. Doubly so for less experienced developers.
The industry has needed good alternatives for a long time. Finally, they're coming, and not nearly soon enough to suit me! :-)
Firstly, because 75% of all that knowledge is easily transferrable.
Secondly, because you want to take 50% of your bug count.
It doesn’t work well for embedded programming.
It very much does not fix all bugs, especially given lack of static type checking.
lmao
I actually worked in Automotive, and the software higher level up the stack there is usually god damn awful piece of s*, often done by people who have almost no clue what they are doing, with plenty of misconceptions about how C/C++ even really works (using `volatile` for concurrency/atomicity and stuff like that). They are just beating their spaghetti code from segfault to segfault for decades.
This and slow delivery process easily explains why entertainment, navigation and other software-driven part of mainstream cars are so buggy, slow and generally terrible, and why Tesla could have so easily deliver way better experience.
So it doesn't matter that some people can't "get into Rust". The business that hire them will be replaced if they can't up their game, that's all.
Few "want" C++, but for robotics a non garbage-collected language is necessary so latency is predictable. There are few mature languages besides C/C++ in that category.
Rust is an improvement, but I'm hopeful something like Julia (Julia Robotics, https://juliarobotics.org/) or Scala Native (https://scala-native.readthedocs.io/en/v0.3.9-docs/) becomes mainstream, the productivity gains would be substantial.
It is a great choice to prototype the ideas
But perceived "comfort" isn't entirely reality. (The comfort of smart GC languages is immense in a different way.)
For 99% of realtime work, the Rust or Scala Native approach is just fine. No GC required. Julia users can just use the pre-allocation approach.
The important thing is avoiding language patterns that encourage needless allocation.
GC languages still support stack allocation, you don't have to pre-allocate anything you can stack allocate. (That's where .NET Core has been especially burning rubber in recent releases. Span<T> is a stack allocated, GC-safe "pointer", for instance, that is doing all sorts of heavy lifting in .NET Core performance-critical work these days. It's still early too, as not everything has moved to Span<T> that can move to Span<T> and family.)
But also, not everything needs to be pre-allocated for the "best approach". There's some work to get used to the feel of any specific GC, but most modern "VM" GCs (.NET and today's Java, not yesterday's) are multi-generational and there's a lot you can do in strategies such as "focus on the nursery and the LOH" (using only [potentially many] small short-lived objects and a few, mostly stable "very large" objects, avoiding the intermediate generations).
> why carry the overhead of the GC at all?
Safety. (Why wear seatbelts?) Rust's borrow checker is great but it still requires a lot of manual adjustment and it's still possible to miss something (it's not easy, certainly, but it is possible); a GC gives you safety by default, with no manual intervention required to guarantee safety, and requires manual effort to write unsafe code.
> The important thing is avoiding language patterns that encourage needless allocation.
That's where we agree and why I'm very adamant that though some of the tools ("knobs") look scarily different in performance optimization for GC versus non-GC languages, the vast majority of the tools are the same: know the O(memory) of your algorithms, and make smart trade-offs regarding that O(memory), avoid allocating what you don't need, know your trade-offs between pre-allocation and allocation only when necessary, etc.
Could you elaborate?
Previously, the code base was primarily Python with some C++. Now there is a significant chunk of code, particularly related to safety, written in Rust.
C++11 is a really good language. Also there are tons of libraries and things people have already built in it that you can leverage to reduce development time.
Deliberately inflammatory, and also false.
1. Rust has limited abstraction features to make it more approachable and implementable, but make it unable to express libraries that are easy in C++. This will not change soon, although Rust will accrete features at a steady rate. But the gap in feature sets will widen, not narrow with time.
2. The total number of people using Rust in production is easily less than the number who pick up C++ in any given week. It will be ten years before Rust is a mature industrial language, if it gets there. (It has made a good start in that direction, which is better than can be said for any other newish language.)
3. C++ and Rust will coexist for decades. The most ambitious work will continue to be done in C++, while Rust will be more than adequate for what might otherwise have been done in (the much less capable) C, Go, or Java.
4. D fizzled because it is too similar to C++, and therefore unnecessary. Rust found a ready audience in people intimidated by C++, frustrated with the limitations of C, Java, and Go, and ready to try something wholly new. Its designers have threaded the gap deftly, uniquely adopting C++'s greatest strength, the destructor (which it calls the "Drop trait"), and avoided weighing it down with garbage-collection. It has a bright future if it can multiply its adoption rate by two orders of magnitude.
As Stroustrup said, there are only two kinds of language: the ones people complain about, and the ones nobody uses.
With enough luck, by the time Rust is mature, it will have gained plenty to complain about. Rust will have got somewhere when you read more complaints about it than brags about having made it do something already done in a mature language.
2. True, but growth curves are rarely linear. Here’s a rough proxy on users - the number of subscribers to /r/rust - https://subredditstats.com/r/Rust. Look at the growth between 2014-18 and 2018-2020. You’re extrapolating on current growth rate, but that may increase in future.
3. “Ambitious”. Nothing I’ve seen precludes using Rust for ambitious projects. In fact, seeing the experience of Dropbox, Mozilla, Facebook and others, there are some ambitious projects that could only have been done in Rust. I’m gonna say [citation needed].
I agree with Stroustrup and look forward to the day people complain about Rust :)
I'm guessing, but I think that something like Armadillo[1] would not be possible on stable Rust. Something like Catch[2] might also difficult to make ergonomic.
I don't program in C++ anymore and I would personally live with the lack of expression/abstraction for a safer language though.
[1] http://arma.sourceforge.net/speed.html [2] https://github.com/catchorg/Catch2/blob/master/docs/tutorial...
Type-aware macros might not be the best way to implement the features needed to match C++.
Also, how is it ergonomic? I'd agree if you say that it's (one of?) the best for C++, and it's also my go-to option, but ergonomic?
Nah, I mean maybe in the way that Fortran coexist with C/C++ for decades, but it's not equal coexistence.
I would rather say that new languages arise, replaces old ones for most scenarios and in the cases where they can't, due to various reasons, they push the old language into zombie state like cobol.
It's the same BS like NoSql will kill all R-D's.
You just don't invest millions just to rewrite programs that work's perfectly (and that's often the case with old battle-hardened software)
OP is right, unfortunately. C++ is a dying language. Mozilla, Microsoft and Google are all looking at Rust. Why? Because it's probably makes more sense to rewrite a buggy C++ component in Rust instead of updating it to use modern C++ (where admittedly, you have to go out of your way to get things wrong). The damage has been done.
I'm also concerned about our ability to hire in the future. C++ devs will either be too expensive, or just not there since it's not an attractive language any more.
I'm not a Rustafarian either, I've actually never used it but it would be negligent of me to not look at it. One concern I have with it is that the eco-system may be full of poor-quality ports of C/C++ libs, because that's how people work when they learn a new language.
It's far too premature to declare its death. The pace of development of C++ is decently fast and there's many stakeholders with millions of lines of C++ who are interested in C++ not dying. C++ is taught in universities around the world so the chance of C++ developers becoming expensive is low.
To suggest C++ is a dying, slowing, or stagnant language is objectively delusional. The language is healthier than ever, and going gangbusters.
P.S. I'm not a COBOL programmer nor have I ever been a COBOL programmer.
Other than that it's nonsense to say that X is dying.
Sure, it'll stick around for some years yet but all those jobs will become maintenance jobs. Very little greenfield projects will elect to use it outside of niche areas (games and maybe embedded - UK salaries for embedded dev are terrible). Both C++ and Rust can use LLVM, so the generated code is likely to be the same.
If you were starting a greenfield project today why would you choose to do it in C++?
I forgot to mention Go too.
To suggest C++ usage is in decline is, objectively, nothing short of delusional. For Rust, C++ will the one to beat in ten and twenty years, provided not too many have already skipped onto some new hotness.
Rust is an objectively better design than anything else that has arisen in 30+ years. That doesn't guarantee success.
I used to hope a better language would displace C++, and for a time thought Rust might be it, but that better language turned out to be C++ itself. Nothing else is even on the horizon.
Oh and by the way, LLVM is 100% c++.
Saying it is too dangerous and complicated is absurd. It is easy to write safe code in C++, having been doing it for almost 30 years.
You are throwing around lots of assertions - challenge you to back them up with real data.
React Native, the new Games SDK for Android, WinUI 3.0 release, lifetime analysis support for Visual C++ and clang and lets not forget they are two major contributors to ISO C++.
While the Rust/WinRT efforts from Kenny Kerr are welcomed, that it is just yet another option alongside C#/WinRT, C++/WinRT, Python/WinRT and JavaScript/WinRT.
What about people not intimidated by C++ and want to switch to Rust anyway? Why have you discounted them? Do such people exist in your world view? Do you think there might be a good reason for those people to choose Rust?
There are kludgy workarounds for everything, more or less, but why switch to a limited language with immature tooling and practically nonexistent immediate prospects, when C++ demand is going up, up, and up?
Memory safety is just not an issue at the level where coders of modern C++ work. I have had exactly one lifetime error in five years, caught in initial testing. My bugs are overwhelmingly specification omissions and logic mistakes that Rust suffers from exactly as much.
My day-to-day experience is to write 2000 lines and, when it compiles, it works correctly, modulo a "!" short or extra. Then, I spend a few days refining the design, which often means deleting code. Things Rust promises to help with consume only trivial attention. Library features not expressible in Rust prevent many more and bigger problems.
Rust has some nice qualities I would rather C++ had--pattern match support, simple iterators, default const and default pass-by-move, sane conversions, sane initialization--but they are all low-level conveniences, not anything I am willing to trade away architectura-level capabilities for.
Rust is going interesting places, is taking full advantage of starting from scratch, and is miles ahead of C, Java, and Go on every axis. But if Rust could get to where C++ was in 2011 by 2025, that would be amazing. Meanwhile, C++ has already shipped C++14, C++17, and C++20, will have done C++23, and will be firming up C++26.
Assume Rust could match C++20, just five years later, in 2030, which would be more amazing. C++29 will be out.
Unfortunately for many people technology is still an emotional rather than a professional topic.
The language is messy and filled with undefined behaviors and unsafe methods by default. Where there are rules you can mostly ignore them whenever you want. People complain about JavaScript being messy but C++ is way worse.
Though the language itself isn't all that bad, I don't understand why there so many build systems? And the top build system CMake isn't so much a build system as it is a build system for build systems that exists because no one can seem to agree on one.
Many of these systems seem bloated and over designed by comparison when I can install libraries or cross compile in one line in go. I couldn't help but think there had to be a better way and it seems like rust is that way. I expect C++ will eventually go the way of Cobol and eventually be used to maintain legacy systems.
p.s. thank God for vcpkg because I had nearly thrown in the towel while trying to integrate simple libraries until I discovered it.
I guess what I meant is "vast-majority of devs out there".
I did ~10 years of kernel/embedded myself. Generally people use C++ only when they really have to (like: they work in one of this niches, or want to get a job there). I've experienced myself many times when people would go with anything but C++ because of all it's faults, weaknesses and general infamy. And I also have seen some people that gave Rust a try and it went smoothly. They deliver a proper C++-level performance and resource control, without any of the problems and were happy about the experience.
AAA-game/kernel/embedded are all lucrative (except games, lol), important and not tiny but they are still niche.
Not used Rust yet, used a lot of C++; isn't a weakness that it also is extremely slow in compiling? Not sure about others but to me that's a big weakness (if it still applies, but as far as I can find on Google it does).
Might be better than whatever C++ does though.
Then most organizations have staging areas where you can share binaries across the company.
And the two package managers that have been growing community support, conan and vcpkg, support caching and distribution of binary dependencies.
No doubt cargo will eventually get something similar, it just isn't there today.
If I was to nuke my target directory _(the compile cache)_, it would take minutes. Not sure how many honestly, because when I do it, I rarely wait for it.
So the compiles are definitely slow, but for me it's only bad when dependencies are needing to be compiled. Which is rare.
If you don't cache your dependencies well, like in a poorly written CI pipeline, things will suck though. 20 minute builds at work (slow build machines) are common for us due to some poorly done caching.
But just like anything else given enough time, money and harddisk space anything is possible :)
I feel that people can learn rust faster if they know c++ beforehand.
c++'s syntax is scary too. But there are different levels of c++. You don't need to use the scary part to make things work.
Ding ding ding! However I do think that the combination of syntax with the brand new concepts just adds that extra layer of complexity. A similar thing is Optionals in Swift -- the syntax is so baked into the language that even if you really understand how optionals work, the syntactic sugar keeps piling up in different situations. (i.e., first the ? operator, then implicitly unwrapped optionals, then if lets, guards, guard lets...)
I’m curious about what you find scary about Rust’s syntax. I always found it to be a fairly natural extension of the syntax from C and other ALGOL-derived languages.
Its semantics, on the other hand, took quite a while to wrap my head around. I am reasonably productive in Rust these days, and I still sometimes can’t predict whether or not the compiler will allow something.
The borrowing model was actually my favorite part because it not only was interesting, but made sense! And the syntax was relatively clean :)
For example, is there a way in rust to get a runtime error when there's an int overflow?
Or better yet, the Rust standard library exposes all the relevant LLVM intrinsics for the primitives, so you have the {Integer}::checked_, {Integer}::saturating_, {Integer}::wrapping_, {Integer}::overflowing_ (inlined) functions to do all your integer math in an error-free fashion.
Well, almost. I'm not sure I like unsafe FFI and other bits.
> Personally, at some point Rust was just clearly better and after a while - I lost interest in D. I don't have time to keep track of D catching up
Yup. Better to use Rust if it's the one introducing the features.
And especially Mozilla's intense passion for open-sourcing everything. I think it was a good catalyst to get it into the hands of as many people as possible.
Industry has had Ada since 1983, Modula-2 since 1980, Object Pascal since 1990, and a couple of other ones, not counting all those Algol and PL/I variants that precede C for about 10 years.
Unfortunely the industry will only take security seriouly when security exploits are severly punishable by law.
And Rust's borrow checker can give very strong guarantees that aren't present in any other mainstream language that I'm aware of. In Rust, you can pass mutable references to large data structures between threads, without copying or GC or any type of runtime checking (e.g. Mutexes), and the borrow checker will guarantee that you can't have a data race (data race = concurrent read & write). In comparison, I believe that in Haskell you'd do this with GC, in Java you'd do it with GC and a mutex, and in C you'd do it very carefully.
As another example, in Java if you modify an ArrayList while iterating over it, you'll get a ConcurrentModificationException. In Rust, you can't. The borrow checker won't let your program compile.
The cost of this borrow checker is huge: every reference in every program needs to be annotation with whether it's shared or mutable, and you often need to splatter confusing lifetime annotations all over the place. It adds a big learning curve to the language.
I don't know the details of D's ownership system, but it's not like Rust's borrow checker. Does someone who does know more want to describe it? I've just seen the language reference page here, that describes "scope" and "returns". https://dlang.org/spec/memory-safe-d.html
https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in...
Basically D just needs that big break to actually get things done. There are some absolutely brilliant people working on D but there's only so much sweat people will donate (some people are paid but I imagine rust probably has upwards of a hundred full time staff given that Mozilla and Microsoft use it in an official capacity)
Which is nice but it's still missing some of Rust's features.
No. You need to "annotate" a mutable binding since bindings are immutable by default. But that also means that immutable bindings (ie the vast majority) does not to be "annotated". And even when you do need to, you literally just add the keyword `mut` as in `let mut foo = 42;`.
> and you often need to splatter confusing lifetime annotations all over the place. It adds a big learning curve to the language.
Again an extreme exaggeration. There are a few cases here and there where you need lifetime annotations, but most often the compiler simply infers them for you, allowing you to elide them completely. Specifically, you only need to do it yourself when it's ambiguous from which input(s) the output is derived.
EDIT: What's really relevant is that you can look at a Rust type, and tell whether it's shared, mutable, or owned; this is what Rust's borrow checker derives its power from. Likewise, Haskell's type system derives its (equally amazing) powers from the fact that you can look at a Haskell function's type signature, and tell what kinds of side effects it has. (Sometimes people think that Haskell functions don't have side effects in the sense that they never mutate anything. This is wrong; Haskell has mutable arrays in its standard library. Rather, it's that all side effects are reflected in a function's type signature.) https://hackage.haskell.org/package/array-0.5.4.0/docs/Data-...
I write Rust code for work, and we have a large codebase. We manage it pretty well, but there are definitely still innocuous looking changes that require adding lifetime annotations all over the place to avoid confusing error messages.
Rust is my favorite language by far (I get the impression you like it too and are defending it). I think the costs of its borrow checker are worth it, but they are significant costs.
I have not utilized tagged unions outside this type so I'm not one to comment on any deficiency.
* Releasing D under a closed source license was a non-starter. This has killed every language that has tried in the past 30 years.
* Garbage collection was really the only memory management until recently. Manual memory management has always felt clunky and tacked on. Ownership and borrowing came really late to the game in comparison with rust.
* Rust embraced all of the best parts of ML, like algebraic data types and pattern matching and strong static typing, but combined them in a package that made for extremely fast software with low resource utilization and static memory management. They combined it with hygienic fully typed macros. They added type classes, securing the majority of the benefits of OOP while still maintaining a functional style.
Whereas Rust has taken influence from a broad range of PL research, functional programming concepts, high assurance concepts, etc., and applied them to system programming, D has always just felt like C++ with garbage collection.
The one area where I think D still has an advantage over rust is GUI development. Functional programming advocates make lots of platitudes of functional reactive programming, and there are no shortage of toy examples for it, but when it comes down to industrial use, OOP still rules the roost. And while Rust gets most of the benefits of OOP, they still don't have anything approximating inheritance, which just works too well for GUI development to give up on. Maybe Rust will address that in the future, but it's not there at the moment.
Rust won on paper based on C-like performance without GC and being not OOP-oriented in a Java way (I tried Java earlier and wondered who in his right mind would want to write that). But what convinced me was excellent basic documentation (the Book), concise and well documented standard library and nice FP-inspired idioms which I had no previous experience with.
I passed on Go due to GC and the fact that while I could probably learn the ropes quickly, there was not much I saw the language could teach me (I may be wrong here but such was an impression). Main accent was on speedy development in teams and it was orthogonal to my needs.
Nim (still Nimrod at the time) was intriguing but too fresh and lacking on documentation. It's much more intriguing now with gc:arc, move semantics and overall general momentum. I keep my eye on it.
D was the one I couldn't really find a place for. It was promising less, there was no killer feature that set it apart. To me it looked like more friendly C++ but with GC. I saw no real advantages.
I tend to think time proved my analysis to be mostly on point. At the time tooling and library ecosystem was rather poor for all four. Today even if featurewise D looks much more interesting, it needs to deliver on well-libraries to be competitive (I have no idea on its current situation on that front).
Sorry for such a long personal anecdote.
Interesting that you mention this; one of the reasons I really enjoy Rust is because of how it forces me to think through things more clearly, and how a number of the higher-quality crates teach more advanced approaches in a straightforward way.
I wasn't early to Rust and I won't be early to any other language. For PLs I'm solidly on the far end of the chasm.
If history telling us something, python only take off after 20 years and now D language is around the 20 years mark. But fortunately D has passed the growing pain similar to python 2 to 3 when it transitioned to D2.
Personally I think D just need a big breakthrough in a form of a killer application like Ruby with RoR, and Go with Kubernetes to make it more popular and gets the snow ball rolling. The killer application probably involve some kind of data science or data analytics that is currently more popular now with python. But python seems starting to reach its limits and it will be good if D can take over.
For rust since it came from Mozilla team I'd expect by now Firefox is already re-written in rust by now but it seems yet to happen, and this article probably tell us why [2]. It will be wonderful to have Firefox-rust (if it ever happened) to replace Chrome that keeps eating away my quad core CPU and 16 GB ram laptop memory once opening more than 20 tabs.
[1]http://erdani.com/hopl2020-draft.pdf
[2]https://hacks.mozilla.org/2019/02/rewriting-a-browser-compon...
If anything, Chrome can just offload the contents of the unused tabs to the hard drive, and reload it when it becomes active again. But this will require a massive architectural change to the core program itself.
Side note, but at least on linux, with both Chromium and Firefox, you can observe exactly this behavior- tab-based segregated memory management. The work was done on both engines over the past several years, works beautifully now.
The content of each tab lives in a separate process. Kill the process, see the tab marked failed in the UI. Reload the tab, see a corresponding process spin back up.
I keep dozens of tabs open and periodically kill the ones that creep to the top of ram use, both wired ram and virtual. Keeps me from going into swap.
Nope. In fact that article says:
> By 2017, Mozilla had made two previous attempts to parallelize the style system using C++. Both had failed.
And goes on to say how they were successfully able to re-write it in Rust, and then talks about the kind of security problems Rust solves and the ones beyond language scope (correctness).
But I don't think we really needed an article to tell us why a 20+ year old browser that has a billion man-hours of development hasn't been re-written in a language that has only been stable for five years, and has a relatively small team working on it.
However, where it's the bigger and unique thing that D haves. Fast and very powerful metaprogramming. Can do things like parsing a XML or JSON at COMPILE TIME and generate code. No body catches how powerful is this ? For example, imagine parsing a gtk-build /glade XML and generating the GUI code at compile time, instead parsing it at runtime.
I was writing a library and a contributor popped out of nowhere. He didn't knew D. The first patch it suggested was about parsing some JSON at compile-time.
It turned out std.json the stdlib parser was able to parse at compile-time in CTFE context. So, the contributor parsed JSON at compile-time without his knowledge, without really knowing D, and the fact it worked was accidental (since the parser was n't specially designed to do that, but could).