As someone who scripts mostly in Python I prefer Rust over Go. If I could have Go with more functional paradigms (a map function!) I'd be happier with it.
Go seems most comfortable in network and systems roles. I think that fit sees more competition from Java and C++ than Python. But that’s biased by my experience of mostly seeing Python in analysis/scientist roles with the odd Django use here and there.
As a language, I've always found Go to be a compelling middle ground between Java, Python, and C. It writes quite linearly and plainly like Java, but with the brevity/typing somewhat closer to python. And as a GCd languages they can be quite similar in usecases. It brings the structy-ness and memory austerity closer to C, but dosnt really operate in the same niche.
The reason it attracts Python programmers more than Java or C is because anyone who would leave for the language features left already. If you didn't like Java you'd be using something else already. There's so many options in those domains. On the opposite end, you're likely working in C because you needed to, GCs typically don't fit into those same uses.
In terms of what it's good at, Go is most similar to Java/C#. It's a pretty fast, fairly straightforward, strongly typed, roughly object-oriented, general-purpose programming language. It has some distinct implementation differences from Java/C# (AOT compilation, different implementation of polymorphism, etc), and it is further towards the straighforwardness end of the straighforwardness-expressiveness axis than they are, but it's comparable.
But in terms of the niche it occupies in the whole programming ecosystem, it's rather different. Its straighforwardness makes it easy to pick up, and as you note, it has become a popular choice for dynamic language programmers who either want a fast, typed language as a second language, or who want to move on from their current language altogether.
I don't know much about .NET, but that isn't true of Java in a substantial sense. Using AOT compilation would mean not using bytecode weaving and some other dynamic features, at which point you're not really using Java.
Bytecode weaving is not something supported officially by the language standard, just something that "happens to work, use at your own risk" kind of thing. There are even Aspect Oriented programming libraries for C++ that work at machine code level, just as info.
Examples of Java AOT toolchains since around 2000: Aicas, Aonix, JET, PTC, Websphere Real-Time, gcj, Embedded JVM, Gemalto, J/Rockit.
Not all of them have survived to this day due to multiple reasons, mostly business related, PTC has acquired Aonix, gcj was abandoned when OpenJDK was released, and JET has given up their business as of this year, for example.
Likewise on .NET side, it was shipped with NGEN since version 1, Mono/Xamarin uses AOT for iDevices, Sony and Nintendo consoles, Unity AOT compiles via IL2CPP, Windows 8.x uses MDIL which produces AOT binaries on the Windows Store, Windows 10 has .NET Native, with CoreCLR and .NET going to get merged in .NET 5.
Also Singularity and Midori only used AOT mode, making use of MSIL just like LLVM uses its bitcode.
"I was asked a few weeks ago, "What was the biggest surprise you encountered rolling out Go?" I knew the answer instantly: Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++."
He later writes:
"Python and Ruby programmers come to Go because they don't have to surrender much expressiveness, but gain performance and get to play with concurrency.
C++ programmers don't come to Go because they have fought hard to gain exquisite control of their programming domain, and don't want to surrender any of it. To them, software isn't just about getting the job done, it's about doing it a certain way.
The issue, then, is that Go's success would contradict their world view.
And we should have realized that from the beginning. People who are excited about C++11's new features are not going to care about a language that has so much less. Even if, in the end, it offers so much more."
I like Rob Pike but wow that sounds like a bad argument, at least based on the parts you quote. Saying, effectively, "you just don't understand how great it is" and then insulting the intelligence of C++ programmers isn't going to win many people over.
I think Pike actually missed a real reason for the effect he saw: Python and Ruby were at the time (and Python perhaps still is, Ruby less so) languages that were hot as on-ramp languages (Ruby especially in webdev, Python in a wider number of areas) where you had lots of people whose entire experience with programming was in that language, maybe one or two broadly similar dynamic languages (JavaScript especially), and maybe some static experience in C and/or Java (the latter often as the prior hot language for webdev for programmers who had run from there to Ruby.)
For that kind of programmer, “more speed and easier deployment than Python/Ruby, less type-system incantation than Java, and more type-system value than C, with a decent concurrency system that seamlessly exploits available parallelism is a pretty compelling story, at least for some uses.
But each of those features (and most combinations of them) are less surprising with broader experience, because they aren't all that uncommon, and Go is far from the best example of any of them, or even many useful combinations (not sure it's even the best example of all of them in combination.)
For writing complete programs I'd be inclined to agree that Rust could do pretty much everything Go could do. However, I'd be inclined to say the reverse is not always true although in the vast majority of circumstances it will be.
This is actually not accurate, there are some simple task that are actually very hard to do because of the borrow checked that are trivial to implement in a GC language.
Surely not "because of the borrow checker", since it's trivial to relax its enforcement with very limited runtime overhead. The tasks that essentially require GC (and this is pretty much always the case, even wrt. C!) are those where you're dealing with general graphs, potentially with cycles, and where the overall profile is such that you can't simply deal with it by allocating everything within an arena and then wiping it when you're done. This is where something like LISP traditionally shines, but Go of course ships with a well-designed concurrent GC that makes it a viable candidate in this space.
Certainly because of the borrow checker, try to implement a GUI using Gtk-rs to see how much fun it is, to the point that even the samples use macros to reduce the boilerplate of accessing widget data from event handler callbacks.
Author here. I have read somewhere (and have two links in the post) that the FFI transition between native code and Go has huge overhead because of Go runtime and bookkeeping Go has to do for making such call safe. But calling Rust e.g. from C# P/Invoke has the same cost as calling C library. So the point is that writing a complete program in Go is probably better or equal, e.g. some network utility. But if I write a shared library that I call a lot from C# via P/Invoke, Go will have much higher overhead. This may be wrong for the latest Go versions, I researched that around a year ago.
I mean talking to Go from C or any other language as if Go was replacing a C library. Could not find low-level detail on this, but I remember it used to be very slow. E.g. PInvoke has an overhead of between 10 and 30 x86 instructions per call, which is quite small.
Actually I'm not sure if that is possible now to call Go from C via some C ABI/ABI. I looked into CGO in the past.
Alternative to Go, the ease of talking to C could get simple, V language which transpile into C code with minimal overhead, still infancy at this stage, the end goals is to translate C source to readable V code.
This wasn't always the case. When Rust was publicly announced, there was a heavy emphasis on concurrency via a an actor-based green thread model. It's also easy to compare them because they were sponsored by direct competitors - Google & Mozilla.
Personally this feels like an odd conversation. Languages are lucky if they can find a niche where they get used substantially.
Rust has brought high-level language features, like memory safety, data race free, and an advanced type system to a low level space that didn’t have a great option in place (yes, there were other options, but none ticked all those boxes so elegantly). Rust keeps gaining traction in this space because of all those features.
I’m all for languages finding their niche, and Zig might end up attracting C programmers in a way that Rust doesn’t. That would be great, but the difference with Rust is that it’s attracting programmers to a space where they wouldn’t necessarily have gotten involved before. It’s that fearless mentality, and it’s helping expand the numbers of devs working in this area, and that’s a really good thing. Enabling people to do really great things without worrying about sharp edges and unknown issues, is pretty great.
IMHO, Rust is not the new C, perhaps D or Zig could be the new C. Rust is the hardest language i failed to learn and eventually gave up. C is one of the easiest language to learn but difficult to master.
Edit: Rust libs can be used to interface with C, but so could other languages. Porting the huge amounts of system software is near impossible task.
In that exercise Rust is compared with C from zero cost C ABI point of view. Rust could replace C for shared libraries. Other languages could work with Rust cdylibs as if those libs were written in C. But as the language, Rust features such as safety are good. I did not intend to compare the languages, but the use case of shared libs with C ABI. Also the title has "as", not "is", and that word choice is very intentional and not accidental.
the people that seem to have the least trouble with rust are coming from ocaml or f#. if your c++ style is highly imperative it seems to beat you up until you quit or figure out the patterns it prefers the prefers is the hard part, because it isn't wrong it just isn't a well supported style. I am concerned about the amount of syntax rust has accumulated. if I play in my subset I'm fine but I often find supposedly idiomatic rust that looks like an entirely different language to what I write
With C it might be easy to get a program to compile, with Rust it's easy to be sure that a compiled program is actually correct from a memory safety PoV. Rust is harder to learn, but much easier to master. I guarantee the vast majority of systems programmers writing C code are not masters in the sense that they will write memory-unsafe code regularly.
Personally I think Rust is competing with C (and C++ as well as Go) in the "systems programming" sphere. It isn't a competitor to C's "portable assembly" history. It's a far more FP-esque approach to systems programming.
42 comments
[ 3.3 ms ] story [ 90.2 ms ] threadReally? That seems odd to me. I guess there's some overlap between the two languages but they mostly exists in different spheres.
C++ would be the more obvious comparison.
The reason it attracts Python programmers more than Java or C is because anyone who would leave for the language features left already. If you didn't like Java you'd be using something else already. There's so many options in those domains. On the opposite end, you're likely working in C because you needed to, GCs typically don't fit into those same uses.
But in terms of the niche it occupies in the whole programming ecosystem, it's rather different. Its straighforwardness makes it easy to pick up, and as you note, it has become a popular choice for dynamic language programmers who either want a fast, typed language as a second language, or who want to move on from their current language altogether.
Examples of Java AOT toolchains since around 2000: Aicas, Aonix, JET, PTC, Websphere Real-Time, gcj, Embedded JVM, Gemalto, J/Rockit.
Not all of them have survived to this day due to multiple reasons, mostly business related, PTC has acquired Aonix, gcj was abandoned when OpenJDK was released, and JET has given up their business as of this year, for example.
Likewise on .NET side, it was shipped with NGEN since version 1, Mono/Xamarin uses AOT for iDevices, Sony and Nintendo consoles, Unity AOT compiles via IL2CPP, Windows 8.x uses MDIL which produces AOT binaries on the Windows Store, Windows 10 has .NET Native, with CoreCLR and .NET going to get merged in .NET 5.
Also Singularity and Midori only used AOT mode, making use of MSIL just like LLVM uses its bitcode.
So yeah, just lack of information.
"I was asked a few weeks ago, "What was the biggest surprise you encountered rolling out Go?" I knew the answer instantly: Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++."
He later writes:
"Python and Ruby programmers come to Go because they don't have to surrender much expressiveness, but gain performance and get to play with concurrency.
C++ programmers don't come to Go because they have fought hard to gain exquisite control of their programming domain, and don't want to surrender any of it. To them, software isn't just about getting the job done, it's about doing it a certain way.
The issue, then, is that Go's success would contradict their world view.
And we should have realized that from the beginning. People who are excited about C++11's new features are not going to care about a language that has so much less. Even if, in the end, it offers so much more."
In a company with funny interview games that even some Phd aren't able to tackle.
For that kind of programmer, “more speed and easier deployment than Python/Ruby, less type-system incantation than Java, and more type-system value than C, with a decent concurrency system that seamlessly exploits available parallelism is a pretty compelling story, at least for some uses.
But each of those features (and most combinations of them) are less surprising with broader experience, because they aren't all that uncommon, and Go is far from the best example of any of them, or even many useful combinations (not sure it's even the best example of all of them in combination.)
And of course, C# and Java also have overhead.
Actually I'm not sure if that is possible now to call Go from C via some C ABI/ABI. I looked into CGO in the past.
https://vlang.io
Go and Rust don't overlap/compete enough to be interesting comparisons, especially considering how often the comparison comes up
Rust has brought high-level language features, like memory safety, data race free, and an advanced type system to a low level space that didn’t have a great option in place (yes, there were other options, but none ticked all those boxes so elegantly). Rust keeps gaining traction in this space because of all those features.
I’m all for languages finding their niche, and Zig might end up attracting C programmers in a way that Rust doesn’t. That would be great, but the difference with Rust is that it’s attracting programmers to a space where they wouldn’t necessarily have gotten involved before. It’s that fearless mentality, and it’s helping expand the numbers of devs working in this area, and that’s a really good thing. Enabling people to do really great things without worrying about sharp edges and unknown issues, is pretty great.
Edit: Rust libs can be used to interface with C, but so could other languages. Porting the huge amounts of system software is near impossible task.
Personally I think Rust is competing with C (and C++ as well as Go) in the "systems programming" sphere. It isn't a competitor to C's "portable assembly" history. It's a far more FP-esque approach to systems programming.