Re: More trees and roles
Em Sex, 2009-02-20 às 11:19 +1100, Timothy S. Nelson escreveu: if(! defined($footree.root)) { warn Unrooted tree; } There are some other very interesting possibilities: unless ($footree.can(root)) { warn Unrooted tree; } or even better unless ($footree ~~ RootedTree) { warn Unrooted tree; } or yet even better my RootedTree $footree = something() and it fails automatically... *That's* what Roles are for... daniel
Re: More trees and roles
HaloO, Daniel Ruoso wrote: Em Sex, 2009-02-20 às 11:19 +1100, Timothy S. Nelson escreveu: if(! defined($footree.root)) { warn Unrooted tree; } There are some other very interesting possibilities: unless ($footree.can(root)) { warn Unrooted tree; } or even better unless ($footree ~~ RootedTree) { warn Unrooted tree; } or yet even better my RootedTree $footree = something() and it fails automatically... *That's* what Roles are for... I strongly support that position! A rooted tree to me also implies the presence of parent nodes/trees. That is a RootedTree has two related methods .root and .parent in addition to the methods that Tree has. So we should even have 'RootedTree does Tree' so that algorithms that work with the Tree interface can work with a RootedTree doer. The approach with a .root attribute in the Tree role spoils that clean subtyping approach and forces users into definedness checks all over the place. A user that wants to convert the cleanly subtyped roles into the undefness can implement multi method root (Tree $self: ) { return undef; } multi method parent (Tree $self: ) { return undef; } in a class that composes the Tree role and go with definedness checks. But I seriously doubt the usefulness of this approach. I'm unsure if the method dispatcher still falls back to subs, but if it does one could make these methods to global subs and be done without a class. The presence of these subs is no problem for code that uses the clean role interface of Tree because it doesn't call them anyway. There is however one inconvenience with the subtype approach. A method .nodes of a RootedTree has to return the parent node as well to be compatible with the Tree semantics. That is if you want to traverse a RootedTree you have to explicitly skip the parent. But this can be easily remedied with a method with a different name. E.g. we could introduce .nodes in RootedTree and have a .trees method in Tree. From this we see that these two roles should be designed together. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: More trees and roles
On Fri, Feb 20, 2009 at 05:11:31PM +0100, TSa wrote: I'm unsure if the method dispatcher still falls back to subs, It doesn't do that anymore, as it happens. You mark methods with is export if you want that, and they automatically show up as both multis and methods in any lexical scope that uses the class in question. Or you write a sub that calls the corresponding method. But this all lexically scoped by default so that we retain compile-time knowledge of what language is currently defined, including multi definitions. To call a global/contextual sub you actually have to say something like: GLOBAL::globalsub() *globalsub() The core built-ins are imported into the CORE lexical scope, not into GLOBAL. CORE is the default setting (aka prelude) of the current compilation unit. Unlike languages which call it a prelude, we call it a setting because it's considered a lexical scope *outside* of the compilation unit (and because it can place things like loops around the compilation unit like the -p and -n switches do in Perl 5). Anyway, we're trying to maximize flexibility while also giving the compiler as much information as possible to feed the optimizer. So fallbacks are not in vogue these days. Larry