On 2009-Oct-16, at 12:54 am, Richard Hainsworth wrote:
Is there syntactic sugar for aliasing the conflicting method? Eg.
something like
does XML :db-write<xml-db-write>;
There needs to be something more than sugar: making a new class or
role with different methods will break substitutability. However, we
could have a feature which aliases a method name in a given scope or
context; elsewhere, the original name would still be visible. So you
could pass your new XML-plus-SQL object to do-xml-stuff(XML $x) and it
would know to treat it as an XML object with the proper .db-write
method.
(Incidentally, we could use something similar for renaming imported
symbols, though in that case it would be only sugar. Currently, we
can choose to import something or not, but if a module exports
something, it presumably has a good reason; rather than simply not
importing the sub/etc., it would be handy to be able to import it
under another name.
use Bar <foo>; # import Bar::foo
use Baz :foo<boo>; # import Baz::foo as boo()
use Baz foo=>'boo'; # or spelled this way
)
Moreover, suppose that the two modules have roles with the same
name, eg., suppose XML-Database-Module and SQL-Database both define
a role 'Writable'. How could these one (or both) of these roles be
aliased?
I suppose the polite thing would be for them to define roles (or
anything else) inside their own namespaces: XML-Database-
Module::Writable.
Meanwhile, on 2009-Oct-14, at 7:58 pm, Jon Lang wrote:
Another clarification: there's a subtle but important difference
between "$dogwood.bark:(Dog:).()" and "$dogwood.Dog::bark()". The
former calls a Dogwood method that has an invocant that does Dog;
the latter calls a Dog method. That is:
$dogwood.bark:(Dog:).(); # calls &Dogwood::bark:(Dog:)
$dogwood.Dog::bark(); # calls &Dog::bark:()
Aha, so the bark:(Dog:) syntax identifies the method by its signature
as well, thus distinguishing it from the .bark:(Tree:) method. This
works fine when the sigs can distinguish the invocants, which is very
common. However, I could have ambiguous methods even including the
signatures. Suppose I have a Logging role that provides a log()
method for printing some info about a variable. In particular, I have
method log(Numeric $x:) { ... } because I want to handle Nums
specially (say, round them off before printing). Meanwhile, suppose I
also have Math::log(Numeric $x:).
If $x does Numeric and does Logging, then $x.log won't be able to
decide which method to call, unless maybe it's in a sub like
foo(Numeric $x) that can know to provide "Numeric" context to $x.
Outside foo, or inside a sub like bar(Any $x), I need some other way
to indicate which "log" method I mean. $x.log:(Numeric:) won't work
here, because both roles provide a method with that name and signature.
What if all roles' methods got automatic aliases, to a long(er) name,
e.g. the .log method could be referred to as such, or
as .Logging`log()? That at least would provide a fully-qualified way
to refer to methods no matter where they came from originally, and
also allow short names to be used where unambiguous.
(I guess this parallels what we already have for subs, etc., except
methods would be automatically "exported" into new roles or classes so
that we can use short names. I don't know what the actual syntax
should be -- I only used ` above for lack of anything better, since
the obvious .Logging::log means something else.)
-David