5 ms·
>> the main thing missing from Go is ADT's. After using these in Rust and Swift, a programming language doesn't really feel complete without them What are the
by CraigJPerry 4y ago
>> the main thing missing from Go is ADT's. After using these in Rust and Swift, a programming language doesn't really feel complete without them
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 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?
- skohan 4y agoI'm not a go expert, but imo the main difference is ergonomics and clarity. Rust/Swift style ADT's plus pattern matching gives you a very concise and readable way to declare and use sum-types, and the Go way seems to have more boilerplate. 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.
- CraigJPerry 4y ago>> I'm not a go expert 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/s4TTZeo7Gse https://go.dev/play/p/s4TTZeo7Gse Definitely less boilerplate in the rust version, but i don’t think i go along with it being incomplete or less clear.
- skohan 4y agoI think this is less clear than. The rust/ swift version.
- CraigJPerry 4y agoThat’s fascinating, what would you say obscures clarity? Go: https://go.dev/play/p/s4TTZeo7Gse https://go.dev/play/p/s4TTZeo7Gse Rust: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8276ff4430c3f5b344f3ddde3c5e4930 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.
- skohan 4y agoYeah exactly, imo the way the Go version requires you to declare an interface, in this case with a no-op method essentially acting as a tag, and declare conformance on your types is quite noisy and feels like a hack. 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.
- preseinger 4y agoThis Go code is wildly non-idiomatic. Type assertions via `.(type)` are a tool of last resort, not something that an application developer should turn to as a solution to a problem, and certainly not post-1.18, which permits generics. edit: e.g. https://go.dev/play/p/wDO5J8CElSC https://go.dev/play/p/wDO5J8CElSC
- CraigJPerry 4y agoHey thanks for sharing this, I think this has lost track of the problem though, remember we're looking for the alternative to rust's: 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&edition=2021&gist=03c26eceee80168ffd69518aeefcc8e6 https://play.rust-lang.org/?version=stable&mode=debug&editio...