[Perl 6 page]
You might be surprised to learn that the Synopses does not say much about the Perl 6 type system. Rather, it is more of a requirements document with some examples of what it ought to be able to do, and some statements of guiding principles.
So, my work in fleshing this out isn’t proposing radical changes to the existing work, but is defining the stuff in the first place. This page summarizes the state of affairs.
See What the Synopses say for a listing of what the Synopses say about the type system. This doesn’t cover matters of syntax or features that use types, but things that must be true on a deep level about the type system itself.
Notice how little is says. Yes, we have classes. We know that you can optionally check parameter types. Well, the rest is in the details!
Fundamentally, Perl 6 syntax allows for named method dispatch on objects. But it does not demand anything of the type system to do it! Classes are ruled by metaobjects that don’t have to be of specific types, or be organized in any specific way. Basically, you can write your own method dispatcher and drop it in, with any representation and feature set you like.
Fundamentally, each object points to its metaobject which Perl talks to in order to do a regular dispatch. Objects don’t have to belong to classes in the traditional sense. Rather, each object could be one-of-a-kind like in Self or Javescript. The concept of the object’s metaobject is purposefully more general than that of a type. Each object knows how to perform dispatches on itself, and that’s about all there is to it.
This can be used to supply different object systems, such as the standard Perl 6 class system, a Perl 5 compatibility system, a COM/CORBA interface, whatever foreign object support, or whatever. I’m sure some day there will be a Self-like object system on CPAN, and you can code with those and never touch the
The rest of this article is about the standard Perl 6 type system, which is supported by the built-in class mechanisms, grammar, library, etc. But remember, you can change anything.
What does Perl 6 the language think about types, in general?
To ordinary (single dispatch) method calls, the “type” is simply what the metaobject decides to do. The object contains an internal hidden pointer to the metaobject, and that’s all there is.
For normal classes, each class is a type, represented by a distinct metaobject which dispatches to the methods defined for that class.
Type annotations on variables have nothing to do here. Methods dispatch based on their metaobject, and no “type checking” is done anywhere. This is the Perl 5 model, and it will continue to work if you don’t declare types on your variables or parameters at all.
On the other hand, for “multi” subs and methods, types have meanings. In order to resolve to the correct multi choice, the multimethod dispatch (MMD) system built into Perl 6 has a detailed awareness about certain aspects of types.
Obviously, it needs to know that values have particular types. It needs to compare this to the declared parameter types, and work out partial ordering relationships and better/worse match rules. So it knows that some types may be substituted for another, and that some substitutions are better than others.
Some type substitutions are valid only depending on other details of the parameter declarations. For example, a read-only parameter can accept more than a by-reference parameter.
If you declare types on your variables, Perl 6 will validate that only compatible objects are stored in those variables. This is a subset of what is known by the MMD system. It doesn’t care how good a match is, only that it is indeed allowed.
Besides checking assignments and parameters for legality, Perl can use its knowledge to perform conversions automatically. Instead of saying “You can’t do that”, it will know how it can work, and take care of the details for you.
If a variable is known to hold a particular type, method dispatch can be highly optimized. Instead of looking up a method by name, it can use a direct pointer to the proper code. So typing your variables can make code run much faster, not just catch mistakes at compile time.
The big question is, “Just what are the relationships between types?” The relationship tells whether or not I can store a particular object in a typed variable, whether or not a parameter is of the correct type for a call, and which multimethod (if any) is matched by a particular set of actual parameter types.
The questions of “can this substitute for that?”, “if so, how?”, and “is this better or worse?” describes the meat of the type system. This is not discussed in any manner whatsoever in the synopses, except to assume that “isa” subtyping is assumed to work like in Perl 5. Thinking it through, it provides for simple dispatch, but doesn’t work once you add types to parameters. This is discussed in detail on my page “isa” relationships and inheritance.
The learned opinion among those who have pondered the issues in the Perl6-language mailing list for a few years is that research has been done on this topic since the mid 1980s, and lessons can be learned from seeing how templates in C++ provide a different kind of reuse, and from the work in other languages faced with similar issues.
You might want to check Wikipedia on Type polymorphism for a summary.
The higher-order concept of substitutability that takes in both “isa” inheritance and generics is called “Function-bounded quantification”, or simply “F-bounds”. My introduction to performing F-bounds in the Perl 6 type system is described in Advanced Polymorphism in Perl 6 — Features of a second-generation type system (PDF) or (ODT)
Here is a list of links to reference material on the web. (coming soon)