4 ms·
After using Go for ~5 years, so many little things in Rust blew me away. I thought I was okay with Go's "enums" but then I saw Rust's Enums. Most notably, the r
by asdkhadsj 6y ago
After using Go for ~5 years, so many little things in Rust blew me away. I thought I was okay with Go's "enums" but then I saw Rust's Enums. Most notably, the real enum type combined with pattern matching was an eye opener over what I've been missing.
Iterators were another one. The ability to express data transformation (mapps/filters/etc) in a very concise way blew me away. I had no idea what I had gotten used to in Go, though that's definitely not to say that I didn't feel the pain.
There's advanced features in Rust I could live without, but most of it just feels empowering. The beauty in it though, in my mind, is that you don't need to use all that advanced stuff. You can write Rust shockingly similar to Go.
The only thing Go truly nailed in my eyes is green threads. Those will always be better in Go than Rust (though futures are getting way better). Go nailed green threads.
But all the other "lack of features as a feature" left me frequently wanting for more tools to solve simple problems. And I was a Go nut. I have a Gopher plushie in my car for Petes sake.
- shpongled 6y agoThe crazy thing is that sum types (Rust enums) and pattern matching have been around for at least 30 years. I'm simply not interested in learning any new language that doesn't have sum types, they allow you to write incredibly expressive and terse code.
- estebank 6y agoFor all the complaints about the breakneck change in rust, it's a very "boring" language: all of its features with the single exception of the borrow checker already exist in other languages.
- anticonformist 6y agoIt's not any particular feature that makes a language a mess. It's the interaction between the features. It's a bit like mixing paint, it's very easy to end up with greyish poop. Go was designed by very experienced programmers that understood the cost of abstraction and complexity well. They didn't do an absolutely perfect job. It's probably true that Go would be a better language with a simplified generics implementation, enums, and maybe a bit more. That they erred on the side of simplicity shows how they were thinking. It's an excellent example of less is more. Most programmers never gain the wisdom and/or confidence to keep things boringly simple. Everyone likes to use cool flashy things because it makes what can be a boring job more interesting. But if your goal is productivity, and the fun comes from what you accomplish, then the code can be relatively mundane and still be very fun to write.
- estebank 6y agoGiven that I am involved in the Rust project I'm very likely biased, but given that I've focused on the learnability of the language (diagnostics and ergonomics) I have a bit of context on this subject. When designing a language there are intrinsic (what things the project wants to focus on, be they features of the language or the associated tooling that affect the language, like generics or compilation speed) and extrinsic (external impositions like being able to run on certain platforms, or interfacing with existing technologies like being able to run a statically linked binary in Linux or being able to debug using gdb or calling C libs without runtime translation) design constraints. All languages have (or should have) an objective of being easy to learn, pick up and use long term. It might just not be the top priority. For the sake of argument you can take Python where expressiveness at runtime and clean syntax are prioritized over speed, Go where fast compilation and multithreaded microservices are prioritized over more complex language features, and Rust where fast binaries and expressiveness are prioritized over ergonomics (when push comes to shove this is the case, otherwise you wouldn't need to call `.clone()` or add `&` to arguments when calling a method ever), you can see how these objectives permeate every decision throughout the language. When it comes to Rust in particular, I feel it is still a boring language despite the appearance of too many features, precisely because of how they interact between them and fit together naturally. It is not the best fit for every use case, but it is one of the projects out there that is embracing the fact that it can't be as easy to learn as it could be (without sacrificing some of the constraints that make it interesting as a systems language), but we can rely on the compiler being a necessary part of the developer toolchain to make the compiler understand the user's intent when they do things that make sense from extrapolated misunderstanding of the language and help them write the "correct" code instead. This has the added benefit that reading the code is easier because you have to "guess" much less what it is doing. Remember that if the code can confuse a parser it will also confuse humans. On the opposite end of the spectrum you have JavaScript, where it's grammar has a lot of optional or redundant ways of doing the same thing (think semicolon insertion), which makes the act of reading and debugging code harder. This is a reasonable approach in a case like the web, less so in a compiled language that can evolve independently from the end users' platform.
- stouset 6y ago> It's the interaction between the features. Precisely, and this is one area where go fails completely. The features don't interact well at all! Tuple returns are everywhere, but there are no tools to operate on them without manually splitting the halves, checking conditionally if one of them exists, and returning something different based on each possibility. Cue the noise of subtly-different variants of `if res, err := nil; err != nil` in every function. Imports were just paths to repositories. Everything was assumed to just pull from the tip of the branch, and this was considered to be just fine because nobody should ever break backwards compatibility. They've spent years trying to dig themselves out from under this one. Everything should have a default zero value. Including pointers. So now we go back to having to do manual `nil` checking for anything that might receive a nil. But thanks to the magic of interfaces, if you call a function that returns a nil interface pointer, it will directly fail a nil comparison check! This is completely bonkers. Go has implicit implementation of interfaces which makes exhaustive checking of case statements impossible. So you type-switch and hope nobody adds a new interface implementation. So you helpfully get strong typing everywhere except for the places you're most likely to actually mess something up. Go genuinely feels like a language where multiple people each had their pet idea of some feature to add, but nobody ever came together to work on how to actually make those features work in concert with one-another. That anyone could feel the opposite is absolutely incomprehensible to me.
- jandrese 6y agoI know this won't be popular to say on HN, but I think Rust has the same problem Perl does. The language has so many systems to learn and a tough syntax that it looks unreadable to people just starting out.
- shpongled 6y agoI mean I could see learning Rust being really hard if you only know something like Python or JS. The only "system", as you say, that is present in Rust that doesn't have something analogous in C++ is the borrow checker, and lifetimes still exist in C and C++. Rust is significantly simpler and easier to learn than C++
- jandrese 6y agoC++ has a much shorter time to first non-"hello world" program than Rust. C++ has a lot of features, but few of them are mandatory for general development. With Rust you have a pretty steep hill to climb before your first non-trivial program compiles.
- shpongled 6y agoI strongly disagree.
- nemothekid 6y agoC++ and Rust, IMO have a very similar featureset, Rust just puts that upfront as properly part of the language. Those C++ features are pretty much mandatory for general development, and likewise you will find them in most open source and production projects. Programming without them is just C++'s one of many ways that it gives you enough rope to hang yourself. Yes, you could program C++ without even knowing what std::unique_ptr (and I talk to many college grads with C++ on their resume who don't know what unique_ptr is, or that C++ has more than one type of pointer). But Rust won't let you use raw pointers (as part of the language), whereas in C++ you will be told "make sure you have read Google's 10,000 word style guide before committing any code".
- 6y ago
- alquemist 6y agoAlgebraic datatypes started with Hope, in the late '70s at Edinburgh. Rod Burstal, David MacQueen and Don Sannella. https://smlfamily.github.io/history/SML-history.pdf https://smlfamily.github.io/history/SML-history.pdf https://dl.acm.org/doi/10.1145/800087.802799 https://dl.acm.org/doi/10.1145/800087.802799
- xyzzy123 6y agoI came to go from C++ and was so glad about how few sharp objects were lying around, working in software with just one allocator, just one string type. I’m possibly damaged by previous experiences but ultimately I’m also glad not to have to pretend I’m clever. I just go brrr and solve the problem with for loops and go home to my loved ones at 5:30 exactly. Like proper enums might be nice I guess, but really what I love are all the other things which are not there. Lack of enums has not hurt me deeply. What hurt me was languages where someone might conceivably express the COM apartment model and also think it was a good idea.
- stouset 6y agoDo you somehow labor under the impression that Rust programmers stay up at nights and on weekends to learn to use "clever" tools like iterators, enums, and sum types? These aren't clever tools. They're dumb tools like chisels and hammers. Yeah, you can just use a screwdriver to chip things away or to whack something in, but there are better tools that are purpose-built and let you do the job faster, more precisely, and with less effort.
- anticonformist 6y ago"You can write Rust shockingly similar to Go." This applies in any case where one language is more complex than another. You can write almost any style of any language in C++, for example. The problem is that every team ends up writing in their own subset of these languages, which means it's impossible to ever really achieve expertise. Each team's definition of the language is different, and no one has worked on every team. Ergo no one in the world is actually a C++ expert at any given company's "version" of C++, even if you know every C++ feature independently. You have to follow the style guide which tells you what subset of the language to use and how to use it. This isn't an insurmountable problem but it is a problem. Rust has the same issue. With Go, everyone can feel free to use the entire language and every team's code ends up looking and feeling incredibly familiar, making it straightforward to contribute to most parts of any code base.
- matwood 6y ago> With Go, everyone can feel free to use the entire language and every team's code ends up looking and feeling incredibly familiar, making it straightforward to contribute to most parts of any code base. And it goes a step further. I read Go library code and it looks just like code I would have written. It's easy to understand and makes sense.
- asdkhadsj 6y ago> This applies in any case where one language is more complex than another. You can write almost any style of any language in C++, for example. True, but my point was primarily that Rust and Go share many of the same patterns. Structs, methods and interfaces can look nearly identical. This matters in my view when people think you need to go the most efficient and complex way to achieve similar goals as you might in Go. You were fine with performance loss in Go, so why complicate your life in Rust? It's, at least to me, a useful lesson. Using every tool is a form of premature optimization. Go forced me not to do that, sure. Rust doesn't, sure. So I do hold more responsibility in Rust than I do in Go, but that doesn't mean I can't learn the positives of Go _(boring code/etc)_ without suffering some of the extremes of their decisions _(no enums, pattern matching, etc)_. > With Go, everyone can feel free to use the entire language and every team's code ends up looking and feeling incredibly familiar, making it straightforward to contribute to most parts of any code base. Yea, it's a trade-off I suppose. My problem with that though is when I realized I don't like Go's version of verbosity and spreading out logic. I've had pages full of helper functions just to do some minor iteration mapping, flattening, etc. Having every team keep to the same standard of _(in my view)_ bad still feels bad. Consistent, sure, but consistently bad.
- dnautics 6y ago> The only thing Go truly nailed in my eyes is green threads. Those will always be better in Go than Rust (though futures are getting way better). Go nailed green threads. If you think Go's green threads are great, you should see erlang's. In erlang if you need to construct a mutual failure domain (have two green threads mutually destruct if one fails) you can use the link() function. Done. You can also trivially choose to have one of them be notified on the failure of the other instead of being destroyed.
- zeroc8 6y agoThe thing it nails is that mediocre programmers (like me) can easily understand and reason about source code written by others. In the C++ world, this can be very hard and thus time consuming. Go on the other hand let's me focus on the business value as opposed to becoming a language lawyer.
- bfrog 6y agoTrue until the code blows up to extraordinary sizes because of lack of expressive features. Rust code is incredibly easy to understand. Far, far easier than C++ in my opinion.