So I'm starting to write the inferencer.  Immediately I encounter the
problem that every type can potentially contain "undef":

    my IO $x = open('/etc/passwd');
    $x = undef;
    $x.close;

This raises the runtime error:

    *** Can't call method "close" on an undefined value.

The "undef" literal can defeat the type checker freely:

    my Int @x := undef;
    say @x.end; # boom, undefined list generator, per S04

I understand $Larry had rejected RFC192 "Undef Values ne Value", on the
ground that "undef" can now carry more interesting information.
However, sometime it is better if we can have a clear boundary so
the dreaded NullPointerException can be raised as early as possible.

The Nice programming langugage (http://nice.sourceforge.net/) has a nice
way to solve this.  Transliterating to Perl 6:

    my IO $x = ...;  # never undef
    $x.method;       # always succeeds

    my ?IO $x = ...; # possibly undef
    if defined $x {  # needed -- direct $x.method will not typecheck
        $x.method
    } else {         # handle the undef case
        ...
    }

This is certainly too static for Perl6.  However, it would be nice to
be at least able to declare a variable so that all undef reaching it
will instantly explode.  So I propose the "is defined" trait:

    # must be assigned before use
    # if open() returns undef, die right there.

    my IO $x is defined = open('/etc/passwd');

    $x = undef;     # this fails at compile time

For the compiler, $x is compiled to the real "IO" type, while the
ordinary "my IO $x" is compiled to "Either Error IO" type.

Furthermore, it would be nice to tell the inferencer to infer the type
of a certain variable, instead of having to either write them out by
hand, or accepting their fate as Any.  I'd like to see "is typed":

    {
        my $x is typed; # Infer $x's type (Str) for me
        $x = "Hello";
        print $x;
    }

Finally, it would get tedious to write them out by hand.  So a lexical
"traits" pragma may help:

    {
        # Entering the realm of referential transparency...
        use traits < defined typed constant >;
        my $x;  # automagically receives the three traits

        {
            # Falls back to the dynamic world...
            no traits < typed constant >;
            my $y;
        }
    }

Does this sound sane?

Thanks,
/Autrijus/

Attachment: pgpJ8vZUZ7eIg.pgp
Description: PGP signature

Reply via email to