7 ms·
I see this point everywhere about Rust's union types and it always kind of irks me: > The point is, this [Result type] makes it impossible for us to access an
by nmilo 4y ago
I see this point everywhere about Rust's union types and it always kind of irks me:
> The point is, this [Result type] makes it impossible for us to access an invalid/uninitialized/null Metadata. With a Go function, if you ignore the returned error, you still get the result - most probably a null pointer.
It's all about framing. You can just as equally say it is "impossible" to access an invalid Go FileInfo, because you'll get a panic for derefencing a null pointer. Or you can just as equally say it is "possible" to access an invalid Rust Metadata, just by doing .unwrap(). Everyone knows an unchecked .unwrap() is just bad Rust code, but then again dereferencing a pointer without checking the returned error is just bad Go code.
Anyways the rest of the article seems like just a criticism of Go's file system API, which seems fair but also seems a little niche given how difficult it is to create a good cross-platform file system API. This particular point irks me though:
> stat "$(printf "\xbd\xb2\x3d\xbc\x20\xe2\x8c\x98")"
> fmt.Printf(" %s\n", e.Name())
> It... silently prints a wrong version of the path.
What did you want it to do? The author even admits go strings are just byte slices, not UTF8, and then passes a non-UTF8 string to a function that expects UTF8. If there's a chance the file path your program works with might not be UTF8, then you should validate it. I think moving the complexity UTF8-ness out of the type system was a necessary evil.
- jen20 4y ago`Result<T, E>` is just one possible use of enumerations ("union" types as you're calling them). The beauty is that you can make illegal states unrepresentable.
- shadowgovt 4y agoThe difference is what the language makes easy to do and how it signals to you you're about to do something dangerous. If you call `.unwrap()`, that's a big yellow flag that you're going to be taking the gloves off and maybe touching something radioactive. Go has the maybe-radioactive thing sitting right there; safely touching it and unsafely touching it look exactly the same. I generally enjoy using Go, but this is one of the pieces of the language design that I was surprised Go went with; we've known as an industry for decades that including bare null / nil / undefined / whatever we want to call it without type-system assistance is leaving a bare third rail lying around.
- nmilo 4y agoRust's approach is definitely safer, but my point is that the concerns are overblown. The Go compiler raise an error if a variable (error) goes unused, and just ignoring this error by naming it "_" is obviously dangerous. Yes, Rust makes it easier to never ignore an error, but I don't think I've ever accidentally ignored an error that I shouldn't have in Go.
- jhoechtl 4y agoGolang gives you freedom. Rust gives you seat belts. It depends on you what you value more.
- jeroenhd 4y agoI don't think Go gives you freedom, actually. There aren't any good standard library functions for dealing with badly encoded unicode for file names, for example. Instead, Go provides what the language designers considered solutions to most problems. Window not having Unix permissions? Just fake a bunch of them. Path not valid unicode? Probably not a problem. As long ad you agree with the way the Go designers think, that'll save you tons of work. Just don't use Go in situations where those solutions might not work out, like when you're iterating over arbitrary files instead of the files you've created yourself in Go code.
- shadowgovt 4y agoThe counterpoint is "your filenames shouldn't be badly-encoded unicode." In other words, "If `ls` can't render it, it's a bad filename. Rename the file." (This does mean that Go is constraining the set of problems it's easy to solve with it. But that's the nature of programming in general... We decide what problems need to be easier to solve at the expense of putting some problems outside the "sweet spot" and requiring more work to solve them).
- WJW 4y agoIf `ls` can't render a filename that is legal under the POSIX specs, there are two possibilities: - `ls` is wrong and should be fixed. - The specs are wrong and should not allow filenames to be arbitrary bytesequences. The third option ("The user is wrong even though they did exactly what was in the spec") is just unsatisfactory because it self-contradicts.
- eklavya 4y agoBy extension of that logic, all dynamic languages are as strict as static typed, since it will crash on first abuse. The benefit is in capturing things in type system so you can see what’s going on and you can’t ignore it. Runtime vs compile time debugging. Did I get you right?