Re: More trees and roles

2009-02-20 Thread Daniel Ruoso
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

2009-02-20 Thread TSa

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

2009-02-20 Thread Larry Wall
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