4 ms·
I really like Rust, but in my mind it's still relegated to the periphery of tasks that must be super fast (like C/C++, to your point) and/or low-level. Rust has
by throwaway894345 5y ago
I really like Rust, but in my mind it's still relegated to the periphery of tasks that must be super fast (like C/C++, to your point) and/or low-level. Rust has made impressive strides at reducing the toil involved in compile-time memory management, but there is still a big productivity gap between the borrow checker and GC.
Frankly, people are making boatloads of money off of software written in Python and JS--languages which are both far less safe than Go and far slower and yet Go is on par with those languages with respect to productivity (I argue it's more productive due to its static typing features, but others argue it's less productive presumably because of the learning curve). Most software doesn't need to be so fast or correct.
Also, I work in distributed systems and SaaS (software as a service). In this world, most errors are silly type errors ("undefined is not a function", forgetting to `await` some async function, etc) that would be caught with a flat-footed type system like Go's. Beyond that, the next largest bucket are issues that even a sophisticated type system like Rust's wouldn't help with, such as infrastructure issues (missing/misconfiguration of some cloud permission, networking rule, etc), misconfiguration of the service, race condition with many processes accessing the same networked resource, deployment error, etc. This means that Rust's stated advantages aren't really as nice as they initially sound.
As a programmer, I can appreciate a super fast language with a strict type system; however, as an engineer or a technologist, Rust is rarely a good fit for me. Go seems to be a lot closer to the sweet spot, which makes sense because it was developed expressly with distributed systems in mind.
- josephg 5y ago> In this world, most errors are silly type errors I can’t speak to python, but typescript has basically fixed this problem overnight in the javascript ecosystem. The typescript compiler finds almost all small bugs like this while I’m coding. And as an added bonus, type hints allow the IDE to be much more helpful - adding to jump to function support, autocomplete, method parameter suggestions (or documentation on hover). And typescript is easier to read than javascript because you don’t have to guess what data type some variable is. I love javascript’s quick and dirty nature, but I still use typescript instead of javascript now for any code I write that I expect to survive the week. (And as a bonus: you still get IDE type hints when calling typescript functions from raw javascript!) Typescript’s type system is also more powerful than Go’s. It supports enums, genetics and type unions (eg x: string | number). Go sits in the awkward place of having a worse type system and no significant advantages over typescript for me. It’s awkward to use go on the web. Go is faster than javascript on the server but that usually doesn’t matter. And when it does I can reach for C or Rust. Both of which work really well with native code, or with JS through wasm. Rust is much harder to learn than Go - but personally I’ve climbed that hill already. Once you’re over that hill, Rust is much more expressive. On purpose both ways - go isn’t trying to be expressive, and rust is. I love rust’s parametric enums and output types in traits. Which I now sorely miss in other languages. I can imagine Go shining a lot more brightly when working with a team which has mixed skill levels. Most of my work lately has been solo, so I don’t need gofmt to enforce a consistent code style, or anything like that. I do miss Go’s green threads. Rust’s afterthought scattergun approach with threads and futures feels like a mess. But I can’t see myself ever really using Go. It’s weak in areas I want it to be strong (eg the type system). And strong in areas I just don’t care much about. (Eg consistency).
- zzt123 5y agoYour point about Go shining a lot more brightly when working with a team which has mixed skill levels was one of the design goals of Go, so it seems they’ve succeeded on that front if you’ve come to that conclusion independently!
- silisili 5y agoIMO, Go is the easiest language to read by far. Python can be, but lets one use a lot of hard to figure out magic. Go is very much WYSIWYG, and to me that's its greatest strength. It's easy for anyone to jump in about anywhere. And that lends itself well to teamwork.
- josephg 5y agoI find that's only true so long as the problem you're solving fits well into Go's view of the world. If you want to make a data structure holding the equivalent of a parametric enum (or tagged union from C), go is very awkward to use compared with richer languages like Swift or Rust. Go is also awkward if you want to implement custom generic data structures. Eg, this[1] code I wrote a couple years ago for doing text based operational transform became about 1.5x longer in Go compared to rust or typescript because its so awkward to express a parametric enum in go. And it was much harder to read & more buggy as a result. Sadly I lost the go version of the code. I'd be curious if someone with more go experience could do a better job, but I'm skeptical. Hopefully the situation improves somewhat when generics land. [1] https://github.com/josephg/textot.rs/blob/03c84b7c35a375ba7dbb9c3db38923aaced4cccc/src/lib.rs https://github.com/josephg/textot.rs/blob/03c84b7c35a375ba7d...
- throwaway894345 5y agoI agree that enums are the thing that Go is lacking. I would really like first-class enums perhaps even more than generics. Hopefully we get them.
- tptacek 5y ago
- tialaramex 5y ago> but there is still a big productivity gap between the borrow checker and GC. The borrow checker and GC aren't really doing the same thing though. One very important distinction in some fields (but unimportant in others) is that GC only really cares about memory resources. So you are (or should be) doing explicit manual cleanup for all non-memory resources in a GC language. Rust isn't, in Rust we don't write explicit resource cleanup for a programmable interrupt controller, or a file, or a database connection -- the resource knows how to manage itself, and Rust promises to tell it immediately when it falls out of use, whereas a GC can't promise to ever clean up which is why Go doesn't even bother providing a means to do this automatically for your non-memory resources when they're garbage collected (Java does, but again, no promises it ever fires, so, don't rely on this).
- throwaway34241 5y ago> Go doesn't even bother providing a means to do this automatically for your non-memory resources when they're garbage collected (Java does, but again, no promises it ever fires, so, don't rely on this). It sounds like you are talking about finalizers? If so, they exist in Go in a similar way to the Java feature [1]. [1] https://pkg.go.dev/runtime#SetFinalizer https://pkg.go.dev/runtime#SetFinalizer
- sagichmal 5y agoFinalizers are not guaranteed to run. They're not ersatz destructors.
- throwaway34241 5y agoYes, if you look at the quote I was responding to, it appears they are saying Go doesn't have finalizers, which is incorrect.
- beltsazar 5y agoYou usually want to release non-memory resources deterministically, but finalizers in C#/Java/Go are not deterministic. That's why finalizers usually are not used for resource management. Instead, C# has using statements, Java try-with-resources, Go defer statements.
- Blikkentrekker 5y ago> I really like Rust, but in my mind it's still relegated to the periphery of tasks that must be super fast (like C/C++, to your point) and/or low-level. Rust has made impressive strides at reducing the toil involved in compile-time memory management, but there is still a big productivity gap between the borrow checker and GC. Even if it weren't for the performance I would use Rust over Go due to the lack of generics alone, as well as the associated general philosophy of Go that boilerplate is good and one should repeat oneself as much as possible.
- throwaway894345 5y agoI really, really like type systems, but I’ve built enough software to know that the returns for most applications diminish after a Go-like type system is in place, and there are many other factors that are more important than type systems (and Rust gets a lot of these right too!) such as performance, productivity, tooling breadth and quality (especially build tooling and package management), ecosystem, deployment/distribution story, learning curve, readability, etc. Ultimately I’m of the opinion that as cool as type systems are, for most software they need to exist in service of productivity which means you need a basic type system that helps you but gets out of your way. Type systems can’t catch many classes of bugs that are increasingly prevalent in a world where our services are getting increasingly smaller (or rather, where more infrastructure and networking are being put in between the logical components of our application) and we’re often able to detect bug fixes before they impact a significant number of users (progressive deployments, automated rollbacks, continuous deployment, etc) but the discourse around type systems hasn’t caught up yet.
- Blikkentrekker 5y agoIt has nothing to do with catching bugs. It has to do with that one sometimes has to write 80 lines of code in Go to to the same as 3 lines of Rust code due to having to repeat oneself all the time.
- throwaway894345 5y agoThat’s an even more superficial concern. No one is bottlenecked on the rate at which they can type.
- Zababa 5y agoI have the opposite view on the type systems: Rust's type system is really great for business logic because it's really expressive (based on algebraic data types), but the language being made for low level stuff makes some things a pain. If you do something like DDD, ADTs really shine, especially when combined with pattern matching. I do agree that when you can afford a GC, Rust can be annoying.