5 ms·
Almost the perfect language. I don't get why it's they didn't make it compatible with normal Go. It should have been like Typescript where you can compile plain
by nmilo 2y ago
Almost the perfect language. I don't get why it's they didn't make it compatible with normal Go. It should have been like Typescript where you can compile plain Go, it just adds features on top it. The "let" and struct changes are totally unnecessary. Then you can interop with existing libraries and convert large Go projects to this incrementally.
- atombender 2y agoInterop would force the language to keep certain core features, like nil pointers and zero values, that in Borgo are presumably considered anti-features. You end up with the worst features as the common denominator and something you can never get rid of; the moment you call a Go library that can return nils, for example, you have to deal with those as nils (and run the risk of nil bugs) rather than the safer option type. We've been there before. C++ chose to be largely compatible with C as it existed at the time, and that legacy casts a long shadow, even if it's no longer a strict superset. C++ still has C-style arrays, null-terminated strings, unsafe pointer arithmetic, implicit conversions, etc. You could also argue that TypeScript's backwards compatibility with JS also adds a similar burden. It's had to provide a lot of mechanisms to allow untyped values to share the same universe as typed values. Maybe the solution is to provide a kind of "unsafe" kind of block where you can interact safely with Go code but you're forced to deal with the discrepancies. For example, you can call a Go function that returns nil, but to pass the value out of the unsafe block, you have to convert it to an optional.
- jitl 2y agoThe easy way to deal with this is to just treat any pointer coming from regular Go that isn't annotated as //@NotNull or something as an Option<*T> - no need to ask the user to do the conversion, the compiler can just handle this. You don't even need a different representation -- just keep the type as the pointer in compiled Go. The user will still need to do the nil check, but the compiler is enforcing it, and you can use `?` or another macro to propagate the null. It's the same with Typescript as you say, if there's some library and you're not sure if `function getThingy()` will always return `Thingy`, you can declare the type as `Thingy | undefined`; potentially you check the return value right away or you just propagate it and it's totally fine.