Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

This week's summary

6 views
Skip to first unread message

Adam Turoff

unread,
Jun 9, 2003, 10:13:49 AM6/9/03
to perl6-l...@perl.org
On Mon, Jun 09, 2003 at 01:26:22PM +0100, Piers Cawley wrote:
> Multimethod dispatch?
> Adam Turoff asked if multimethod dispatch (MMD) was really *the* Right
> Thing (it's definitely *a* Right Thing) and suggested that it would be
> more Perlish to allow the programmer to override the dispatcher,
> allowing for all sorts of more or less cunning dispatch mechanisms
> (which isn't to say we could still have MMD tightly integrated, but it
> wouldn't be the *only* alternative to simple single dispatch). Luke
> Palmer gets the "Pointy End Grandma" award for pointing out that Perl 6
> is a '"real" programming language now' (as Adam pointed out, Perl's been
> a 'real' programming language for years), inspiring a particularly pithy
> bit of Cozeny. As far as I can tell, Adam wants to be able to dispatch
> on the runtime value of a parameter as well as on its runtime type (he's
> not alone in this). Right now you either have to do this explicitly in
> the body of the subroutine, or work out the correct macromantic
> incantations needed to allow the programmer to use 'nice' syntax for
> specifying such dispatch.
>
> Assuming I'm not misunderstanding what Adam is after, this has come up
> before (I think I asked about value based dispatch a few months back)
> and I can't remember if the decision was that MMD didn't extend to
> dispatching based on value, or if that decision hasn't been taken yet.
> If it's not been taken, I still want to be able to do
>
> multi factorial (0) { 1 }
> multi factorial ($n) { $n * factorial($n - 1) }

That's pretty much correct.

I've been musing on dispatching over the last week, and I've come
up with a few scenarios:
- pure type-based (match a method's signature, modulo superclasses)
- pure value-based (scalars with specific values)
- mixed-mode (RightMouseClick class, with 'control' modifier set/unset)
- pre-/post- methods; chains of pre-/post- methods
- AOP-style pre-/post- methods that can come and go at runtime
- Eiffel-style contract checking/enforcement
- roll-your-own inheritance mechanisms (see NEXT.pm)

I've also considered "side-effect based dispatching" for lack of a better
term: Consider an object with a whole gaggle of methods that need to check
whether the database is up before continuing. All of them fail similarly
with a "database is down" error. Why *not* factor that out into a
different set of multimethods that execute only when the database is down?
Now consider what happens if the database handles are not parameters to
each method call, but slots in the object or stored globally...

There are a few other, admittedly weird scenarios where this kind of
behavior would be desirable. All of them exhibit an AOP-ish quality.


Anyway, as Piers summarized, my concern is that if there's only two types
of dispatching, it may be artificially limiting. I'm guessing that if I
can think of three dispatching behaviors, then there may be five, and if
there really are five then there just might be as many as ten or more.
Therefore the simple dispatch/type-based MMD dispatch duality limits more
than it empowers.

I don't think this is really a problem to be solved in the domain of
macro expansion or syntactic warpage. Writing classes to handle these
rules feels like the way to go. Whether or not MMD as it's been sketched
is hardwired into the language (e.g. for performance) is less important to
me than the ability to plug in different (levels of) dispatching behaviors.

Z.

Sean O'Rourke

unread,
Jun 9, 2003, 10:47:56 AM6/9/03
to Adam Turoff, perl6-l...@perl.org
On Mon, 9 Jun 2003, Adam Turoff wrote:
> - roll-your-own inheritance mechanisms (see NEXT.pm)

On a related note, you might also want to take a look at CLOS (the Common
Lisp Object System) where it talks about method selection. They've got a
pretty clear and general model that describes every imaginable (and
unimaginable) thing you'd want to do with dispatch. It's broken into 3
steps, any one of which you can customize:

- find all applicable methods
- sort them in order of specificity
- apply some kind of combining operation to this list (e.g. select 1st)

Granted, this is hardly efficient, and from what I've seen you need to
be careful in how you use MMD to get decent performance in Lisp. But it's
still helpful in laying out the design space.

/s

Mark A. Biggar

unread,
Jun 9, 2003, 12:19:47 PM6/9/03
to perl6-l...@perl.org

On Mon, Jun 09, 2003 at 01:26:22PM +0100, Piers Cawley wrote:

> Multimethod dispatch?

> Assuming I'm not misunderstanding what Adam is after, this has come up


> before (I think I asked about value based dispatch a few months back)
> and I can't remember if the decision was that MMD didn't extend to
> dispatching based on value, or if that decision hasn't been taken yet.
> If it's not been taken, I still want to be able to do
>
> multi factorial (0) { 1 }
> multi factorial ($n) { $n * factorial($n - 1) }

That's a bad example, as it's really not MMD. It's a partially
pre-memoized function instead.

Which brings up a issue. Is it really MMD if you're only dispatching on
a single invocant? Most of the examples I've seen for MMD so far use
only a single invocant and are really either regular dispatch or simple
overloading instead. MMD only becomes really interesting if you
have multiple invocants possibly with best-match signature matching
involved.

--
ma...@biggar.org
mark.a...@attbi.com

Michael Lazzaro

unread,
Jun 9, 2003, 1:15:37 PM6/9/03
to Piers Cawley, Adam Turoff, perl6-l...@perl.org

On Monday, June 9, 2003, at 07:13 AM, Adam Turoff wrote:
> On Mon, Jun 09, 2003 at 01:26:22PM +0100, Piers Cawley wrote:
>> Assuming I'm not misunderstanding what Adam is after, this has
>> come up
>> before (I think I asked about value based dispatch a few months
>> back)
>> and I can't remember if the decision was that MMD didn't extend to
>> dispatching based on value, or if that decision hasn't been taken
>> yet.
>> If it's not been taken, I still want to be able to do
>>
>> multi factorial (0) { 1 }
>> multi factorial ($n) { $n * factorial($n - 1) }


The most recent semi-official opinion given onlist, AFAIK, was from
Damian on 3/13/03:


On Thursday, March 13, 2003, at 06:15 PM, Damian Conway wrote:
> Piers Cawley wrote:
>> Speaking of multis and constants, Greg McCarroll wondered on IRC if
>> this would work:
>> multi factorial (Int 0) { 1 }
>> multi factorial (Int $n) { $n * factorial($n-1) }
>
> Probably not. We did discuss whether multimethods should be able to be
> overloaded by value, but concluded (for that week, at least ;-) that
> this might prove syntactically excessive.

See the rest of his message for a marginally scary workaround.

MikeL

Michael Lazzaro

unread,
Jun 9, 2003, 2:18:51 PM6/9/03
to Mark A. Biggar, perl6-l...@perl.org

On Monday, June 9, 2003, at 09:19 AM, Mark A. Biggar wrote:
> On Mon, Jun 09, 2003 at 01:26:22PM +0100, Piers Cawley wrote:
>> multi factorial (0) { 1 }
>> multi factorial ($n) { $n * factorial($n - 1) }
>
> That's a bad example, as it's really not MMD. It's a partially
> pre-memoized function instead.

It's MMD if you think of the number 0 as being a "subclass" of C<int>
or C<num>. In other words, you have an C<num> class, and then a
subclass of C<num> that binds the value to always be zero.

In a not-too-twisted fashion, you can think of any constant as being a
"subclass" of its base type, overridden to store exactly one possible
value. It's like instance-based (classless) inheritance, which we
haven't discussed much, but which I hope we eventually get to, because
it's bloody useful... Sigh...


> Which brings up a issue. Is it really MMD if you're only dispatching
> on
> a single invocant? Most of the examples I've seen for MMD so far use
> only a single invocant and are really either regular dispatch or simple
> overloading instead. MMD only becomes really interesting if you
> have multiple invocants possibly with best-match signature matching
> involved.

I think it's a matter of semantics: a single-invocant routine is still
a "multi", and still semantically MMD, because it uses the same
internal dispatcher as an N-invocant one, and checks the same list of
possible variants. So you can have:

multi bar (Baz $b : ...); # one invocant
multi bar (Foo $f : ...); # one invocant, but different!
multi bar (Foo $f, Baz $b : ...); # two invocants

All three of those are multimethod variants of a routine named C<bar>.
The MMD mechanism has to determine which of those three variants to
use, based on the invocant(s) -- of which there may be one, or several,
for any given call to C<bar>. Even if there only happens to be one
invocant, it's still the same dispatcher, sifting through the same
possible variants.


The single-invocant C<multi> thing I still find confusing at this point
is that, for example, you can't actually have C<multi><method>s! That
is, you can't do this:

class Foo {
method bar (int $i);
method bar (str $s); # ERROR
method bar (str $s1, str $s2);
}

You'd have to do this:

class Foo {
multi bar (Foo $self, int $i : ); # semicolon optional
multi bar (Foo $self, str $s : );
multi bar (Foo $self, str $s1, str $s2 : );
}

Which, internally, makes some sense -- they have to go to a more
complicated dispatcher than normal methods -- but is semantically icky,
IMO, and I hope/wish we could find a better way of expressing that.
Perhaps E6 will help.

MikeL

Dave Whipp

unread,
Jun 9, 2003, 6:45:46 PM6/9/03
to perl6-l...@perl.org
"Michael Lazzaro" <mlaz...@cognitivity.com> wrote

> multi bar (Foo $self, int $i : ); # semicolon optional

<pedantic>
I think you meant "colon optional". The semi-colon is, I think, a syntax
error. You need the yada-yada-yada thing: "{...}".
</pedantic>

But I agree with the main point you were wanting to make: a class-based
multimethod really should make the primary invocant ($self) implicit -- if
doing so doesn't make things even more confusing/ambiguous/nasty.

Dave.


Michael Lazzaro

unread,
Jun 9, 2003, 7:39:34 PM6/9/03
to Dave Whipp, perl6-l...@perl.org

On Monday, June 9, 2003, at 03:45 PM, Dave Whipp wrote:
> "Michael Lazzaro" <mlaz...@cognitivity.com> wrote
>> multi bar (Foo $self, int $i : ); # semicolon optional
>
> <pedantic>
> I think you meant "colon optional". The semi-colon is, I think, a
> syntax
> error. You need the yada-yada-yada thing: "{...}".
> </pedantic>

Sigh. Yes, thank you. This, not that:

multi bar (Foo $self, int $i : ) {...} # colon optional

It's been a bad day. :-/

MikeL

0 new messages