Categories

Posts in this category

Thu, 12 Aug 2010

What is the "Cool" class in Perl 6?


Permanent link

In Perl, subroutine and operator names determine what happens, usually not the type of the arguments. Instead the arguments are coerced to a type on which the operation makes sense:

say uc 34;      # coerces 34 to a string, and upper-cases it
say 1 + "2";    # converts "2" to a number before adding

To make things more extensible, the uc function re-dispatches to the uc method on its argument. So for the example above to work, we need an uc function in Int. And in Array, so that @a.uc works. And so on.

The original approach was to stuff all these methods into Any, the base class of the object hierarchy. Which kinda worked, but also meant that all user-defined classes ended up having some few hundreds methods to start with. Not good.

These days, the type Cool fills this niche: most built-in types (all that are meant to be used in that polymorphic way) inherit from Cool, so the uc method is actually defined in class Cool, coerces to string, and then re-dispatches to the internal logic that actually does the upper-casing.

The name either stands for Convenient object oriented loopback, or just expresses that that most built-ins are cool with an argument of that type.

If users want to write a type that can be used like a built-in type now just inherit from Cool, and define coercion methods to other built-in types. If the types don't inherit from Cool, they are more light-weight, and less magic. There's more than one way to do it.

Cool is a class (and not a role), because classes are mutable; so if you want to inject behavior into nearly all built-in types, augmenting Cool is an option (though usually considered evil, and should not be done lightly).

[/perl-6] Permanent link

Comments / Trackbacks:

Trackback URL: /blog-en/perl-6/cool.trackback

Passerby wrote

Injecting behavior into built-ins
"Cool is a class (and not a role), because classes are mutable; so if you want to inject behavior into nearly all built-in types, augmenting Cool is an option (though usually considered evil, and should not be done lightly)." That's pretty fascinating. Would this be in the same vein as adding functions to Javascript's Object prototype? I've seen a lot of great things done with that in Javascript, but then, that language typically isn't used to build anything big. (So action-at-a-distance is never a consideration.) Can you expand more upon the idea of injecting behavior into built-ins?

Moritz wrote

Injecting into built-ins
One possible example would be to add a .pretty method, that pretty-prints an object, and defaults to .perl (which produces output similar to Data::Dumper in Perl 5). This might look like

use MONKEY_TYPING;
augment class Cool {
method pretty { self.perl() }
}
# override some more specific methods
augment class Cool {
method pretty {
# a nice method here...
}
}

that way most built-in types have a .pretty method, and you could add custom methods along the way.

All in all it's still a very fragile idea, because it might interact badly with similar extensions from other modules.

Write a comment

The comments on this blog post have been disabled; the comment form below will not work.

 
Name:
URL: [http://www.example.com/] (optional)
Title: (optional)
Comments:
Save my Name and URL/Email for next time