I don't know why but haven't seen many posts on how the combination of Rust's trait system, implicit conditional returns and strict enforcement of im/mutability of state allows one to handle significantly higher amount of states the application can take in the same amount of code. Other languages usually have you writing thousands of lines of verbose error handling and state validation code and traits allow for a superior way to compose behavior over standard interfaces / abstract classes.
I realize that Rust's compiler might catch more concurrency problems, but your comment is written as if you feel "blind" even writing single threaded code.
It's very common in Rust to do a big refactor or write a program from scratch and have it work on the first or second try, which may release a good amount of dopamine for some.[0]
Not saying the language is perfect, but it can feel pretty good, to the point of being addictive, while also freeing to know you can think less about the variants and let the compiler do it for you, and the reliability of the created program is usually pretty amazing. It can also be annoying, specially when you're learning it and try doing something in a way that's just not viable in an easy way (e.g. manually creating a Linked List).
[0] https://old.reddit.com/r/rust/comments/uixup6/just_wanted_to...
How would you compare it to Typescript? Having become a recent convert, I feel the same way going back to Javascript now
You often end up with obscure issues that a good type system should prevent. Maybe because the third party typings for a package are faulty or incomplete, maybe because the compiler just gave up on a complex expression and fell back to any, or because the developer just gave up and used `as any`.
Typescript is also really constrained by keeping JS compatibility. A prime example is the lack of real sumtypes. Instead you have to use objects with a string tag and do if/switch on that tag to disambiguate the concrete type, which is incredibly awkward when compared to proper compiler sum type support.
I'd much rather use Typescript than Javascript, but it's far from perfect.
Is your software more performant and does this translate to additional customers or reduced costs? Is your software more stable and does this result in reduced support costs or happier customers?
Testing effort is likewise not a decisive matter. In fact it's quite likely that what one wins time-wise on the testing side is lost on the development side.
That said, I think Go's simplicity has a lot of advantages over Rust for a great many use-cases. Imo Rust almost feels like a prototype for a great language which will finally get ownership-based memory management right. The goals of the language are admirable, and the tooling is great, but it's such a complex language once you start getting into topics like lifetimes and async.
I think it shines for certain use-cases where the tradeoffs it makes genuinely add value, but in a lot of ways I think it's more of a niche language for people who love esoteric programming topics rather than something with the potential to go truly main-stream.
What are the differences between an ADT (plus pattern matching i’d reckon?) in Rust/Swift vs the equiv in Go (tagged interfaces + switch statement)?
One has exhaustive matching at compile time, the other has a default clause (non exhaustive matching), although there’s an important nub here with respect to developer experience; it would be idiomatic in Go to use static analysis tooling (e.g. Rob Pike is on record saying that various checks - inc this one - don’t belong in the compiler and should live in go vet). I’ve been playing with Go in a side project and using golint-ci which invokes https://github.com/nishanths/exhaustive - net result, in both go and rust, i get a red line of text annotated at the switch in vscode if i miss a case.
Taking a step back, there isn’t a problem you can solve with one that you can’t solve with the other, or is there?
To take a step further back, why incomplete?
Also with Rust for instance you have more robust pattern matching. So you don't have to match only on type, you can match on complex criteria (i.e. foo is a Circle, with foo.radius < 10).
I find this type of programming very expressive and easy to reason about.
Yeah me neither, i’ve just been dabbling for fun recently. I’ve been dabbling with rust for longer
>> the Go way seems to have more boilerplate
…
switch t := s.(type) {
case Circle:
if t.radius < 10 {
fmt.Println("the rust syntax for this is sweeter")
}
…
https://go.dev/play/p/s4TTZeo7GseDefinitely less boilerplate in the rust version, but i don’t think i go along with it being incomplete or less clear.
Go: https://go.dev/play/p/s4TTZeo7Gse
Rust: https://play.rust-lang.org/?version=stable&mode=debug&editio...
For me, i reckon the Go type machinery is more verbose in this case, e.g. the isShape method to tag Circle as a shape - that just feels awkward to me.
The cyclomatic complexity is identical for both though.
Also I prefer with Rust-style sum types that the declaration happens in one place. In the Go version your Shape types could be scattered around all over the place, which makes it harder to parse and understand if you're reading unfamiliar code.
edit: e.g. https://go.dev/play/p/wDO5J8CElSC
enum Shape {
None,
Circle(radius: usize),
}
In your version we've lost the Shape concept, to make it more explicit, what's the idiomatic go version of: enum Shape {
Circle(usize),
Rectangle{length: usize, breadth: usize},
}
https://play.rust-lang.org/?version=stable&mode=debug&editio...In Go code will typically "offer" concrete types, and "accept" abstract interfaces. Abstractions over concrete types are expressed by consumers who want to operate on those types, rather than producers who provide implementations of them. So your Shape would probably end up an interface defined by whatever consuming code wanted to treat Circles and Rectangles equivalently.
E.g. if that means implementing low level things like cryptography APIs, or being able to define the exact memory layout of objects in memory or access raw pointers or write ASM inline then obviously that disqualifies ruby, python and js but it would mean Go qualifies.
The article is about a “messenger bot” for example and nobody’s complaining that it’s wrong to write such a thing in Rust.
The reality is that Rust is competing with Java and Go and Python for many things and its poor ergonomics are hobbling it.