On Fri, Oct 23, 2020 at 12:17 AM Ian Lance Taylor <i...@golang.org> wrote:
> So there are several possible approaches. I'm guessing you want one > that is more implicit, but as a general guideline Go tends to prefer > explicit code. > > I don't think there is a good implicit approach to this problem. If you have a value that is optional, it has to be modeled as such in your system. The `*bool` representation is precise: `nil` maps to the bottom of the domain, and `true`/`false` maps to the values of the domain. The only way to work with such a type is to match on it to determine if the pointer is nil, followed by inspection of the boolean value. Generally, optional values need somewhere in the program where they are scrutinized, and you can't avoid that scrutiny. You can try to hide it with some clever implicit construction, but that is very likely to lead to subtle errors in programs. People might want to treat `nil` as an exception case, but it really isn't. It is a value like any other value, and should be treated as such in the program. The approach taken by e.g., OCaml is that there is no `nil` in the language at all. Rather, there is a `'a ref` type, but that cannot be initialized to be `nil`. It always references something valid. You can then mint your own `nil` by means of an option type: type 'a option = None | Some of 'a However, the underlying representation is much akin to that of a typical pointer value. What has this gained us? Well, we can now create type 'a option2 = None2 | Some2 of 'a for instance. This type is *different* from the first one, yet has the same underlying representation. Thus, we can avoid a problem in the Go `*bool` solution: namely conflation of pointer representations with optional values; we simply mint a new type. I think this is more explicit and more precise in representation. And it's solution would work well for the originally proposed case. As an aside, this leads to an important design point: if pointers are used as optional values (and not for the sake of sharing/optimization) stripping away the pointer often leads to code that is easier to work with since you avoid that pesky nil-check all over the place and can do with it in one place. Also, the astute reader might have caught on to the fact that the same observation holds true for error values, which in OCaml are defined as: type 'a err = Err of 'a type ('a, 'b) result = Err of 'a | Ok of 'b If we now recognize there is a unit type with one inhabitant, you can see that an `'a option` is really just a `(unit, 'b) result`. That is, there is a good type-theoretic reason for your observation. -- J. -- 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. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAGrdgiWjsL-hyp3%2Bch8aRaHFxiFqZekbcHPVcftV7SpXLMiCeQ%40mail.gmail.com.