I like Rust a lot and I hope to get to use it more, but "added type safety at the expense of iteration velocity" is not a good tradeoff for my domain and I suspect many others (although its iteration velocity is improving monotonically!).
I like Rust a lot and I hope to get to use it more, but "added type safety at the expense of iteration velocity" is not a good tradeoff for my domain and I suspect many others (although its iteration velocity is improving monotonically!).
Not that Java is even good, but that beats go. The history of Go is the history of Java, repeated as farce. It's even some of the same academic lineage come to bail things out with the type system for generics!
Go is a dramatically nicer programming experience than Java. There are some benefits in Java however: sometimes JIT is nice and Go has no analog to Spring. But these are very circumstantial benefits and not good tradeoffs in the general case.
>No need to learn groovy to configure Gradle to build your application
I rarely have to configure msbuild, mostly to do some relatively advanced stuff like auto-installing npm dependencies for an SPA.
>No need to learn javadoc
Just use
/** */
>No need to figure out how to statically link your codeYou can build pseudo-statically linked executables by adding one line to .csproj (which builds a single executable file, but it's really a self-extracting archive), and real static linking is in the works. I have no need for it personally though.
>how to compile your code ahead of time
Same thing — AOT compilation is one configuration line away. You don't need it very much though, as the CLR is very performant these days and beats Go in most benchmarks:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
>No need to figure out how to tune your GC for low latency and low memory usage
I would argue CLR's GC is ahead of Go's GC at least for latency. Memory usage, not so much, but damn, look at the execution times above. It depends on your priorities I guess.
>Plus Go has value types
C# has had them since before Go was a thing. Unlike Java, it also has real structs, which you can configure the alignment of, and map a raw chunk of memory to them (which you received from a COM port, for example). This came in handy more often than I care to remember.
As for your forest/banana analogy, I'd argue it's never been as bad in .NET world as it's been in Java world. I have personally never found anything similar to the insane class hierarchies they have in Spring.
Try to do something with stuff like XAML Workflows, Bizztalk, WCF, SharePoint, or MVVM. :)
Btw, did you know the default Gradle configuration for compiling a Java app is literally 1 line?
apply plugin: 'java'
I'm not that much a fan of Gradle (too much magic), but it's one of the least verbose and easiest to figure out parts of working with java.Wrt gradle: While it’s super easy to get started, any slight modification is a major pain.
Note to other tooling guys for other languages:
- I don’t want to write in a new language just for my build system
- I don’t want freaking xml hell like maven
And don’t get me even started with Maven as a package manager. But to be honest... it’s at least better than NPM :-)
In general the concept of a "cross platform" build tool and "not having to learn another language" are at odds with each other, for anybody who isn't lucky enough to already work in the language the build tool is written in.
Those are the stapled languages in the backend space which Go competes in. You could give some of them a try.
I can easily see it being tedious if you have to type every character.
Code navigation is extremely basic (can only find references in the same package!), often breaks, and can't handle stuff like finding all interfaces that a type implements, or finding all implementations of an interface.
Then, I tried VSCode with the Go plugin, both the default version and the go pls based one; and Emacs with the LSP package and go pls.
Really good IDE support would include refactoring (more than renaming a local variable/struct field, e.g. Extract Function, extract parameter), advanced navigation/analysis (analyze data flow to/from variable, find call stack etc).
Go is somewhat decent in the tooling area, and you can get your job done with it, but it really doesn't have anything I would call good support in any area of tooling except the compiler (not code analysis, not debugging, not monitoring, not profiling, not package management).
I suppose it depends on what you're used to. I've never found myself wanting to do these things, but I'm also strictly from a Python and C++ background so my standards are admittedly lower than Java and C# people. Hopefully gopls solves for these problems.
Rust: For code that isn't meant to be iterated upon, that must be safe/correct while also being performant.
Go: For code that is meant to be iterated upon frequently, that must be performant and easy to maintain.
I would like my tools to be written in Rust, and I would like to interface with them in Go.
But the same shoddy system is also constantly changing the requirements, precisely because nothing is built for posterity and there's tons of make-work churn. Good type systems make code far easier to refactor, and refactoring (as opposed to slapped-on new code) is the only way to handle shifting requirements without being crushed under ones own weight.
I'm not confident that average level developers are able to ship features in Rust as quickly as they would in Go, which is the root of my point. Those building tools, which generally do not have the same success metrics with respect to speed and correctness, should use the language with a focus on safety and correctness. Those whose positions do not lend themselves to safety and correctness should not use that tool.
Even if this was a genuine concern, they should still use Rust. Because it will be far easier to refactor the code that they ship into something that is safe and correct, compared to rewriting a Go codebase.
I don't write much Go code, but my company does. I have seen so many incidents and bugs whose root cause was: someone changed a library, that broke the semantics that users were relying on, but everything still compiled fine, so nobody noticed the subtly wrong behavior for a long time. An incredible amount of money has been lost like this.
Go simply does not give you the tools to prevent these issues in the type system, you have to rely on really thorough unit tests (which inevitably don't get written in the spirit of "moving fast".)
Whenever I hear about Rust in companies same dozen or so companies get mentioned every time.
But in general, companies adopt Go for the same reason they adopt MongoDB [0]: it's really easy to get started with, and get something that "works." The pain comes months or years down the road, and by then you're stuck with it.
[0] A company I previously worked for starting using MongoDB as a small startup, starting finding the limitations about 6 months later, but ending up spending an incredible amount of engineering time over 5 years getting rid of it.
We get it. You don't like Go. Don't use it. That's a perfectly fine option. Plenty of very successful companies, open source projects and services all work with Go (and literally every language) without issue. You not liking something does not make it bad.
As another example, Go makes it impossible to create a Maybe/Option type which leads to a bunch of issues around returning failing or empty values from functions. In one particularly costly example, there was a function in a library that was getting some price information from a file. Originally this returned nil when the price information could not be loaded, but a refactoring caused it instead to return 0 which the client happily used. This was not caught for _weeks_.
You can write unsafe code in Rust. Does that mean that Rust is bad too?
Hard to feel sympathetic, as this practice violates the Go convention of adding an additional return value to the function to indicate failure, either of type error or bool, as appropriate.
>Go makes it impossible to create a Maybe/Option type
It's very much possible: https://play.golang.org/p/MCxGcZ-rJRU.
Of course, it's not generic, but I have a feeling that might change soon :)
Go constantly requires boiler-plate checks for errors, null values etc. without the type checker helping ensure you've checked for an error or null value.
As for the second example I don't think it's a language issue but more a programmer one, how Rust would have saved you in that case, anyone could have returned 0 for the price instead of a proper type. Using Rust doesn't magically turn programmer into good ones. You still have to know how to properly design your code and best use the language and its features.
I'm often reading code in various language and I'm baffled at what a giant lib.rs looks like from someone that never really used Rust.
They wanted to do: something(getPrice()), but if getPrice can actually fail the then either something needs to accept an error, or they need to handle the error.
No type system imagined can save you from someone who's decided returning 0 is the correct way indicate an error in this scenario.
You've missed the problem that was posed. It wasn't returning 0 to indicate an error, it was changing the error value from nil to 0. In rust that would've been a type change (from Option<int> to int). Because the context here was about how stronger type systems (like rust's) allow you to be more specific about your types, and thus many code changes that would not involve the type changing in other more weakly-type languages do cause a type change in rust.
return 0, errors.New("unable to get price")
It's less elegant than Options but still, very common practice. GP's company clearly hasn't bought into Go if they're using a library that doesn't follow well-known conventions.Go has its problems, and it isn't a perfect language, but I have never felt unproductive using it. In fact, my company uses it for all backend services. It has a great stdlib and first class tooling. Most of the discussion in this thread seems to be coming from people who barely use it or have only dabbled with go.
As a tangent, it's really tiring to see HN engage ad nauseum in these pointless language debates. Every language has its place; use it when it's appropriate.
The package ecosystem was so stable that go didn’t ship with a package manager (not saying it’s good but definitely a sign of relative stability).
Besides nil pointers (typesystem could do better here) and bad logic (can’t do better but language simplicity reduces this), what you’re saying is definitely not the experience of the majority. People constantly talk about being able to go to a golang program from 8 years ago and run it with no problems. Rust changes every few weeks.
You stated that "Rust is merging random syntaxes and random packages get upgraded to std lib all the time" as though it were incompatible with "being able to go to a program from 8 years ago and run it with no problems". But there's no incompatibility here. Rust adds new features at a faster rate than Go does, but it also maintains backwards compatibility ("stability without stagnation").
Sure the mainline stays clean but thats not what matters in practice.
Which also explains why you can git clone a Go library/tool and have it not building because some dependencies introduced some breaking changes in the master branch. That happened the last 3 times I wanted to fix something in a Go project.
I really don't know where this is coming from. The only package that was included into std like this is replacing the hashmap with hashbrown, and this didn't even change the public api of the standard library at all, besides improving performance of the hashmap.
In all likelihood, that "incredible amount" is a small fraction of the money your company saved in iteration velocity by not using Rust in the first place. This might not be true depending on your domain--if you're writing space shuttle software, bugs can be really expensive. If you're writing ordinary web app backend code, you're probably much better off with Go than Rust.
2. There's lots of software that "ships" as a web service, often used by people who are not paying for the web service.
If you're talking about defects for an actual product that render it unsafe or unsuitable for the intended purpose, then I can see your point (though even there I'm not sure that I completely agree). But there's much more software than that.