5 ms·
I just came from rust to go and… what a disappointment. Missing fields default to some kind of default “zero value” - for any type, even full blown structs. Yo
by the_gipsy 5y ago
I just came from rust to go and… what a disappointment.
Missing fields default to some kind of default “zero value” - for any type, even full blown structs. You can’t tell the difference of a missing field or the field having the default value.
So if a field has a validation of “must be greater than zero”, you can’t really give a proper error message. If user puts in “0” or omits the field, you always get a value of “0”.
- deleted 5y ago[deleted]
- rtkaratekid 5y agoI just went from two years of professional Rust development to Go, and I’m right there with you. Thankfully we have some terrible C++ that looks to be a good candidate for a rewrite.
- apendleton 5y agoIf you want a field to be able to be not-set, you just need to specify that by making it an `Option<_>` type. So like, if the field is a number, make it an `Option<u64>` -- that way you can distinguish between not-set (`None`) and set to zero (`Some(0)`). Edit: whoops, misread which language it was you were frustrated with. Nevermind!
- tylerhou 5y agoI know you’re giving helpful advice, but the author is talking (complaining) about Golang, which has no option typing (unless you want to use a pointer).
- the_duke 5y agoYou misunderstood, parent is complaining about Go, not about Rust. In Go you would have to use a pointer to represent Option<T>, which makes code really awkward. Go serialization really has quite a few issues apart from default initialization. Configuration by somewhat weird struct tag strings which are only evaluated/validated at runtime, de/serialization is all done via reflection (unless you want to use code generation), ...
- eyelidlessness 5y ago> In Go you would have to use a pointer to represent Option<T>, which makes code really awkward. This sounded surprising to me, then I remembered Go doesn’t have generics. I imagine this won’t be as much of an issue when it does?
- throwaway192874 5y agoPerhaps if they were to remove the concept of nil in golang, but since they are all about backwards compatibility (which is nice to be fair), I don't think there's much change of seeing mainstream adoption because of how many existing projects will rely on default value in certain circumstances I'd love to be proven wrong, but even with generics if you start using option types, it's going to be like JS and TypeScript where you'll have some parts nicely typed and others are the wild west
- the_duke 5y agoEmulating ADTs without language support/pattern matching is quite awkward. A prime example is std::optional in C++. .map() et al only get you so far. When extracting the value in Go you either have to return a pointer / error pair or abort. Both of which introduce awkward code patterns and potential for misuse.
- hawk_ 5y agowhen Optional<u64> is used in rust what's the memory layout like? is the absence tracked using a pointer which is null or a bitvector of optional fields?
- goldsteinq 5y agoOption<u64> would look like tagged union in memory, so one bit "tag", 8 bytes u64 and padding. If type inside of Option<_> has invalid values (like references which can't be null) one of these would be used for None, so Option<&T> is the same size as &T.
- hawk_ 5y agothanks and is the padding for aligned access (wasted space) or just full byte (poor performance on non x86/64 like architecture)? because that's the interesting part as to what's the tradeoff chosen and whether a dev can choose a different one. Any doc references are appreciated.
- Nullabillity 5y agoThey are padded for aligned access, so on amd64 Option<u64> will be 16 bytes.[0] However, the unused discriminant values are counted as niches for enums wrapping that, so Option<Option<u64>> is still 16 bytes (for example). [0]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ccfc6db189ae326a52d3d5187fce11fc https://play.rust-lang.org/?version=stable&mode=debug&editio...
- ahahahahah 5y ago> If type inside of Option<_> has invalid values Can it actually use any general invalid bit pattern? I expect that it only supports an optimization for values that cannot be zero (and then it uses zero to indicate None).
- X6S1x6Okd1st 5y agoI've usually seen this handled by having everything be a pointer, the default value of the pointer is nil. You can also use the SQL values.
- the_gipsy 5y agoIsn’t it insane to change your types to accommodate this? You have to change all fields accesses, it behaves differently, you lose non-nullability…
- shp0ngle 5y agoWell that's go for you. Go is simple and "default case" which is simple and works for most cases... and then you have edge cases where you need to bend over backwards. As an exercise, try to use comma (",") in JSON field name.
- autarch 5y ago> Isn’t it insane to change your types to accommodate this? Welcome to Go! This was a real pain for us at my last job, where we used go-swagger to generate REST API code. All the generated structs had pointers for _non-optional_ fields so it could also check that they were populated. Meanwhile, optional fields were not pointers because they could use the default value. So then we ended up with lots of code doing checks for `is X nil` all over the place. Many of those wouldn't be needed in normal usage, since a nil value would be rejected by the validator earlier, but we also sometimes needed to make these structs by hand and pass them around. All of this is necessary because of the lack of generics. With generics you can solve this with things like an `Option<T>` type, like Rust does.
- bpicolo 5y agoPretty excited for Go 1.18 for that reason! Will likely take some time for the ecosystem to shuffle out good solutions for different bits, though
- the_gipsy 5y agoYea exactly, pointers id allowing nils, which I don’t want to conflate with omitting either. In the end what I did is parse the JSON-string twice, once more with a “checkjson” library that tells me about missing fields.
- nevermind_29381 5y agoThis is a thread about Serde, not how superior Rust and how shitty Go is. We've had more than enough from this ...
- dcow 5y agoRight, serde is one of the many features about Rust that people miss when writing Go. Simply a group of downtrodden programmers bonding over a shared experience the memory of which evoked when reminiscing on a grand cathedral. But alas the mere reminder of the existence of such a grand structure weighs on the heart of the plebeian. No need to rub it in sorry gogrammers’ faces that their language is a limp noodle in comparison. Thanks for reminding us (;
- chakkepolja 5y ago> No need to rub it in sorry gogrammers’ faces that their language is a limp noodle in comparison. Say what you want about Go, but gophers get better jobs than you, meanwhile almost all rust jobs are shady crypto startups. Hard truth lol.
- dcow 5y agoI know how to write both, thank you very much. And I predominately use Rust and Swift at my current gig, which is not a crypto anything. Did you know Microsoft, Cloudflare, Google, and Mozilla all use Rust? Wow. Such shade. Much crypto. I guess you're right about them all being startups though.