On Thu, 22 Feb 2018 12:55:01 +0000 Jesper Louis Andersen 
<jesper.louis.ander...@gmail.com> wrote:
> For sums, in Go, I have to return a pair,
> x, err := someOperation(..)
> but this is slightly inconsistent, insofar I can return "nil, nil", which
> might not be a valid value, or I can return "3, Error(..)" but in that case
> the 3 is not to be used. Only one "side" is valid at a given point in time.
> If you have sum-types in the usual sense, you can define something along
> the lines of (OCaml follows):
> type ('a, 'b) result = Ok of 'a | Error of 'b

I once worked out some details of adding sum types to Go and I
think it is quite doable and easy to implement. For example,

    func f(i int) float64|error {
        if i == 0 { return errors.New("not zero") }
        return 1./float64(i)

As in OCaml "|" is used for sum types and it binds less
tightly than existing type "expressions".

> And then you can discriminate on this value via pattern matching
> match res with
> | Ok value -> ...
> | Error err -> ...

Not quite the same but something similar is doable with
type switch.

    res := f(j)
    switch res.(type) {
    case error: ...
    case string: ...

This use is identical with f returning interface{} (even the f
body remains exactly the same).  This makes sense since
interface{} is in a sense the sum of all other types.

But by allowing sum type, we can do better checking within f
(e.g. return "string" will fail to compile). And by using a
sum type instead of a product type to return a value or error
also makes the code clearer.

I once counted there were about 8000 uses of <type>,error as
return types for functions in $GOROOT/src which could benefit
from sum types. Now there seem to be about 4253 instances
(found using a crude regexp).

I think I worked out the semantics of T1|T2 where T1 and T2
are both interface types themselves. It all seem to fit
together, at least on paper! I need to find my notes....

> The other matching construction is a switch-statement, but such a statement
> doesn't allow for matching deeply into an AST structure, which a
> traditional pattern matcher does.

Deeper matching also binds names to matched parts. e.g.

    sumsqr [] = 0 
    sumsqr (x:xs) = x*x + sumsqr xs

This sort of binding may be difficult to shoehorn into Go.
There may be no real benefit of binding head, tail of a slide
but consider an AST. If you are already cracking it open for
matching it with a pattern, you may as well bind variables to
interesting parts.

    match stmt {
    case If1stmt(test:, thenstmt:): ...
    case If2stmt(test:, thenstmt:, elsestmt:): ...

Hard to come up with an intuitive syntax here.  Also probably
impossible  to add func level patterns.

> Coincidentally, given sum-types, you can write a regexp matching engine in
> very few lines of code. See Bob Harper's "Programming in Standard ML" [2]
> for example; it is the introductory example to get a feel for the language.
> The solution uses sum types to define the AST for regular expressions, and
> then uses pattern matching to build a matcher on regular expressions. I
> can't remember how far Bob takes the exposition however.

This should be doable given my sum-type proposal sketch above?!

> [0] They are really the same in the right setting. In a boolean algebra,
> for instance, + is OR and * is AND. If you look at them from the Category
> Theory branch of mathematics they are related: they are duals of each other
> which means that if you "invert" one you get the other and vice versa.
> [1] Obviously, Go, being a descendant of Algol has two syntactic classes:
> statements and expressions, whereas OCaml is descendant from either Lisp or
> the Lambda Calculus depending on view. Those languages only have
> expressions as a syntactic class.

sum-types (which are easy to implement) and pattern matching
(may be not so easy) can be added to Go even if it has
non-expression syntatic classes.

> [2] http://www.cs.cmu.edu/~rwh/isml/book.pdf
> [3]
> https://www.microsoft.com/en-us/research/wp-content/uploads/1987/01/slpj-book-1987-small.pdf

SLPJ's book was quite an eye opener for me back in the '80s! 

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.

Reply via email to