I don't understand how Rust is being weighed. It's a systems programming language seemingly intended for critical code with baked in security and "programmer mitigation".
I've heard and watched some pretty wild claims about it being the new Uber language. If it targets c, Cpp, then it might end up just out of sight for most programmers.
If it reaches lots of Linux and Windows integration, then it'll become the new "foundational" language, but even that doesn't mean widespread adoption.
Well, I guess the response to Rust just means people are still waiting for a language that:
- has a very expressive and sound type system
- provides a good mix of paradigms (functional, imperative, object oriented, etc.)
- uses modern techniques to address the warts of many existing languages (nulls, exceptions, optionality, unsafe memory access, async, etc.)
- is (reasonably) fast
- comes with great tooling and docs
- is mainstream, general, open, and not tied to any particular vendor
Whether they are right to pin these hopes on Rust is one thing, but there's no denying there is still an un-addressed hunger for a next-gen open language that generally addresses many pain points with modern software development.
I think Zig is a step in the right direction. The simple syntax feels as pleasant as Go and the manual management allows for very performant software. It makes it easier to write safe programs but definitely isn’t as memory safe as Rust. The day we have a language as simple as Go/Zig and as safe as Rust will be the day we have a perfect language.
IMHO, if you stick to just unsafe rust, it’s got similar ergonomics to Zig. And the lack of safety in Zig to me is a move in the wrong direction for a language created so recently.
The safety is the added complexity because so much of what we regularly do can fail in ways we don’t think about.
The alternative so far has been to introduce some kind of automated memory management like reference counting or a GC.
Rust in fact gets much simpler (but slightly verbose) if you wrap everything in an Arc.
That’s why I say in another comment that Swift is the closest to a more accessible Rust. Granted, until Swift 6, it won’t go as far as Rust for thread safety. But for everything else, it is Rust without having to think about as much while writing.
I really, really hope that the energy cross platform Swift has been seeing lately continues and accelerates. It’s not perfect, but I find it productive and enjoyable to write. It strikes a nice balance between being strict and getting out of your way and doesn’t come off as pedantic as some languages with similar syntax.
Tooling is also a factor I think. Last time I was playing with writing Swift on Linux, the official LSP with VS Code was alright (surprisingly even supporting debugging) but I found myself wanting a proper IDE.
Swift on its own is already much more usable than Obj-C is and will only become moreso with the Foundation rewrite. It has a way to go but it’s possible to write useful software with it without Cocoa/GNUStep (especially if one is willing to lean on C or C++ libraries via interop), which was never true of Obj-C.
It was definitely true for Objective-C with GNUStep, or during the time Microsoft had their porting framework into Windows Store (Windows Bridge for iOS).
That extreme dependency on a supporting framework (Obj-C doesn’t even have its own allocator) was a massive weakness though, as has been proven by GNUStep’s stagnation and MS’ abandonment of WinObjC.
Swift has no such issues. It’s weaker without AppKit/UIKit yes, but at least has most of the basics covered. The only real threat is Apple deciding they don’t want cross platform compatibility any more in which case Swift can simply be forked.
Not even Apple is fully supportive of it outside their ecosystem, besides CLI tools and Linux based servers, as stated on Swift's open source website.
Seeing how much engagement Microsoft is having with .NET outside Windows and still failing in many fronts in regards to adoption by non-Microsoft shops, versus the little Apple has invested, I doubt it will really be any different than Objective-C.
But the framework dependency is exactly why I mention the C++ interop and Foundation rewrites.
Swift prior to the interop didn’t interest me as much for cross platform use, primarily due to ecosystem .
That has changed significantly because the ecosystem just magically expanded. I can use most C++ libraries I throw at it. Foundations rewrite means I can use a more comprehensive stdlib everywhere.
IDE tooling is definitely a weak point but I think that’s easier to rectify than ecosystem. The biggest loss has really been the Swift plugin for CLion and the entirety of AppCode for me. But when they were around, they worked very well and so the foundation for it is already there along with the Swift LSP to improve on.
From my experience dual language approach always adds some atriction across the board, in tooling, building infrastructure and debugging layers.
Hence why while I could use C++/CLI on my hobby coding to stay on the confort of .NET, with a couple of bindings being used from C#/F#, I end up using straight C++ instead.
In my experience, it’s the opposite. Most people tend towards the easier language unless they need to be maintaining the bindings or something on the other end.
Perhaps you’re considering mixed language projects. I’m talking about primarily Swift where I can just import C++ libs over. The fact that it’s C++ is easily hidden, especially with the use of SPM.
I think Python is a big example. So many people stay on the Python side for things like Qt.
Historically, there were performance complaints, but a lot of these were mitigated (AOT, heavily improved GC..., faster hardware). They are fast enough for a large majority of apps.
There are many people, like me, who dislike anything Java: the language, the runtime/SDK, and anything built on top of these. I even refuse to install anything that requires the JRE. Might be an irrational stance, but my early experience of JRE hogging my machine turned off it forever.
The CLR is supposed to be open now, but in practice, the ecosystem around it is still basically Microsoft.
There is space in the world for a difficult complex language that produces low level operating system and library code, we just don't need to be writing every application using it, since ordinary people should also be able to program computers.
Rust is renowned for imposing a high cognitive load on all but the most trivial tasks. This is perhaps the worst traits a programming language can have.
> This is a thing people experience at the beginning (...)
This is not an onboarding problem. This is a trait of the programming language, which only gets worse as a project grows.
It's high time for the Rust community to start to get honest with themselves and stop pretending problems don't exist. It's already bad enough with the clusterfuck which is async Rust, and you're doing no one any favor to pretend that the borrow checker doesn't add a heavy cognitive load.
I can't speak for others, but it absolutely has made life easier, on both small and large scales.
Actually being forced to think about how long allocations and resources need to live turned random "takes days to figure out" bugs into an instant response of "oh, that was stupid of me to try doing that huh? Guess I'll try something else"
> pretend that the borrow checker doesn't add a heavy cognitive load
The borrow checker actively reduces cognitive load once you learn to adopt program designs that mesh well with its requirements. And those happen to be really good program designs across a wide range of axes.
I am sorry that you seem to think you know how I feel better than I do?
The borrow checker means I have to pay less attention to memory management, not more. That’s why it exists. So I don’t have to worry about it. It catches my mistakes, I fix the code, I move on.
It’s quite the opposite. It may not be worth learning Rust for small simple programs, but it has an entire toolbox of features for dealing with complex problems and large programs.
For example, dealing with multi-threading and low-level memory management without the assistance of thread-safe types and borrow checker adds mental overhead of verifying and upholding all the requirements manually.
You can do that via much simpler message passing instead. No "thread-safe types", no "borrow checkers", no "verifying and upholding all the requirements manually". The downside is you are sacrificing performance.
Rust is for high performance, high concurrency applications where the developer can spend all day building them.
Did you? It doesn't say anything about the respondents. "respondents that self-identify as a Rust user" is completely useless. Are they professional programmers? Are they just beginners playing with it? Do they know the language well enough to make an assessment?
Rust is memed for that by people who don’t actually program Rust.
In practice it is absolutely the opposite. Rust makes really challenging problems extremely tractable, and takes an enormous amount of mental overhead off the table.
I don't think GP meant that as "of extraordinary ability" just "tackling the common problems people write code for". Ordinary problems vs ordinary people.
I tend to agree. That is currently the systems world. C lives here by convention. Those people who intend to make systems and tools for systems that are semi-tightly integrated with those systems.
I've worked with debian maintainers and they are some of the best C programmers around, and even they would use Python as much as possible, using C for the lower level stuff.
I really believe this is where Rust will - and maybe even should - live. I do not believe it will replace C and Python in this example, but definitely C for those wishing to have another tool to use, and Python for some as well.
I'm an old programmer. I started with Java, learned Ada because I thought it'd be the next best thing. Then learned Cpp for windows programming, then php. Then a job with Java, then embedded work with C. And coursework in C. My thesis was a data structure implemented in C and Java. Then a decade and a half of Cpp because robotics and ROS dominates that area. Distrbuted robotics in Cpp. Along the way Python took off, I've used R and Matlab for research for years at a time. Now Rust is here.
I have never stopped "thinking in C" from my few years of embedded work near the operating system or on bare metal. It's the language that makes the most sense when you study CPUs. The concepts match OS apis. It is simple to write C glue for any of the above languages. C libraries are not mangled. Etc etc. C feels like the language that computers and software are made with, and all other languages just try to hide that by building someone on top of it. I say that as a feeling but it might just be true.
Now Rust is here and I love it when it tries to be like C. It's clean, pure, I believe the compiler when it says something (not like Cpp), and the mental leap to the borrow checked matches ownership dynamics from C pretty well.
I hate it when it tries to be like Python or JavaScript, pulling 1000 libraries for something flashy and simple. But that's us, the programmers. The language is strict because it's the core of C without the generality. If C is the wilderness, Rust is the national park. It's beautiful, sparse, you can get lost for days, but it's safer.
> I think it's interesting that C still exists despite great efforts to kill it.
You won't get rid of C until UNIX/POSIX goes away, that is why C is still around mostly.
Now i fully agree with WG14's incompetence, it is impossible to understand that in 40 years, it was so hard to add proper string and array types to the language, between new native types, additional struct based standard library functions, or fat pointers, one approach would definitly have worked out, if they bothered.
> These guys haven't been able to come up with a non broken version of strcpy with 40 years of trying.
strcpy() is there for historic reasons, and is staying for compatibility. Functions like strtok() and in fact most functions in <string.h> are awful -- don't use them for new code.
In the same way, zero-terminated strings are there for historic reasons. They weren't a C invention. And they are staying for compatibility. There's no practical way to get rid of them.
I don't think that it would be useful to add another string type to the C library. The types of programming where C is useful today, you need memcpy and snprintf, that's about it. To add another standardized string type would only lead to a situation where we now have 15 incompatible solutions, and none of them are good for everyone.
Built in string types are more useful for languages with some form of automated resource management where one is used to mindlessly concatenating and splitting strings. The types of programming where that's a valid approach, don't use C in the first place. It's a bad fit.
Btw. zero-terminators are not entirely bad. They are an in-band signal (and can be easily completed using an additional out-of-band signal). And that can be quite useful, for example when looking at a plain binary. The space saving part that comes with zero terminators for small text strings is another thing, but admittedly has become irrelevant.
I have a confession to make. I am so bad with dynamic programming languages that I prefer to make scripts in Rust rather than Python. It has all the modern conveniences that I want, it’s impure, I can simplify if I want (maybe allocate more, borrow less), and the compiler helps me out.
I’m using Rust in embedded systems for this reason - sure C is the ‘native’ language, but the engineers before me couldn’t tame the beast and made barely working software. The HAL provided by STMicro is functional but riddled with side-effects and is incompatible with an RTOS.
Inferno and Android are two good examples on how to do it, with a clear separation on the low level stuff, and more developer friendly and safer userspace.
Not the only examples, there are plenty of other systems following similar approaches.
I have done a fair amount of Rust. The complexity is not in the borrow checker or lifetime. It’s in the combination explosion of the of generic, traits, lifetime, and constraints. When a struct takes on these, all functions and impls need to specify them. The amount of brackets becomes very distracting.
It's all relative. I've done my fair share of both C++ and Rust for over a decade and yet I can quite easily read Rust source code for both the Rust standard library and any 3rd party crate. In comparison, reading C++ std headers is complete pain, same as sources of many popular C++ libraries, due to them being overly generic in a C++ way.
For what it's worth, I'm currently learning Rust. My primary motivation is that it offers the opportunity to get a job where I can use functional programming techniques (even if it isn't necessarily a "functional language" in the way something like Haskel is).
53 comments
[ 3.2 ms ] story [ 166 ms ] threadI've heard and watched some pretty wild claims about it being the new Uber language. If it targets c, Cpp, then it might end up just out of sight for most programmers.
If it reaches lots of Linux and Windows integration, then it'll become the new "foundational" language, but even that doesn't mean widespread adoption.
- has a very expressive and sound type system
- provides a good mix of paradigms (functional, imperative, object oriented, etc.)
- uses modern techniques to address the warts of many existing languages (nulls, exceptions, optionality, unsafe memory access, async, etc.)
- is (reasonably) fast
- comes with great tooling and docs
- is mainstream, general, open, and not tied to any particular vendor
Whether they are right to pin these hopes on Rust is one thing, but there's no denying there is still an un-addressed hunger for a next-gen open language that generally addresses many pain points with modern software development.
The safety is the added complexity because so much of what we regularly do can fail in ways we don’t think about.
The alternative so far has been to introduce some kind of automated memory management like reference counting or a GC.
Rust in fact gets much simpler (but slightly verbose) if you wrap everything in an Arc.
That’s why I say in another comment that Swift is the closest to a more accessible Rust. Granted, until Swift 6, it won’t go as far as Rust for thread safety. But for everything else, it is Rust without having to think about as much while writing.
Really good ergonomics, safe by default for many cases and getting more of rusts safety for others.
Easy interop with C/ObjC/C++, which is a big deal for me because it’s what’s caused me to write less Rust/C++/Zig at all lately and focus on Swift.
I really feel like easy interop in languages is the missing key to moving people into more safe languages.
GNUStep went nowhere.
Swift has no such issues. It’s weaker without AppKit/UIKit yes, but at least has most of the basics covered. The only real threat is Apple deciding they don’t want cross platform compatibility any more in which case Swift can simply be forked.
Seeing how much engagement Microsoft is having with .NET outside Windows and still failing in many fronts in regards to adoption by non-Microsoft shops, versus the little Apple has invested, I doubt it will really be any different than Objective-C.
Swift prior to the interop didn’t interest me as much for cross platform use, primarily due to ecosystem .
That has changed significantly because the ecosystem just magically expanded. I can use most C++ libraries I throw at it. Foundations rewrite means I can use a more comprehensive stdlib everywhere.
IDE tooling is definitely a weak point but I think that’s easier to rectify than ecosystem. The biggest loss has really been the Swift plugin for CLion and the entirety of AppCode for me. But when they were around, they worked very well and so the foundation for it is already there along with the Swift LSP to improve on.
Hence why while I could use C++/CLI on my hobby coding to stay on the confort of .NET, with a couple of bindings being used from C#/F#, I end up using straight C++ instead.
Perhaps you’re considering mixed language projects. I’m talking about primarily Swift where I can just import C++ libs over. The fact that it’s C++ is easily hidden, especially with the use of SPM.
I think Python is a big example. So many people stay on the Python side for things like Qt.
Historically, there were performance complaints, but a lot of these were mitigated (AOT, heavily improved GC..., faster hardware). They are fast enough for a large majority of apps.
The CLR is supposed to be open now, but in practice, the ecosystem around it is still basically Microsoft.
This is not an onboarding problem. This is a trait of the programming language, which only gets worse as a project grows.
It's high time for the Rust community to start to get honest with themselves and stop pretending problems don't exist. It's already bad enough with the clusterfuck which is async Rust, and you're doing no one any favor to pretend that the borrow checker doesn't add a heavy cognitive load.
Actually being forced to think about how long allocations and resources need to live turned random "takes days to figure out" bugs into an instant response of "oh, that was stupid of me to try doing that huh? Guess I'll try something else"
The borrow checker actively reduces cognitive load once you learn to adopt program designs that mesh well with its requirements. And those happen to be really good program designs across a wide range of axes.
The borrow checker means I have to pay less attention to memory management, not more. That’s why it exists. So I don’t have to worry about it. It catches my mistakes, I fix the code, I move on.
For example, dealing with multi-threading and low-level memory management without the assistance of thread-safe types and borrow checker adds mental overhead of verifying and upholding all the requirements manually.
Rust is for high performance, high concurrency applications where the developer can spend all day building them.
By whom exactly? I think it's actually the exact opposite. It completely frees you from having to think about entire classes of bugs.
You didn't read the article, didn't you?
In practice it is absolutely the opposite. Rust makes really challenging problems extremely tractable, and takes an enormous amount of mental overhead off the table.
I've worked with debian maintainers and they are some of the best C programmers around, and even they would use Python as much as possible, using C for the lower level stuff.
I really believe this is where Rust will - and maybe even should - live. I do not believe it will replace C and Python in this example, but definitely C for those wishing to have another tool to use, and Python for some as well.
First it was C++, then it was Java, now it's rust.
Perhaps it would be easier to fire WG14 for incompetence[1], add a few things to the language, and update the standard library.
[1] These guys haven't been able to come up with a non broken version of strcpy with 40 years of trying.
I have never stopped "thinking in C" from my few years of embedded work near the operating system or on bare metal. It's the language that makes the most sense when you study CPUs. The concepts match OS apis. It is simple to write C glue for any of the above languages. C libraries are not mangled. Etc etc. C feels like the language that computers and software are made with, and all other languages just try to hide that by building someone on top of it. I say that as a feeling but it might just be true.
Now Rust is here and I love it when it tries to be like C. It's clean, pure, I believe the compiler when it says something (not like Cpp), and the mental leap to the borrow checked matches ownership dynamics from C pretty well.
I hate it when it tries to be like Python or JavaScript, pulling 1000 libraries for something flashy and simple. But that's us, the programmers. The language is strict because it's the core of C without the generality. If C is the wilderness, Rust is the national park. It's beautiful, sparse, you can get lost for days, but it's safer.
You won't get rid of C until UNIX/POSIX goes away, that is why C is still around mostly.
Now i fully agree with WG14's incompetence, it is impossible to understand that in 40 years, it was so hard to add proper string and array types to the language, between new native types, additional struct based standard library functions, or fat pointers, one approach would definitly have worked out, if they bothered.
strcpy() is there for historic reasons, and is staying for compatibility. Functions like strtok() and in fact most functions in <string.h> are awful -- don't use them for new code.
In the same way, zero-terminated strings are there for historic reasons. They weren't a C invention. And they are staying for compatibility. There's no practical way to get rid of them.
I don't think that it would be useful to add another string type to the C library. The types of programming where C is useful today, you need memcpy and snprintf, that's about it. To add another standardized string type would only lead to a situation where we now have 15 incompatible solutions, and none of them are good for everyone.
Built in string types are more useful for languages with some form of automated resource management where one is used to mindlessly concatenating and splitting strings. The types of programming where that's a valid approach, don't use C in the first place. It's a bad fit.
Btw. zero-terminators are not entirely bad. They are an in-band signal (and can be easily completed using an additional out-of-band signal). And that can be quite useful, for example when looking at a plain binary. The space saving part that comes with zero terminators for small text strings is another thing, but admittedly has become irrelevant.
Not the only examples, there are plenty of other systems following similar approaches.