develooper Front page | perl.perl6.language | Postings from March 2005

Re: MMD as an object.

Thread Previous | Thread Next
Rod Adams
March 11, 2005 04:56
Re: MMD as an object.
Message ID:
Leopold Toetsch wrote:

>Ok. If you'd really need such random dispatch, it could be done like
>this, when I interpret A12 correctly:
>  sub run_random_bar($x) {
>     my @meths = WALKMETH($x, :method('bar'));
>     my $meth = @meths[rand(@meths.elems)];
>     $meth($x);
>  }
>or even with
>  my sub bar($x) {...} # same body as above
>  bar($x);
>If you need an esoteric dispatcher roll your own :)
That's certainly the doable with any language that provides sufficient 
introspection, within limits. It's a matter of where you store your hand 
rolled dispatcher.

If I were to need a different policy for a given method .bar, I would 
likely create something called .bar much like your "run_random_bar", 
which then dispatches amongst methods I name something like ._bar .

I see some detractions to this approach:
1) Users wishing to add another multi to the mix must know that they 
have to make it a ._bar instead of a .bar. This is a relatively minor 
concern. It feels rather clumsy having two different names for what is 
essentially a single set of multis.

2) What parameter signature do you give the wrapper method, so it does 
not clobber the arguments, yet still has them to pass on to the 
appropriate method? And at the same time, determine what signature the 
wrapper was called with, to determine who to dispatch to... I hadn't 
said it before, but I had assumed the dispatch method of the MultiSub 
would have a signature of something like "Str @types" passed to it.

3) It does not allow more than one sub with the same signature and short 
name to be in scope at the same time. There are cases more legitimate 
than MMD::Random for this. For instance, dispatching based on return 
type. Or off of some user defined trait the different methods have. Or 
the most common case: on named arguments.

My understanding of the P6 Long Names is that if one creates a multi 
with the same parameter signature as a previously defined multi of same 
short name, it masks the previous one if in a tighter scope, or erases 
the previous if the same scope.

The original thought was to have the policy take over the acceptance of 
new multi's into the MultiSub as well as taking over dispatch, thus 
allowing for such flexibilities.

>>Since the main goal of treating multis as an object was to be able to
>>override the dispatch policy, I think how a user defined policy
>>interacts with different localities is very much on topic.
>I don't think that the policy should be in the MultiSub object.
I'm not sure if I think it should be there either. It just seemed to 
allow some flexibility in having it there that is otherwise very 
difficult to do.

And quite likely, the policy itself would not be in the MultiSub, but 
the MultiSub would have a reference to which policy it's using.

>Your approach would very likely disable all possible optimizations.
It's always been in the back of my head that this would be a performance 
hit. How big of one I don't have a good feel for. I've been attempting 
to get a feel for how much is gained in return for that hit. So far I am 
inclined to agree that the benefits do not outweigh the costs, but I 
like to know exactly what I'm giving up when making those decisions.

>>>1) is there a MultiSub object with one short name that holds all
>>>possible long names (and function references)?
>>As for whether such a thing is visible at the Perl level, I think that
>>depends on if we allow user defined dispatch policies or not. If not,
>>it's just an introspection tool that could be addressed in other ways.
>Don't think so. It's a problem of namespaces and how these multi subs
>are managed. It touches Perl6 as well as Parrot.
What I meant to say was that yes, there does need to be management and 
introspection capabilities at the Perl6 level, but they do not *require* 
it to be a MultiSub object to happen. Some non-object solution could 
likely be found.

With that mindset, the compiler could use a PMC object for it, but show 
the Language something else, or it could show the Language something 
that looks like an object, but use something different in Parrot. Those 
are questions I am not able to answer.

Some of the management issues I see that need addressing are:

- How do I dynamically create a new multi with differing levels of 
scope? For instance, add a package scoped multi from inside a sub of 
that package?

- If I'm in a lexical scope which overrides a certain long name, how can 
I call the package scoped version of that long name instead?

- Given a method returned from WALKMETH, what scope level is it defined at?

- Can I get a CODEREF that points to the short name as a whole, or do I 
have to take a ref to a given multi?

- How can I tell if a given long name already exists?

>>>What about multi subs? They can be defined everywhere. Given:
>>> multi sub *foo(A $a, B $b) {...}
>>>Is this something like:
>>> %globals{"foo"}  -->  MultiSub{"foo_A_B" => Sub, ...}
>>>What about a not so global multi:
>>> multi sub foo(A $a, B $b) {...}
>>This can be seen as questioning how to keep track of what multi's are in
>>scope at any given point in time, because you must dispatch amongst all
>>the multi's visible, regardless of the differing scope.
>Sure. But the dispatch scheme is described in A12. That is per se not
>the problem.
Unless your proposal was to allow user defined changing of that scheme. 
Then it becomes a problem.

-- Rod Adams

PS - I stopped the cross posting to p6i, since I was asking more 
questions than answering, and those question didn't belong there.

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About