I would like to echo on Tong Sun's suggestion here. I know his isn't an "experience report" per se, but a suggestion worth building on, for those who're wishful of optionals in Go.
The case mentioned might be immediately solvable by just using a pointer to the variable, which gives you the ability to assign nil (json null) to it. However, *T is *not* syntactic sugar for Optional<T>. Pointers come across as "just as good as optionals" when needed because we don't have another [built-in] option. Not to mention, pointers have more than nil-assignability to them. I understand that we can just write a generic generator for Optional<T> for whatever type we want an optional wrapper for. This is something I've always done when absolutely needed (most of the time with proto3 Protobuf). func main() { msg := pboptional.NewString() fmt.Println("msg:", msg). // => msg: nil msg.From("hello world") fmt.Println("msg:", msg) // => msg: Optional("hello world") if msg, ok := msg.Unwrap(); ok { // some fmt.Println("msg:", msg) // => msg: hello world } else { // none fmt.Println("msg is nil") } } There are obvious advantages to using optionals, including safely defining variable. However, on the contrary, Go is currently, and by-design so, not in the best shape to adopt optional types. For optionals to be a viable in core, non-optionals would have to (?) guarantee a value (and not just assumed zero-value when left uninitialized). This is for the compiler to deliver the type-safety promise of optionals *and* non-optionals. In other words, it means that we would have to not allow uninitialized types to be zero-value. I mean, what good is supporting optional types, if the non-optionals don't require you to set their values? Consider this currently valid Go code: func getAge() (int, error) { var age int return age, errors.New("ERR") // age is assumed zero-value } func main() { age, err := getAge() // => 0, ERR } With optionals implemented (how I'm imagining), this would become: // uninitialized non-optional should not compile // i.e. don't assume zero-value func getAge() (int, error) { var age int return age, errors.New("ERR") // => compile error: variable age is not initialized } // this should work instead func getAge() (int?, error) { var age int? return nil, errors.New("ERR") } func main() { age, err := getAge() // => Optional(nil), ERR } But every method that also returns an error, should not necessarily have an accompanied optional type, like `(int?, error)`. There's so much in Go that can be nil (or nil like zero-values), and isn't necessarily fit to be considered optional, like nil interfaces and pointers. We're also going to have to reconsider the phrase "errors are just values" if we want to pair non-optional types with error in the return types. Take the following suggestion (inspired from Swift): func getAge() (int, throws error) { var age int throw errors.New("ERR") // we're not returning anything and it compiles // i.e. throw *is* return but only for error } func main() { age := try getAge() // => panic("ERR") } func main() { // although getAge() returns a non-optional, it // gets is automatically wrapped in an optional // when using `try?`. // // basically we're trading error for nil value. age := try? getAge() // => Optional(nil) } func main() { // this is the graceful way to get non-optional result // and handle error, if any. try { age := getAge() } catch error { fmt.Println(err.Error()) // => ERR } } Therefore, if considered, optionals would be a *huge* undertaking to implement (and practice) in Go source, while also delivering the promise optionals bring. Let me know if you have a better syntax/suggestion than try catch blocks (for returning only an error; no zero-values for non-optionals). I think an ideal first step would be the community blessing and adopting en masse some Optional<T> "generator". Second step would be to vouch for generics with this use case. And then implement an actual generic like `type Optional<T> struct { Value T; HasValue bool }`. And then perhaps, as the fourth or so step, we may shape our coding practices to better understand how all this could be practiced in Go source itself. -- Gurpartap Singh https://twitter.com/Gurpartap On Saturday, August 19, 2017 at 8:35:34 PM UTC+5:30, Tong Sun wrote: > > Suggesting C# type syntax like "int*?*" so as to take nil as valid value. > > Currently: > > var i int > i = nil > > will give: > > cannot use nil as type int in assignment > > However, more and more people are using json to transport data, and there > will be times that json may be invalid. I.e., the "int" type has 'null' as > input. > > This is causing tremendous problems for me so far, as I have to jump over > the hoops to deal with them. > In C#, just by adding a "?" to the end of the type solves the problem. > > Please consider. > > > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.