Hacker News new | comments | show | ask | jobs | submit login
Go vs. Rust? Choose Go (matthias-endler.de)
87 points by mpweiher 36 days ago | hide | past | web | 159 comments | favorite



Much as I like Rust, I have to agree. When you have to get it done, use Go. When you want to explore advanced experimental programming constructs, use Rust. The Go guys knew when to stop. Arguably they stopped too early, before generics or parameterized types, and "interface[]" is used too much. But that doesn't seem to be a big overhead item.

Rust has the complexity of C++ plus additional complexity from the functional community. Plus lots of fancy template cruft.

The trouble with language extensibility is that people use it without an overall plan. The end result is a Winchester Mystery House language.[1] LISP went down this rathole, and Scheme had to be developed to get out of it. C++ went that way when nobody stopped the Boost crowd before it was too late. Now it's happening to Rust.

(Anyone involved in language design should see Václav Havel's "The Memorandum". Or at least read it; I've seen it performed, but it's not performed often.)

[1] http://www.winchestermysteryhouse.com/


> Rust has the complexity of C++ plus additional complexity from the functional community.

Not even close. C++ has IIRC whole books just on exception handling. And it's crazy how many styles of writing C++ there really are. Exceptions or not, standard library or not, templates or not, boost or not, etc, etc. C++ templates are a language of their own. A lot of times, if your code made a particular choice, you are stuck with a set of libraries that made the same choice, or you'll be writing an insane amount of boiler place to duck tape it together. This code tends to be some of the most sucky code in existence.

Rust on the other hand feels very cohesive and there seems to be like one style of really writing it.

What parts of Rust do you find experimental? The only thing that's new (in a popular language) is the borrow checker but we can all agree that despite it's novelty, it's a huge step forward.

Another thing about Rust is the community. Just about every Rust package I've come across was very well written. Some even teach me a thing or two. E.g. I haven't seen trees implemented the way they are in this package previously https://github.com/PistonDevelopers/history_tree.

Go packages are more all over the place. Also the community seems to concentrate mostly on web stuff. The recent Vulkan tutorial by the Khronos group (i.e. the people behind the standard) used Vulkano.rs which blew my gourd. https://www.khronos.org/blog/beginners-guide-to-vulkan

> Now it's happening to Rust.

Please elaborate.

> Václav Havel's "The Memorandum"

It's crazy that you are aware of this, I always thought that his work had only a local appeal.

I've written a modicum of Go and the boiler plate was driving me crazy.


Most things about Rust are well thought out and well designed. It's the total weight that gets you. Like LISP, back when too many smart people from MIT were adding to it without an overarching vision. It's hard to keep it all in your head. The add-ons aren't libraries with specific functions; they're new control structures. This gives me the feeling I had dealing with the MIT Loop Macro.[1] Proliferation of control structures is not a good thing.

> Václav Havel's "The Memorandum"

It's crazy that you are aware of this, I always thought that his work had only a local appeal.

Saw it at Fort Mason in SF in the 1990s.

I've written a modicum of Go and the boiler plate was driving me crazy.

That's how I felt about Rust. See some code I wrote at [2], at "Return type and its error handling". Now that's boilerplate. The last time I mentioned this, it was brushed off with "Oh, you'll be able to do that with the '?' operator when it's implemented." Feel free to submit a pull request for the rewrite.

[1] https://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/...

[2] https://github.com/John-Nagle/rust-rssclient/blob/master/src...


I get your lisp comparison but the fundamental difference is that in rust even the craziest stuff is bound to be safe. I wouldnt be comfortable doing this sort of stuff in other languages, but I'm OK doing it in rust.

Re error handling, Option's map method doesn't do the trick? Sorry on my phone and reading code is hard.


I think you are describing the "design by committee" kind of problem, that Rust definitely has.


> When you have to get it done

When you have to get what done? Seriously. There are different reasons to pick different technology stacks, some of them because of language features, some of them because of technology stack. Getting it done at my current job is generally Java, b/c that's the tech stack used by most.

> The Go guys knew when to stop. Arguably they stopped too early...

The stuff you mention Go not having is exactly what Rust brings over Go, is it not?

> But that doesn't seem to be a big overhead item.

I disagree, it's the fundamental reason I don't use Go by choice, and instead turn to languages that allow for more expressiveness.

> Rust has the complexity of C++

You say you like Rust, but I find this statement hard to believe if you've learned the language. It has almost none of the complexity of C++. That's not to say that the language isn't more complex than Go, it is. But to say it's anywhere near C++ feels disingenuous.

The Rust RFC process is very good IMO at preventing inappropriate changes from being introduced into the language, "Winchester Mystery House language" is unnecessary FUD.

Look, you don't have to like the language. But, making statements that seem unfounded isn't really appropriate.


> Rust has the complexity of C++ plus additional complexity from the functional community. Plus lots of fancy template cruft.

This is so patently false. C++ contains an order of magnitude more complexity than Rust (as one would expect for a language that continues to evolve radically 30+ years after it was designed; for better or worse, complexity is C++'s game).


> Plus lots of fancy template cruft.

I should start a tally of the number of times that I have told you that Rust doesn't have template metaprogramming. You've been saying this for years; what have you actually written in Rust?


I'm not sure this is a useful distinction. I'm sure you're correct for whatever definition of "template metaprogramming" you're using, but Rust does have a pretty powerful generics system. That gets you most of the way to what C++ templates are used for, albeit less cruftily IMO. Coming at it from a different side, if a C++ person asks you, "does Rust have templates?", you're likely to say "no, but it does have generics which let you do most of what you need templates for". It's definitely enough to let you write complicated, over-general code if you want to. So in an informal context like this, the difference between "template metaprogramming" and generics is probably not one you want to stand on, at least not for your whole argument. There's lots of better arguments to make even if you accept Animats' language.


The claim that Rust's generics system is "fancy template cruft" on top of "all the complexity of C++" is absurd, though.


Yes, which is why I carefully phrased my post to avoid any implication that I might agree with that claim. To nevertheless get a reply like this is profoundly irritating.


I'm sorry.


It's a little unfair to unload on you, I'm just sick to hell of straw men, and it feels like there's no way to make sure people will engage with what I'm actually saying target than what they think I'm saying. It's a pervasive problem. :/


Template metaprogramming is the ability to e.g. say

int x = factorial<5>::value;

and have 'x' initialized to "120" (i.e. execute computation at compile time, not just define new types). Can you do anything like that in Rust? I only read a few about Rust, but my feeling was that it has powerful generics, but NOT template metaprogramming.


We just accepted an RFC for this. So not today's Rust, but tomorrow's.


Which is used more, Common Lisp or Scheme? C++ is as popular as C. Python and JS remain heavily used despite becoming more complex over time. Java is still widely used after adding major features like generics, lambdas, streams.


Is this intended to be a response to the parent comment? What's the connection?


It is. The parent was praising Go's simplicity in comparison to languages like C++, and that Lisp had gone down the complexity rabbit hole, thus the need for Scheme. As a counterpoint to that, complicated languages have seen continued widespread use, so it's not obvious why being simple (intentionally leaving certain language features out) is preferable.

Meaning, the entire programming community hasn't quit on C++, CL, Java, etc in favor C, Scheme, Go or pick your simpler language. Most of the JS community seems very pleased with ES6 & 7 additions.


The problem with templates in C++ is that they are just that. The compiler will hapily generate broken code if you use a map with a type that doesn't implement comparison operators and then spew out hundreds of lines of compiler errors at a location that is another hundred lines deep in library code away from the line of code that caused the error in your application. Something as trivial as type constraints for type parameters like you see in virtually any programming language with generics is the solution.

I don't feel that C++ is complex at all. It just has more crap and every programming language has crappy parts.


Why the duality there ? Rust vs Go. Go is quicker to get hacks done in.

Okay ... so is Python, Ruby, Perl, ... and they will beat Go by a mile on quickly constructing small programs.

Even if it must be fast, there's still C#, Java and quite a few others.


> When you have to get it done, use Go.

Or Java? I mean, I've never seen any reason to use Go over existing, better languages.

Never thought I'd call Java better than anything, but there you go.


> When you want to explore advanced experimental programming constructs

This is a weird euphemism for "get it done correctly". It seems to come up in any discussion about languages that help you to write correct code.


Now what was wrong with that?

I totally subscribe to the view that advanced experimental programming constructs are neither a guaranteed way, nor the only one, to write correct code. Doesn't a language which helps you to get code done (and makes it easy to iterate on it, and has the right psychology to let you move on instead of trying yet another way to get at the old problem) help you write correct code, as well?


Nothing in Rust is an "experimental construct", so I'm not sure why you keep using that phrase.

Lightweight formal tools like those available in Rust do guarantee that your program satisfies certain correctness properties that Go cannot.

To guarantee correctness in all aspects you need more heavyweight tools than Rust provides, but they do exist.

No, languages that let you "iterate" and don't provide any sort of formal guarantees don't help you make correct code. They help you pump out a lot of mediocre code that probably works acceptably enough to satisfy a business with a medium-low focus on correctness.


> Nothing in Rust is an "experimental construct", so I'm not sure why you keep using that phrase.

I don't do Rust (but I did some Haskell), and apart from the fact that both are very small elitist communities, some idioms are definitely evolving or changing as people try to find out what actually works in practice. So, from this practical standpoint, yes, experimental.

What's lightweight lies in the eyes of the beholder. I certainly don't think of the line noise that is Rust code in the wild (again, to an outsider) as "lightweight".

Nor do I think of the bazillions of ways you can obfuscate the simplest things in Haskell (moving 10, 20, or 90 percent of the perceived required invariants from value to type level), requiring large and possibly incompatible sets of language extensions, as lightweight. It's a burden of choice, and changing choices has huge ramifications on the rest of the code (these decisions are inherently unmodular, which is BAD).

> No, languages that let you "iterate" and don't provide any sort of formal guarantees don't help you make correct code. They help you pump out a lot of mediocre code that probably works acceptably enough to satisfy a business with a medium-low focus on correctness.

I'm sorry, but that's a very one-sided view. You can absolutely write correct code in them, and something that helps you to do it faster does help you write correct code. Simple as that.

You seem to think that there is exactly one reasonable, justified level of formal correctness. And that is the level where you stand, Rust in this case.

But that's wrong. Everything has a cost. And formalisms like Rust are still pityful attempts at constructing "formally correct" software. There might be some software that is "completely" verified, but at a cost that is simply not justifiable for the vast number of applications. Ignoring the fact that most real-world problems are ill-specified from the start.

There is more than one valid approach to do things, and more so, to do many different things. It's cool what you're doing, but there are other valid approaches to find things to do and make them work.

Get out of your little corner mate.


> both are very small elitist communities

Yet another irrelevant, unjustified, negatively connoted description that has no basis in realty; first "experimental", now "elitist". Come on.

> What's lightweight lies in the eyes of the beholder.

In terms of formal methods that exist, both type systems simple enough for decidable inference and lifetimes are absolutely "lightweight". But sure, I guess every description is subjective.

> You seem to think that there is exactly one reasonable, justified level of formal correctness. And that is the level where you stand, Rust in this case.

This is untrue. I don't believe Rust is a paragon of correctness-oriented programming; I just think it's a hell of a lot better than something like Go. Rust at least lets you prove a sizeable chunk of practical safety and correctness properties.

> And formalisms like Rust are still pityful attempts at constructing "formally correct" software.

What Rust provides, including type and memory safety and completeness checking, gets you a surprisingly large way towards complete formal verification, imo.

> Get out of your little corner mate.

What was your goal with this statement? This is a fairly technical discussion, not a Reddit politics thread. There's no need for you to stoop to vague insults.


> Rust at least lets you prove a sizeable chunk of practical safety and correctness properties.

Not true in my perception. The things I do with conventional languages, I seldom worry about invariants that could be guaranteed by a more structural language, like null pointer safety or absence of side effects (I seldom worry about them because I seldom get them wrong).

Much more I constantly juggle invariants like "this integer is a power of two and that integer is an odd positive one. This other pointer resource is the one that correlates with the integers in that specific way."

These types of invariants are not practical to encode even in advanced type systems; I've even had a quick look and Agda and what-was-that-other-system-called, but it went quickly over my head.

> Yet another irrelevant, unjustified, negatively connoted description that has no basis in realty; first "experimental", now "elitist". Come on.

Not meant as an insult at all.

>> Get out of your little corner mate. > What was your goal with this statement? This is a fairly technical discussion, not a Reddit politics thread. There's no need for you to stoop to vague insults.

Dito. Your counter-arguments seemed to be heavily implying that there is no way way of getting code done correctly in a language that is somehow "lesser" than Rust. And furthermore you seemed to be preconceived about what others' judgement of the relevance of "correctness" is (which is a vague term - it sometimes seems to be more than "it runs correctly all the time and we could even prove it correct or actually have done so, even if not in some fancy modern type system").

So that little punchline at the end was not meant in an insulting way at all. Just to give note how your comments were perceived. Not that I really need to tell you, but it's good to admit other viewpoints / take interest how problems are typically approached in other domains.

(By the way, I took an interest in John Carmack's recent engagements with static analysis and functional programming. I, for one, LOVE Carmack not only for being undoubtedly a genius who gets shit done, but furthermore for being so undogmatic about his approaches and views. You might have followed some of it, too -- for example, https://www.gamasutra.com/view/news/169296/Indepth_Functiona... , and it's also interesting to see that in the end he backed away after having seriously considered Haskell for game programming. I'm not sure if he backed away from his (actually existing) VRScript implementation written in (untyped) Racket as well)


> Much more I constantly juggle invariants like "this integer is a power of two and that integer is an odd positive one.

You can easily represent exactly these sorts of constraints in a language with something like newtype wrappers (e.g. via a wrapper over integers with an associated injective function from the newtype back to integers).

> These types of invariants are not practical to encode even in advanced type systems;

As I explained, you don't even need an advanced type system if you take the most straightforward approach. You just need a marginally powerful type system like rust's. You could probably even hack it in Go if you wanted, but it would be annoying.

However, these specific examples are also quite easy to represent in either dependent type systems (like Agda's; I'm not sure what your objection is there) or liquid type systems like that of Liquid Haskell.

> a language that is somehow "lesser" than Rust

So you're mad that I think Go is inferior to Rust? Would you like me to expand on why I think that?

> but it's good to admit other viewpoints

Unless you have good reasons for disagreeing with them, which I do. You're not obligated to agree with everyone on everything. I think you're wrong about languages with poor formal systems being acceptable for correctness-oriented programming, so I'm not going to "admit your viewpoint" just because it's polite or something.


> You can easily represent exactly these sorts of constraints in a language with something like newtype wrappers (e.g. via a wrapper over integers with an associated injective function from the newtype back to integers).

This is not even close to reality. In the end they are integers. You will have to add/combine values with different qualities, which means at some point you need to unwrap all these layers of abstraction. The only difference it makes is that you can't recognize anymore what happens in this sea of useless wrapping and unwrapping. You constantly juggle more invariants than you can make newtypes for. Instead of simply writing "x & FOO_MASK" I will not follow some vague idea that if you wrap it in another layer of ad-hoc concept, the complexity will just magically go away and it will all just magically be "correct".

In one sentence, you can move everything to the type level if you insist, but at some point you have to DO it. The complexity does not go away, all you can hope to do is implement a given artifact only a single time. (And plain procedures are pretty good at that for >90% of what I do). Most things are done exactly once in a code base, so moving them to the type level is just a crazy bad idea.

>> a language that is somehow "lesser" than Rust

> So you're mad that I think Go is inferior to Rust? Would you like me to expand on why I think that?

I'm not mad at all. In fact I've never done Go either; I do most of my work in C and Python and sh (and some coding competition style things in C++11 if I need the quick container). I'm perfectly happy with the expressiveness they provide.

Actually I did read your blog post and regarding missing generics I even agree somewhat. But what I think you're missing is that it's not the biggest deal under the sun. I actually like to throw a few void pointers around in C, and it has considerable advantages, for example being highly modular (does not enforce any dependency hell crap, compiles quickly...).

I don't care about NULL-pointer safety. It's one of the least problems I encounter.

I don't care about formalized error handling. In many simple applications you simply die right away, and for many more complex and long lived ones, explicit error handling is the right choice and leads to a consistent code base, and does not force me to second-guess what conditions are "errors" and what not. Frankly error handling in Haskell is a huge mess.

I don't care much about operator overloading either. It wouldn't have been helpful in more than a handful of situations for me, so far. Instead of implementing extra syntactic sugar it's no big deal to simply call the relevant function three or five times. Again, that approach has advantages as well, for example I can easily search the locations where these functions are called. Also I can be sure that '+' means really an add instruction on the CPU.

And as I said I sometimes use std::map<K, V> et. al as well, but actually it's often only an interim solution until I realize I don't need that at all, because a V* would do, or I need an intrinsically linked map instead (which can't really be made as a template class, the only alternative being allocating the V's separately and making std::map<K, V* > instead), or I absolutely die suffering the compile times due to the added dependencies, or I can't bear the allocation overhead.

> Unless you have good reasons for disagreeing with them, which I do. You're not obligated to agree with everyone on everything. I think you're wrong about languages with poor formal systems being acceptable for correctness-oriented programming, so I'm not going to "admit your viewpoint" just because it's polite or something.

That's exactly the point: nobody pulled the correctness-first card. No, you can't disagree that people are productive and stuff EXISTS and works to a large extent, and advanced type systems are niche. I used to play CS:S for example and can't recall having any problems. I'm a heavy Linux user and the kernel is seriously rock solid, with the exception of a few reverse-engineered device drivers.

Not saying that there are not many buggy projects as well. Most of those are financially terribly undersupported.

Also not saying people are not looking for improvements to their methodologies, but you need to acknowledge the methods with which people get their work done, and that correctness-first approaches have largely not worked out so far. I'm not aware of any serious kernels or performant 3D Games written in Haskell. In fact, one of the highest-profile Haskell applications, GHC, does indeed have quite a few bugs, and this is because the type system simply can't encode all THAT many invariants, especially if you need to get something done in the end. (Besides that it's god awful slow sometimes, although I'm in no position to judge whether the implementation language is the reason, or the type system extensions are just not practical from a performance standpoint).

If you can make a little Tetris game in 3h in Haskell (or even Rust), I will tip my hat to you. Tried to do that but eventually gave up due to unsufferable compile times and terrible non-essential complexity due to opionionated framework (and I do have a basic understand how Haskell works, and I went with the most basic dependencies possible). But I did make a working Javascript+CSS Tetris in <3h and I don't think my C version with SDL (no fonts) took much longer.


> But that's wrong. Everything has a cost. And formalisms like Rust are still pityful attempts at constructing "formally correct" software. There might be some software that is "completely" verified, but at a cost that is simply not justifiable for the vast number of applications. Ignoring the fact that most real-world problems are ill-specified from the start.

You seem to be saying "it's hard to verify everything, so we shouldn't even attempt to verify anything," which is silly. I've found having memory safety to be a huge win, even if the Rust compiler can't verify that my program is doing the right thing.


It may be true that Go is easier to use than Rust but over time I have learned to essentially love Rust and hate Go. Rust isn't perfect by any means, but when I program in Go a lot of times I wish I could avoid costly abstractions that don't have any real reason for being required, and thus I usually avoid Go for any task I wouldn't just use Python for (sans the REPL). Go doesn't let me describe data the way I want it to let me. Concurrency is not even incredibly profitable using language idioms. I like the syntax, but frankly Go is in an entirely different league than Rust is. And that is to say, when I want to write a program Go sometimes is just not an option. Rust is always available, even if you have to do a little bit of learning.


What about Nim? I've found that a lot more productive than Rust even without libs.


how's the compile time with nim? go's compile time makes it almost as good as having a repl. i tried crystal a while ago and it has atrocious compile times.


The compile times are on par with Go. The Nim compiler (written in Nim and containing ~100k LOC) compiles in under 10 seconds on my MacBook Pro, and this is from a cold cache. It's even faster when making changes as the C source files generated by Nim are cached.


the question how big are the compile times on a project in the size of kubernetes, i wouldn't call that "quick compile time". even the go part of it. I mean yes the use case for many people who use go have a fast compile time, but once it goes huge, the speedup isn't as big as on other languages.


tangential question: are there still compiler bugs?


Of course, all software has bugs :)


This is not true, and shouldn't be used as a lazy excuse to write bad software. There is absolutely software that is entirely free of bugs; it just takes formal methods to get there for software of any reasonable complexity.


You can never however guarantee that a program will run free of errors. Hardware is faulty and not always in ways that are human caused: en.m.wikipedia.org/wiki/ECC_memory


Sure there is. But in practice most compilers I know of contain multiple bugs. The main difference between the compilers is how many users these bugs affect.


On a personal note I'm not a huge fan of the syntax. The type system looks nice but frankly not as simple and expressive as Rust's as well.


That's a shame. Which parts of the syntax do you dislike? Can you also elaborate on the type system?


Sure Dom (always nice to see you come up in Nim discussions :) if you want I can send you an email getting into specifics but: A lot of the syntax seems like a "special case." For example, being able to specify what value an enum variant prints with a tuple of a value an a string during declaration feels like the wrong way of doing things. In Rust, the way this would be handled is by implementing a Display or ToString trait. For the type system, it boils down to Concepts: in Nim, they're still in development, but in Rust, the language is built around them. And I love this.


Thank you for replying :)

No need to get into specifics. I think I understand your point and I must admit I am inclined to share your feelings about it too. Hopefully soon Nim's concepts will become stable enough to be used in such places too.


I am not the other poster but I would be extremely interested a similar email you offered, but on Go (if you've used it). My email is in my profile. I'm curious if you have any thoughts. Thanks!


> Both languages seem to be competing for the same user base and they both seem to be "systems programming" languages, so there must be a winner, right?

No, Go isn't a systems programming language because it has a GC.

This matters in constrained environments, like when doing embedded development, or for real time systems.

Sorry, but Go isn't in the same category as Rust or C/C++.

Go is in the category of Java and C#. And IMO its only advantage is that it can produce lighter binaries.

And while Java and .NET are evolved towards building lighter binaries, you can't evolve a GC-ed language towards one without a GC.


Oberon [1] showed that a GC-based language could be used as a systems programming language.

The various variants -- Oberon OS, Active Oberon, Bluebottle OS, A2, EthOS [2] -- were entirely written in Oberon (plus assembly), with GC at the OS level and I believe in some (all?) cases even in the kernel.

Oberon had a huge influence on Go, as did Wirth's other languages. Robert Griesemer worked at ETH Zürich (where all of this was conceived) for a while.

Then there's Singarity [3].

[1] https://en.m.wikipedia.org/wiki/Bluebottle_OS?wprov=sfti1

[2] http://www.progtools.org/article.php?name=oberon&section=com...

[3] http://en.wikipedia.org/wiki/Singularity_(operating_system)


> Sorry, but Go isn't in the same category as Rust or C/C++.

From the article:

> 99% of the time, Go is "good enough" and that 1% where it isn't, you'll know. And then take a look at Rust, because the two languages complement each other pretty well.


Yes, that means that 99% of the time you don't need a systems programming language. It's probably also true, depending on the specific case.


And for that 99%, Java or C# or OCaml or any number of other languages were already good enough. Not really sure what Go brings to the table.


> No, Go isn't a systems programming language because it has a GC.

I don't think a GC excludes a programming language from being considered a "systems programming language".


Please explain how you're going to GC on an 8bit microcontroller, or even an AMD64 when the bios/EFI passes control to you. GC requires a runtime; something needs to provide that runtime.

(JavaChips were interesting, thought iirc it only ran a certain subset of Java?)


Fwiw OCaml is a GC language and can run on PIC: http://www.algo-prog.info/ocapic/web/index.php?id=ocapic


That is interesting! Thanks! They seem to just be running the vm on PIC, though, not a straight compile. I wonder how well that works out in terms of resource utilization.


Which 8bit microcontrollers do Rust target?


AVR seems to be... in progress. But if we're discussing the inherent properties of a language, not just what happens to be implemented today, the point is whether it's possible with reasonable overhead (e.g. performance, no weird emulation).

High-level blog post: http://dylanmckay.io/blog/rust/avr/llvm/2017/02/09/safer-mic...

Tracking bug on GitHub: https://github.com/rust-lang/rust/issues/42450


What stops you from writing the runtime in the same language, just a subset of it that doesn't in turn depend on GC?


> What stops you from writing the runtime in the same language, just a subset of it that doesn't in turn depend on GC?

At that point you'd better off using C or C++ directly. Go gives you absolutely no advantage, only costly abstractions.


in C you're writing allocators without using malloc(), a part of the stdlib defined in the language spec. doesn't really feel qualitatively different to write Go without GC allocation. i guess it's more work but it's also not a showstopper that should decide whether Go is a systems programming lang or isn't. i mean it's not like we're talking about writing the Ruby runtime in Ruby here.

advantages of writing the Go runtime in Go might include, just spitballing here, avoiding ffi cost for runtime calls, enabling better optimizations around/into runtime calls, simplifying the build process, or even just enabling Go enthusiasts to contribute to the runtime without learning C. talking about actual language features, i think I'd almost be tempted over just by Go having a module system, but there's probaby a few other subjective ergonomic benefits that you can use without falling into the GC requirement. I'm not sure what exactly decided it for them, maybe i should look that up.

there's probably gonna be some OS-level non-Go shims written in either C or assembly or the weird Go way to write assembly but i feel that's fair as C-written runtimes probably need to have at least some inline asm somewhere as well.


Because that subset of the language will often be different from the actual language.


We need different terms for "language you can use for high-performance infrastructure" (Go fits here) and "language you could use to implement GC from scratch" (not Go). "Systems language" gets applied to both of these categories.


The former is an application language. It may be a high-performance compiled application language (like Go, Java, etc), but if you can't write a driver / OS in it it's not a systems language.


Go's GC is implemented in Go, but with manual memory management.


From the article:

> Go is not even a systems programming language.


Go is for distributed systems. It can be for system programming, depending on what you mean by system programming.

I would personally not assimilate system programming to embedded.


> Go is for distributed systems

Go is for distributed SERVERS.


Yeah, Go is pretty bad at distributed systems programming, well, idiomatic Go. It can be tolerable if we throw away all those poorly designed idiomatic networking packages and multithreading. But it's definitely not for distributed systems.

Its niche is more in boring servers and command-line apps where an interpreted language would be too slow, too memory hungry or harder to ship, where you can get away with only the simplest concurrency, but still prepared to deal with time-consuming concurrency bugs. Like a typical commercial CRUD app, a command line automation and data processing utility, a quick one-off program.


Or in simpler terms.

Any server app where python/perl/ruby are too slow, and you can't use java/C#/C++ for some reasons.


And even then, it's ok. Hell how many places has Java been embedded?



I feel maybe my comment was misunderstood. I was saying that a GC doesn't disqualify a language from systems work, even embedded, using java as an example...


Or billions of places to talk in numbers.

Java is running on so many smart cards, TV and set top box nowadays. It's almost everywhere.


I chose rust after endless annoyances in a 100kloc go program due to piss poor type safety and nil pointer checks, lack of meaningful containers, and working around GC when working with C libs. I didn't think I needed any of those things until it was too late. Any project of meaningful size will eventually need everything go avoids.


You rewrote a 100K LOC project because you felt the language is lacking! It really must have been a huge battle with the management (or whatever stakeholder there is), I suppose? If you did make your case against others, could you please share how you went about that?


No, I didn't rewrite it. But the next project I worked on I no longer considered Go an option


Oh now I see how I've misread that, sorry!


Out of curiosity, what type of project was this? Did you end up rewriting the entire 100K loc in Rust? I ask because Docker and Kubernetes are large projects and as far as I know, using Go hasn't been an issue for them.


it actually has. Try to ask around some former workers of those projects.


Any links?


Can you elaborate on "piss poor"? Are you referring to empty interfaces, or...?


"Rust and Go are both systems programming languages, so we have to compare them! Go wins because it's easier. By the way, Go isn't a systems programming language and would suck for systems programming."

That's basically what I got from this article.


The point of the article is that Go and Rust don't actually serve the same purpose. So asking "Go or Rust" 99% of the time means choose Go. For the other 1% of the time you (should) know that you actually need Rust, not Go.


The problem with performance is that "you don't need it" right up until the moment you do. It's the same argument startups use for writing their apps in python. You get your "massive dev output" right up until you realize your web app isn't going to scale and you've got to do a full rewrite and runtime errors have burnt out most of your dev team.

There's a reason why the lion's share of code written today is Java or C++ and Rust compares much more favorably on the more "enterprisey" merits (stability, expandablility, performance) than the startup merits (how fast can we ship).


Why not Java, Kotlin, Scala, Clojure, C#, F#, OCaml, CL, Scheme, Haskell, or any other efficient GC language?

Its funny to compare Rust, whose sole purpose was to enable garbage collector free semantics, designed to reimplement an efficient and small memory web browser to languages with a GC.

Go is great, because compared to most other GC languages, it has small self contained binaries and comes with a great toolchain. Its AOT is better then C# and Java, and bundles its runtime with every app. It's not great, because people would really just want a more expressive language that had those same qualities. That's why there's effort for Kotlin native and Scala native.

If anything, the fact that some people are thinking to pick Rust over Go is a testament to Rust. Rust should have nothing of interest over Go, except for no GC. But apparently, even with the added complexity of a borrow checker, it has enough to entice people from GC languages.


Or choose OCaml: http://engineering.issuu.com/2015/09/17/ocaml-production.htm...

It's enterprise-ready. Seriously.

Hate the syntax? Wait a little bit and try out ReasonML (new syntax for OCaml), e.g. the following OCaml

    channel
      |> Channel.push "new_msg" [%obj { body = "a" }] ~timeoutMs:10_000.0
      |> Push.receive "ok" (Js.log2 "Created message")
will become (pretty much) the following Reason

    channel
      |> Channel.push("new_msg", { "body": "a" }, timeoutMs::10_000.0)
      |> Push.receive("ok", Js.log2("Created message"));


Still waiting for Duke Nukem Forever, aka multicore, until then OCaml has major limitations for such a low-level and performance-oriented language.


Let's be honest. You don't really need multicore (i.e. language-level parallelism support) for most enterprise work. Hence people use NodeJS just fine. OCaml has not one but two very nice concurrency libraries so for most backend work you will be absolutely fine.


Sure, but for specific projects, I'd leave NodeJS faster if OCaml had multicore.


You don't even need to leave NodeJS to get all the OCaml benefits: BuckleScript compiles to readable JS. Compare the input and output of the example: https://github.com/bucklescript/bucklescript#an-http-server

You can get all the type safety benefits of OCaml right now, on NodeJS.


in what sense is ocaml production ready? does it have the tooling? ecosystem? is there even another stl than jane street's library?


As a meta comment, there will always be detractors of any even slightly esoteric language.

The author of pgloader[1] said the other day "When I told people I was going to use Lisp, I was told it was stupid because there weren't any libraries; when I packaged it for Debian, I was told that I had too many external dependencies"

It was probably different groups, but there were complaints both about not enough and too many libraries!

1: http://pgloader.io/


FYI, here is list of pgloader (direct) dependencies (35 of them): abnf, alexandria, asdf, asdf-finalizers, asdf-system-connections, bordeaux-threads, cffi, command-line-arguments, csv, db3, drakma, esrap, fad, flexi-streams, interpol, local-time, log, lparallel, markdown, md5, metabang-bind, postmodern, ppcre, py-configparser, qmynd, quri, simple-date, split-sequence, sqlite, trivial-backtrace, trivial-utf-8, unicode, usocket, utilities, uuid.


List of what they do, summary first, then detailed:

Portability libraries[1]6: bordeaux-threads, CFFI, command-line-arguments, trivial-utf-8, trivial-backtrace, usocket

Parsing 6: abnf, esrap, markdown, py-configparser, simple-date, quri

Database interfacing 5: csv, db3, postmodern, qmynd, sqlite

Build-tool/dependency management 3: asdf, asdf-finalizers, asdf-system-connections

utilities 3: alexandria, split-sequence, utilities

portable I/O & character encoding 3: unicode, fad, flexi-streams

sugaring 2: metabang-bind, interpol

Other 6: drakma(HTTP), log, lparallel, md5, ppcre(regex), uuid

abnf: parser generater for augmented BNF

alexandria: utility library

asdf-*: build-tool

bordeaux-threads: mutithreading primitives

cffi: foreign function (i.e. calling C)

command-line-arguments: exactly what it says on the tin

csv: comma separated variables (also supports similar things like tsv)

db3: dBASE III reader

drakma: http client

esrap: Parser generator

fad: Files And Directories (portable file-system)

flexi-streams: in-memory streams (file-like objects) and encoding

interpol: interpolated strings (e.g. variable substitution in strings). Also includes regex literals.

local-time: timestamps &c.

log: logging

lparallel: high-level threading

markdown: markdown

md5: md5

metabang-bind: macro library for doing various fancy bindings (setting a variable to a value for a particular lexical or dynamic scope) in a single construct.

postmodern: Postgresql interface library

ppcre: perl compatible regex

py-configparser: parser for .ini like files (compatible with the python "configparser" library)

qmynd: MySQL library

quri: fast URI parsing/emitting library ("quicker" than puri, the Portable URI parsing library)

simple-date: date/time; not sure what it offers that local-time doesn't

split-sequence: Splits sequences based upon value or function of value

sqlite: sqlite3 interfacing

trivial-backtrace: tool for getting backtraces

trivial-utf-8: Portability for UTF-8

unicode: things like character classes for Unicode

usocket: socket library

utilities: utilities library

uuid: UUID library

1: wraps commonly available, but not standardized behavior in lisp implementations: sockets, threads, debugger &c. often named "trivial-"


> does it have the tooling?

Yup. Opam (package manager) + Merlin (editor integration, type hints, error messages) + VSCode are a killer combo. And if you use ReasonML you also get refmt, which is the equivalent of gofmt.

> ecosystem?

Yup. The opam ecosystem is high-quality, growing, and has all the essentials. If you need something out of the ordinary you can call out to C libraries, or even compile to JavaScript and use (almost) the entire npm ecosystem with BuckleScript.

> is there even another stl than jane street's library?

That's odd. Usually people criticise OCaml for having more than one stdlib. But yes, there's a minimal but useful stdlib that ships with the OCaml compiler: https://caml.inria.fr/pub/docs/manual-ocaml/libref/index.htm... . And there's also the community-driven Batteries library: http://batteries.forge.ocamlcore.org/


I think last time I looked OPAM wasn't available for Windows. Has that changed, yet?



Also, you can use the Windows Subsystem for Linux to get opam: http://themargin.io/2017/02/02/OCaml_on_win/


How many stls do you want? I thought Jane Street's replaced the default one.


As much as I like Ocaml and would love to use it for everything, I tend to agree with you. The ecosystem is severely lacking, making it impractical as your general, everyday language.


Productivity comparisons are tricky. As an analogy: Being more than 10 years long Vim user, I am very productive with Vim. I have all my configs polished, I know all the tricks, etc. I can work on shell scripts, C, C++, D, Rust, Python, Go, anything... all in one editor, locally or through ssh, on any platform, etc. But if you take a person that has spent a month using Vim, and a person that has spent a month using some popular IDE, the IDE person is going to be more productive. Also, I'm sure long-term Java IDE user is going to be more productive than I am with Vim, when writing Java. Obviously.

Similarly with Go and Rust, as I'm following Rust development since like 0.3, I am very productive with Rust, while I find Go noisy, verbose and constantly dragging me down with its limitations. I don't have to be "architect astronaut" to need generics or decent macros.

On top of that: how do you measure productivity? Many people seem to measure it by "perceived productivity when writing new code". "I am writing this new service in Go, and I was able to do 500 lines today. I feel very productive!" Never mind that 30% of that lines are verbose error checks and other error-prone boiler-plate, reviewing it might not be pleasant, there are multiple errors that will have to be ironed out when production starts to exhibit them, everything needs refactoring because performance is not good enough under load, and that the next person might not have a such a wonderful time modifying the original code, as the first person writing it, and so on. The project might be in such a bad shape, then it will just get rewritten from scratch, so the next developer will feel "productive" again, ironically. I am NOT addressing Go and Rust particularly here - just overall. It is very hard to measure long-term productivity, while it is easy to lure yourself into believing the perceived short-term productivity matters a lot.

Having said all that, Go is easy to understand, so it is easy to find people that are able to use it (huge business reason to prefer it!), has a nice ecosystem, fast compilation, nice scalability with goroutines and many things that are going for it.

I find Rust's "quality", trump Go's "productivity", but that's like ... my personal opinion, man. :)


I think people who come to Go from not so productive languages might feel productive in Go. I mostly feel very unproductive with Go, like I'm wasting too much time dealing with code, when I should be thinking about the problem I'm solving. Although I almost completely stopped using Go at this point.


If I was to use Go, I would just use D instead. It's a much better language with similar strengths. Just didn't get as much "hype". Well, and had a couple of other issues but oh well...

Having said that, since Rust 1.0 was released, I'm not planning to use any other language unless paid for it. My favorite part of Rust is that it might not be the best tool for a particular job, but is reasonably close for anything I might throw at it: embedded, system tools, networking, web, whatever. Since I'm a generalist, I enjoy having a reliable multi-tool.


Article makes a false premise: that speed of writing the first version is important.

Much more time is spent maintaining software than writing the first version. Some poor sob is going to have to go and fix all those "silly" mistakes that were made and the bugs they caused (but of course, as we all know, they would have been avoided if the programmer had just been a better programmer). Save yourself (and us) the bother. Please use languages that stop you from shooting yourself in the foot.

(Not that rust will avoid bugs, but it seems to catch a lot of stupid "mistakes" before compile time. We're all humans and make mistakes, please accept that fact before inflicting software on us.)


>Article makes a false premise: that speed of writing the first version is important.

In my experience, project managers care more about how long it's going to take to build than about how maintainable it is. It's literally always the first question they ask:

"How long do you think this will take you?"

I don't believe I've ever heard anyone in management ask, "How maintainable will this be?" I'll ask around. I bet none of my peers have gotten that question either.


Except that normally a new feature does not involve creating a new system. Technical debt significantly impacts velocity of implementing new features in the future.


At least at my current company talking about maintenance is a huge thing given it's not happening right now.


> Both languages seem to be competing for the same user base and they both seem to be "systems programming" languages, so there must be a winner, right?

Are they competing for the same user base? As far as I can understand, Go is mostly being used in distributed software systems (like kubernetes) while Rust is being used for more "systems" software where performance is critical (like a web browser).


It seems like this could depend on what is already in your tool belt. If I want productivity, I use Python. If I want raw speed and low overhead, there's Rust. So Go ends up eclipsed on both sides.


There's another dimension to this: how big is the codebase you have to maintain? This is a "pets versus cattle" thing.

If you like artistically crafting small bits of code, Python may work fine. If you're building something to last and need to shovel large amounts of code around while migrating API's, a statically typed language with a fast compiler will do more to help.

Python in the large is not very maintainable. I expect that a Rust codebase will eventually be pretty nice to maintain, after the tooling matures more. Currently, Go is probably easier, and quicker to write.


> Python in the large is not very maintainable.

Could you elaborate on that?

I hear this a lot, but I work on a large Python project, and I don't think it is hard to maintain. We do have some strict requirements, though:

1. Test coverage; if it's testable there must be tests for it

2. Type hinting; for large projects it's actually really nice to know at a glance what the expected type is

3. PEP8 & Pylint; how we write code should be standardized and easy for others to read


Well, (2) seems important and uncommon for Python in my experience, but it's been a while. Maybe it's more common these days?

Here's the sort of scale I'm thinking of: consider a company with many teams, many apps, and many shared libraries. Some of the apps and libraries won't have anyone working on them, because it's generally not the case that a company is willing to fund maintenance forever on everything; people need to drop them for a while (to work on more important stuff) and someone else will come back to them later. (This is being "walk-away friendly".)

Suppose you need to fix a security bug in a shared library and update all the apps, most of which you haven't seen before. How easy is that to do?


side note: check out mypy for a powerful type system in Python; i'm a happy user in a largeish project for a year or so and it really works.


> Python in the large is not very maintainable.

Yes, very much it is. It just need good developers, not only juniors...


Hmmm. If you know Rust well already, sure. But both Go and Rust have a much better binary a distribution story than Python once you stray from the standard library...


Somehow this feels like apples vs oranges.


Agreed. It's unfortunate that Go and Rust are frequently compared to each other, they're not really trying to solve the same problems, they just happened to be modern, hyped, backend languages. I don't blame this post really, it's trying to correct that belief in a way. Rust is roughly a modern C replacement, while Go is a modern Java replacement. (very roughly)


it is; it's like comparing Python to C, except it's 2017 instead of 1997.


I've yet to see some Go code for typical CRUD web apps that doesn't look roughly as elegant as 10-15 year old PHP code, if you know what I mean. I'm not a real fan of ORMs and I'm surely not trying to badmouth PHP - but times have changed and Rails did bring some things that inspired tons of web frameworks in other languages to have cleaner, nicer code.

Open to suggestions for projects to take inspirations from so that my future Go code will not be "quickly written AND it works AND it looks horrible" :)


I've had the same experience. I'd like to learn Rust, at some point, and I read articles about it and tutorials now and then. But, realistically, I would need to dedicate myself to it for a long period of time to be able to build something from scratch in the language.

On the other hand, in a weekend of casual hacking, I was able to learn the language (sort of) and make a project from scratch in Go that actually did something useful. I'm sure the code is awful, and it'll take months of weekends of casual hacking to be able to recognize why, but Go is damned near comparable to Python or Ruby in terms of being able to go from zero to writing working code.

I'll still keep learning a little rust here and there when I have some free time. I'd really like to know a good, modern, systems language. I used to work on some C projects, but C++ was just too daunting, it's just to big of a language for casual use, so I never went down that path. Rust seems to be a good compromise.

It's not even a "Go is better than Rust" situation; the Rust team has made reasonable, occasionally brilliant, compromises on ease-of-use and ease-of-learning vs their other hard requirements. Go just has different requirements and they result in a language that is easier for new programmers.


I've been using Go in production for a little over a year now. I'm also attempting to learn Rust in my spare time.

This post just about sums up my feelings on Go vs Rust.


This'll be a fun comment section.

Maybe Go isn't so simply the answer, but the spread of "write everything in Rust" or "Rust is the salvation of software" is crazy. It's got huge advantages but it's really a very difficult language for what it does. 80% of software (nonsense percentage) that gets targeted to Rust would actually be better in another language. Rust's focus is on (for most devs and software) the wrong things.

It's too bad something like a better OCaml or Nim weren't what people were going nuts rewriting stuff in but they don't have the mindshare. Rust evangelism is like using a very advanced hammer to do everything. We've got screwdrivers, chisels, and multitools, yall, use them! Is Rust actually the right tool for the job? As programmers we do tend to seek the one true language which doesn't really exist.


> but the spread of "write everything in Rust" or "Rust is the salvation of software" is crazy.

Sorry to burn down your straw man, but the overwhelming majority of "Rust evangelism" points out that Rust is not always the right tool for the job. The intersection between people who write both Rust and Go (for instance) is substantial, and people in the Rust community (more precisely: communities) go to great lengths to point out that it's not an either / or proposition. Most of the RIIR! hyperbole is something that happens to the Rust community, not on its behalf.

> As programmers we do tend to seek the one true language which doesn't really exist.

This seems somewhat at odds with your denunciation, mere sentences ago.


If we're talking about strawmen, not sure how you differentiate the one true community from the false community.

stevekalabnik and pcwalton show up in every Rust discussion for a reason (no knock on them), the Rust evangelism strike force meme is real, for a reason, this post called "Rust is Software's Salvation" got 172 upvotes and 176 comments for a reason:

https://news.ycombinator.com/item?id=13280150

The marketing is real, nuance is good.


> If we're talking about strawmen, not sure how you differentiate the one true community from the false community.

I pointed out that there were multiple communities before you did.

> stevekalabnik and pcwalton show up in every Rust discussion for a reason

I agree completely; their calm, constructive engagement with the HN community has been a tremendous help to Rust's adoption.


> the Rust evangelism strike force meme is real

The meme is more real than the strike force itself. For every once I've seen it appear I've hundred times seen that tired meme appear.


One true language, one true paradigm, one true database, one true encoding, one true editor; the list goes on and on and on, that's where forum flame wars and hate mobs are born. The problem is lacking experience; you need to earn enough scars to knock you out of the loop, bump your head against enough walls to realize that the one true way will always fail. As usual; the people who make all the noise don't really know which way is up or down yet, that's what they are so busy trying to figure out.


What are some program that Rust is not always a reasonable choice to write in? Frankly, there may be some areas where another language is slightly easier to program in than Rust, but I see the value in trying to promote a lingua franca for programming. Different languages causes huge interoperability problems


One short answer is anything that needs dynamic linking. Rust has no stable ABI. But that can be fixed.

More fundamentally Rust is poorly suited to programs that don't have a hierarchical ownership model. UI programming is a good example. UI elements tend to have lots of cross-references to each other: think event handlers, etc.

Of course Rust can support non-hierarchical ownership, but only by applying constraints that don't make sense in UI programming. Imagine if JavaScript's `getElementById()` threw exceptions if the referenced element was already on the stack. That would be silly! In this context, Rust's borrow checking is not a seatbelt but a footgun.


> One short answer is anything that needs dynamic linking. Rust has no stable ABI.

In theory this is problematic, but I'm not sure how often it comes up in practice: a lot of systems-y use cases for dynamic linking are writing low-level libraries that many other languages can use, which currently means exposing a C interface. This is supported and stable in Rust.

Of course, this doesn't cover every thing, e.g. pure Rust plugins for pure Rust programs. Although one still can dynamically link, as long as all pieces are compiled with the same version (annoying, but, depending on circumstances, not a complete roadblock due to tooling like rustup).

> Imagine if JavaScript's `getElementById()` threw exceptions if the referenced element was already on the stack

I'm sure you realise it, but Rust does offer a wide variety of functionality for working with shared data. It is definitely syntactically more verbose than in languages that don't try to tame mutation, but it's essentially equivalent functionality (at least, to languages that use reference counting).


> a lot of systems-y use cases for dynamic linking are writing low-level libraries that many other languages can use, which currently means exposing a C interface. This is supported and stable in Rust

UIKit is an example of a high-level dynamically linked library. Rust isn't ready for that category of use case - but to be fair neither is C++ :)

> Rust does offer a wide variety of functionality for working with shared data. It is definitely syntactically more verbose than in languages that don't try to tame mutation, but it's essentially equivalent functionality

My point regarding shared data is not about Rust's verbose syntax, but about its unwanted runtime checks which no other languages perform.

Here's what I have in mind (doing my best pseudo-Rust):

    struct CounterWidget {
      count: u32,
      limit: u32,
      didClick: fn(),
    };
    impl CounterWidget {
      fn clicked(&mut self) {
        if self.count < self.limit {
          self.count+=1;
          didClick();
        }
      }
      fn setLimit(&mut self, limit:u32) {
        self.limit = limit;
      }
    }

The Counter widget has a count and a limit, and a callback for when it's clicked. It also has a landmine: if the click callback attempts to call setLimit on the same Counter, it will crash at runtime.

This crash is hard to test for and doesn't add any value: why shouldn't the callback be able to adjust its limit?


It took me a bit to figure out what you could be talking about. Rust does not insert runtime checks like this of anything by default except for boundschecking on indexing operation.

You must mean that you stored your `CounterWidget` in a RefCell, which does have the semantics that if you mutate it while holding a mutable reference to it, it will crash. But your code sample didn't include a RefCell at all, so this is very unclear.

Yes, its true - Rust provides a hard guarantee against simultaneous mutable access to the same data. This is invaluable even in a non-concurrent context, both because of memory issues like iterator invalidation & higher level logic errors that result from silent mutation at a distance.

I can assume looking at your code that didClick() doesn't mutate this CounterWidget - or even access it. This means I know that if I rearrange the counter increment with the didClick callback, I know nothing is semantically different. I can introduce additional code to the function, knowing that the state is the same after didClick as before it. All of this information is very useful to me when I'm trying to maintain this codebase (not to mention useful to the optimizer).

If you want to be able to provide mutable access to the callback, just make it an `fn(&mut CounterWidget)`.


> UIKit is an example of a high-level dynamically linked library. Rust isn't ready for that category of use case - but to be fair neither is C++ :)

That's fair.

> My point regarding shared data is not about Rust's verbose syntax, but about its unwanted runtime checks which no other languages perform.

FWIW, I think Swift is the only language with implicit checks of this form (for global variables and class properties). Rust only performs such checks if the programmer opts into it by using types like RefCell or Mutex.

> It also has a landmine: if the click callback attempts to call setLimit on the same Counter, it will crash at runtime.

Specifically, the callback will be statically unable to call setLimit unless the programmer decides to use one of those tools, in which case the location of the crash is clear.

> This crash is hard to test for and doesn't add any value: why shouldn't the callback be able to adjust its limit?

That specific case seems like it's okay, but there's a pile of problems in code that is only slightly different. For instance,

- if `clicked` held a reference to an element of a vector stored inside CounterWidget across the callback call, allowing mutation would allow that reference to be invalidated (this is less contrived than it sounds: e.g. iterating through a vector calling the callback for each element has this problem). This is undefined behaviour.

- if the callback enables results in the data being manipulated on multiple threads, you get a data race. (Also undefined behaviour.)

- stepping away from undefined behaviour, there may be things inside the `if` statement after the callback that are relying on the invariant the condition established (e.g. `let remaining = self.limit - self.count` and assuming it will be > 0), the callback can invalidate this in surprising ways, both for the programmer, who didn't expect the circular chain, and for the compiler's, which is thus forced to be defensive/pessimistic, meaning slower code (this is one major reason why Swift adopted exclusivity).


I would argue almost anything. Nim writes like Python. The average programmer never worries about lifetimes because there's a GC, which the vast majority of programmers (especially application programmers) have gotten used to over the last 40 years.

Rust is a big sidestep in usability, which makes sense if you want to replace C and C++, but not much sense elsewhere. Humans are really, really good at juggling multile languages, it's why we make a new one whenever we can.


If I can actually use a GC for my problem there is zero reason for me to switch away from Java/Kotlin/JVM language: Great tooling, great ecosystem, very mature.

So, the reason to use one of these languages is to get away from the "you can use a GC"-space and then the count of interesting languages gets very small very fast.

But sure, if your problem is in the "GC can be used" space, but you like to use new languages .. go for it. It's certainly fun to use a new language to tackle a problem. Just not the most efficient use of someones time in my experience. (But: Fun!)


If I can actually use a GC for my problem there is zero reason for me to switch away from Java/Kotlin/JVM language: Great tooling, great ecosystem, very mature.

Unless you have a language with immutable data structures, ownership is still a problem with a GC.

E.g. Consider the case where you have some class with some member variable. You want to provide a getter to obtain the member. Now you have an ownership problem: you could return a reference, but now the caller could mutate the data structure in such a way that it breaks invariants of the wrapping class. So, instead you return a copy, but this can be prohibitively expensive.


So you're saying that for almost everything Rust is not a reasonable choice. You then state that a reason for this is because people don't have to worry about lifetimes because it has a GC.

There are applications where a garbage collector is simply unnecessary and possibly extremely detrimental.

And if you get down to it you'll find an amazing truth: once you learn how writing programs is about as easy without a garbage collector than it is with one and your programs run a lot faster.

Using an automatic transmission is a lot easier but manual is not hard and you save a lot of gas.


But why make Rust The One and not Common Lisp, C++, Java, Go, Haskell, etc?

Back in the 90s, people were thinking Java would be The One. Didn't happen. Good luck with convincing everyone that it should be Rust and not their preferred language.


I think there are many good reasons to use rust. But trying to promote it so everyone uses it everywhere to replace everything is overkill and can kill any chance of widespread adoption.

If you only need an spa use react or bue. If you only need a website use php or ruby. If you only need a webservice use node or go. If you only need an operating system use rust or c.

Using rust for client side validation is probably not going to work.


I'm not arguing that Rust should be used for everything but that Rust is a reasonable choice of language for pretty much everything. It may not be _preferred_, but just like C or C++ can be used pretty much anywhere to great effect.


Why not solve the interoperability problem instead, then who's gives a flying, about the choice of language :)


We did, remember Corba? I mean XML-RPC, er SOAP... wait no, REST+XML... REST+JSON, er, Swagger (I should really call it Open-API).

Omg, what are gRPC, avro, thrift, and cap'n proto meant to do?

I bet if we could all just agree to pick one of those then the interoperability problem will be solved. I know you were referring to C ABI etc, but as others have pointed out, having two GC languages communicating with each other over a C ABI is tough, which is why IPC/RPC exist.

Oh, and once we settle this single ABI/Interoperability problem, let's come back to this one-true-language idea... I think there's something there ;)


The interoperability is entirely connected to the choices a programming language makes in order to execute a program. A programming language that has a GC will immediately have somewhat of a challenge in calling native C code. And then there's the identifier problem. Some languages allow different characters than others in identifiers. There are so many issues that interoperability is literally impossible to solve generally or by any single individual.


Something must be used against "Everything is done in C/C++/JS. Why change that, ever?".


I code in Go for 2-3 years and tried to learn Rust for fun, but it was harder for me. While Go is very simple and it has almost no barrier of entry, it lacks much as well, Rust definetely looks more interesting and it would be another enlightning experience.


> Predictable runtime behavior (zero cost abstractions and no garbage collector).

I see a lot of people considering Rust/Go because they are looking for something much more modern than C++ and at the same time not running on JVM due to the above


I concur. I would really love to love Rust because it's a cool language that values efficiency and safety, but in the end of the day, I keep writing Go programs on all scales because it's just so productive.


I always look at programming languages from the same position i use to look at guns. What kind would i want OTHERS to use around me?

From that POV Go wins hands down in my opinion. Harder to get wrong. Easier to get right.


How is Go "harder to get wrong?" It's very easy to accidentally introduce a null pointer dereference, data race, type assertion panic, or drop an error. It's much harder to get these sort of bugs in Rust.


actually it's the other way around; once your rust code compiles, it's going to be much safer to use than go. the difference is more in that the parts you have to assemble the gun from are much smaller in rust.


I think this is a good answer. If you're really not in the mood to scratch your head over confusing reasons for why your program won't compile while learning the language, Rust is not what you want. While I have used Rust, I have not used Go. Anecdotally, the consensus seems to be that it's relatively easy to pick up, and get something done. And really, if you're just doing a personal project, part of the point is to feel the Joy of Programming (TM) and being able to make or learn something.


Took a look at both Rust and Go to hack on, but up until today I haven't found a usecase where I _need_ C-like performance (and choose to use Rust).

Even though Google/Fuchsia is using Go for it's networking[1], I wouldn't really consider Go to be a system language.

[1] https://groups.google.com/forum/#!topic/golang-dev/2xuYHcP0F...


If you need what Rust offers, use Rust. If you don't need those things there are hundreds of languages that you could use(including Rust if you really want)


I use F# and Rust for personal projects. At work I deal with a programming language akin to Go on the simplicity side, and it is just not fun.

But I am probably not typical. I'd no problems learning a language I'm interested in (but Haskell. Monad pattern recognizer somehow can't take a hold in my head for long).


I prefer Go's lacking to Rust's syntax and long compile times. But then again I do not write things like Servo. I also like Nim and Crystal and while Crystal's compile times are not ideal I can forgive this as i like the syntax


my take at a summary: use go if you want to do something, use rust if you want to learn a lot of important and interesting stuff that's been hidden from you before doing something.


Based on this article, I guess not a lot of developers need to program in Rust nowadays.


> You'll need to unlearn bad habits and learn new concepts.

Ok, yeah, that's totz the way forward. Repost this if you are strong independent developer who doesn't need no good engineering practices.


"Safety against Null pointers, race conditions and all sorts of low-level threats. Predictable runtime behavior (zero cost abstractions and no garbage collector).

...yadayadayada...

If you don't require any of these features, Rust might be a poor choice for your next project. That's because these guarantees come with a cost: ramp-up time. You'll need to unlearn bad habits and learn new concepts. Chances are, you will fight with the borrow checker a lot when you start out."

If you don't require...seriously is there any case ever in the world of programming when you don't require those?

I can't even believe this article exists. Why would anyone ever use Go for anything? It's the worst programming language ever invented. Yeah Im sure it makes things fast just like jumping down from rooftop makes you go fast but there is small side effect of dying.


yeah... no...




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: