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/
pgpJ8vZUZ7eIg.pgp
Description: PGP signature
