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.

Reply via email to