|
Subject: Proposal: "is defined" trait, "is typed" trait, "traits" pragma. Newsgroups: gmane.comp.lang.perl.perl6.language Date: 2005-08-10 16:09:46 GMT (3 years, 47 weeks, 12 hours and 1 minute ago)
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/
|
|
|