IMHO type inference is the best way to get typing into Perl.
We don't lose any expressiveness or hurt backwards compatibility.
About the only thing we need to make visible are a few additional
pragmas to enable type inference warnings.
Steve Fink wrote:
> Types should be inferred whenever possible, and optional type qualifiers
> may be used to gain whatever level of type stricture desired.
This will impact the bytecode storage format because we don't
want to lose any type information present in the op tree. Reverse
engineering source from bytecode is easier, but I think performance
and distribution (not obfuscation) is driving the need for bytecode
format.
> I propose that we create a type hierarchy, such as
>
> any
> list
> list(T)
> hash
> hash(T -> T)
> scalar
> reference
> ref(T)
> nonref
> number
> integer
> void
The top level types you sketch are easily deduced from Perl's
syntax alone -- we don't need any deep analysis. In order to
produce anything useful, global dataflow analysis is required
with all the optimization stages delayed until all the source
has been seen. That's not a small thing to bite off and I don't
see any way to move the decision to a module -- it's got to be
in the core.
Assuming type inference is accepted...
Many Perl operators are polymorphic, so they don't reveal a whole
lot about their operand types (++$a is a good example). I propose
that we abandon the typical view of a type hierarchy like the one
listed above and adopt a capability-oriented one. It would be
relatively easy for a sub to publish it's prototype in terms of
what operations must be defined on the arguments.
Warnings would be more like "numeric comparison required" instead
of "integer required".
> Now say we insert C<my $x : number> at the beginning of the example
> (or some other syntax). That means that we are asserting that I<$x>
> will I<always> be of type C<number>
Type inference and static typing are two different issues. I think
they should be proposed in different RFCs.
> Note that error messages are only generated when two things with
> strong types collide. So C<my ($x : integer) = /(\d.*)/> will not
> complain, but C<my $x : integer = "string"> will.
That's not useful -- it needs to be more general. Warnings should
occur if a capability is required that the value does not implement.
This is orthogonal to static typing.
- Ken