Hacker News new | ask | show | jobs
by lerno 1776 days ago
What I mean by saying "it's a binding" is that it is a property of the variable (or return channel of a function) rather than a real sum type. Consequently it does not participate in any type conversions and you cannot pass something "of type int!" because the type does not exist.

Here is an example:

    int! x = ...
    int*! y = &x;
    int**! z = &y;

    // If it had been a type then
    // int!* y = &x;
    // int!** z = &y;

    // int*! y = &x;
    // means 
    // int*! y = "if x is err" ? "error of x" 
    //                         : "the address holding the int of x"
This also means that `int!` cannot ever be a parameter, nor a type of a member inside of a struct or union.

The underlying implementation is basically that for a variable `int! x` what is actually stored is:

    // int! x;
    int x$real;
    ErrCode x$err;

    // int*! y;
    int* y$real;
    ErrCode y$err;

    // y = &x;
    if (x$err) {
      y$err = x$err;
    } else {
      y$real = &x$real;
    }

    int z;
    // y = &z;
    y$err = 0;
    y$real = &x;

The semantics resulting from this is different from if `int!` had been something like

    struct IntErr { 
      bool is_err_tag;
      union {
        int value;
        ErrCode error;
      };
    };
Which is what a Result based solution would work like. In such a solution:

    int! x ... ;
    int!* y = &x; // Ok
    int z = ...
    y = &z; // <- Type error!