=encoding utf8 =head1 TITLE Synopsis 13: Overloading =head1 VERSION Created: 2 Nov 2004 Last Modified: 17 Jan 2012 Version: 17 =head1 Overview This synopsis discusses those portions of Apocalypse 12 that ought to have been in Apocalypse 13. =head1 Multiple dispatch The overloading mechanism of Perl 5 has been superseded by Perl 6's multiple dispatch mechanism. Nearly all internal functions are defined as C subs or C methods on generic types. Built-in operators are merely oddly named functions with an alternate call syntax. All you have to do to overload them is to define your own C subs and methods that operate on arguments with more specific types. For unary operators, this makes little effective difference, but for binary operators, multiple dispatch fixes the Perl 5 problem of paying attention only to the type of the left argument. Since both argument types are used in deciding which routine to call, there is no longer any trickery involving swapping the arguments to use the right argument's type instead of the left one. And there's no longer any need to examine a special flag to see if the arguments were reversed. For much more about multiple dispatch, see S12. =head1 Syntax There is no longer any special C syntax separate from the declarations of the C routines themselves. To overload an existing built-in sub, say something like: multi sub uc (TurkishStr $s) {...} A C is automatically exported if governed by a proto that is exported. It may also be explicitly exported: multi sub uc (TurkishStr $s) is export {...} Now if you call C on any Turkish string, it will call your function rather than the built-in one. If you import a multi into a UNIT scope, it is automatically re-exported. The types of the parameters are included in the I of any C sub or method. So if you want to overload string concatenation for Arabic strings so you can handle various ligatures, you can say: multi sub infix:<~>(ArabicStr $s1, ArabicStr $s2) {...} multi sub infix:<~>(Str $s1, ArabicStr $s2) {...} multi sub infix:<~>(ArabicStr $s1, Str $s2) {...} The C syntax had one benefit over Perl 6's syntax in that it was easy to alias several different operators to the same service routine. This can easily be handled with Perl 6's aliasing: multi sub unimpl (MyFoo $x, MyFoo $y) { upchuck(); } &infix:<+> ::= &unimpl; &infix:<-> ::= &unimpl; &infix:<*> ::= &unimpl; &infix: ::= &unimpl; A C is in effect only within the scope in which it is defined or imported. Generally you want to put your C subs into a package that will be imported wherever they are needed. Conjectural: If the first parameter to a C signature is followed by an invocant colon, that signature represents two signatures, one for an ordinary method definition, and one for the corresponding C definition that has a comma instead of the colon. This form is legal only where the standard method definition would be legal, and only if any declared type of the first parameter is consistent with C<$?CLASS>. =head1 Fallbacks Dispatch is based on a routine's signature declaration without regard to whether the routine is defined yet. If an attempt is made to dispatch to a declared but undefined routine, Perl will redispatch to an C submethod [conjectural] as appropriate to define the routine. This provides a run-time mechanism for fallbacks. By default, these declarations are taken at face value and do not specify any underlying semantics. As such, they're a "shallow" interpretation. [Note: the following section on "is deep" may no longer be necessary given the way metaoperators are now constructed.] However, sometimes you want to specify a "deep" interpretation of your operators. That is, you're specifying the abstract operation, which may be used by various shallow operators. Any deep multi declarations will be "amplified" into all the shallow operators that can be logically based on it. If you say: multi sub infix:<%> (Us $us, Them $them) is deep { mymod($us,$them) } then multi sub infix:<%=> (Us $us, Them $them) { $us = $us % $them } is also generated for you (unless you define it yourself). The mappings of magical names to sub definitions is controlled by the C<%?DEEPMAGIC> compiler hash. Pragmas can influence the contents of this hash over a lexical scope, so you could have different policies on magical autogeneration. The default mappings correspond to the standard fallback mappings of Perl 5 overloading. These deep mappings are mainly intended for infix operators that would have difficulty naming all their variants. Prefix operators tend to be simpler; note in particular that multi prefix:<~> is deep {...} is better written: method Stringy {...} (see below). =head1 Type Casting A class may define methods that allow it to respond as if it were a routine, array, or hash. The long forms are as follows: method postcircumfix:<( )> (|capture) {...} method postcircumfix:<[ ]> (**@slice) {...} method postcircumfix:<{ }> (**@slice) {...} Those are a bit unwieldy, so you may also use these short forms: method &.( |capture ) {...} method @.[ **@slice ] {...} method %.{ **@slice } {...} The sigil-dot sequence in these short forms autogenerates the corresponding public operators, in exactly the same way that the sigil-dot in: has $.action; has @.sequence; has %.mapping; autogenerates public accessor methods. And because it uses the same method-autogeneration mechanism, the specific sigil used to specify a short-form postcircumfix operator doesn't actually matter...as long as it's followed by a dot and the bracket pair containing the signature. (Though it's probably kinder to future readers of your code to stick with the "natural" sigil for each type of bracket.) Note that the angle bracket subscripting form C<< . >> automatically translates itself into a call to C< .{'a','b','c'} >, so defining methods for angles is basically useless. The expected semantics of C<&.()> is that of a type on which may or may not create a new object. So if you say: $fido = Dog.new($spot) it certainly creates a new C object. But if you say: $fido = Dog($spot) it might call C, or it might pull a C with Spot's identity from the dog cache, or it might do absolutely nothing if C<$spot> already knows how to be a C. As a fallback, if no method responds to a coercion request, the class will be asked to attempt to do C instead. It is also possible (and often preferable) to specify coercions from the other end, that is, for a class to specify how to coerce one of its values to some other class. So, if you define a method whose name happens to be type name, you can view it as a coercion to that type. But that method is a regular method even its name happens to be a type name. That means the compiler does not enforce the type of the returned value. method Str { self.makestringval() } As with all methods, you can also export the corresponding C: multi method Str is export { self.makestringval() } in which case you can use both calling forms: $x.Str Str($x) If the source class and the destination class both specify a coercion routine, the ambiguity is settled by the ordinary rules of dispatch. That is, C<$x.Str> will always prefer the method form and C will always prefer the functional form. Note that, because the name of an anonymous class is unknown, coercion to an anonymous class can only be specified by the destination class: $someclass = generate_class(); $someclass($x); =head1 AUTHORS Larry Wall =for vim:set expandtab sw=4: