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

Argument Patterns

3 views
Skip to first unread message

Luke Palmer

unread,
Mar 8, 2005, 1:59:59 PM3/8/05
to Language List
All this Haskell programming has opened my eyes to what our multimethod
dispatch could be. As we have seen with C<sort>, the dispatch system is
a pattern matcher. But it's a pretty terrible one.

I think we should replace our multimethod system with a more general
pattern matcher, a "variadic multimethod" system of sorts. Multimethods
need to be variadic anyway, because we want pugs's quicksort example to
work.

Here's my proposal:

Inside an argument list, the first mention of a variable introduces its
binding. Later arguments require a match. We can now define 'equal':

sub equal ($x, $x) { 1 }
sub equal ($x, $y) { "" }

That's one of the MTOWs at least. The evaluation order of the patterns
still needs to be thought out.

There are more types of patterns. Types are patterns, and from this we
see that following a pattern by a variable binds the variable to
whatever matched that pattern. Constants are also patterns. Junctions
of patterns are also patterns. Lists of patterns are patterns, as are
hashes of patterns. In fact, the last two give us slurpy scalars:

sub length () { 0 }
sub length (*[ $x, *@rest ]) { 1 + length @rest }

And +$name parameters:

sub length (*{ name => $name }) { }

C<where> constrains a pattern:

sub factors ($x where { is_prime($x) }) { $x }
...

(The object in question is given as the topic of the where block:

sub factors ($x where { .is_prime }) { $x }
...

)

There will also be hooks to allow arbitrary pattern objects.

# does $x match our pattern?
method Pattern::MATCHES ($x) { ... }

And now here's the cool part. A type is defined to be a pattern (a
'class' is different, though, but it creates an identically-named type).
So instead of definining these multis (I seek to banish the 'multi'
keyword, since I seek to banish the idea of an invocant), you could also
pretend that they're methods on subtypes. A 'role' is just a collection
of methods on a type, a pattern:

role ($x where {.is_prime}) {
method factors() { $?SELF }
}

This is exactly equivalent to:

sub factors($x where {.is_prime}) { $x }

And of course, if you define a role with a name, then it becomes an
"abstract type":

role Serializable {
method serialize() {...}
method clone() { restore(.serialize) }
}

And you have to tell objects that they're Serializeable.

Luke

Rod Adams

unread,
Mar 8, 2005, 5:55:28 PM3/8/05
to Luke Palmer, Language List
Luke Palmer wrote:

>All this Haskell programming has opened my eyes to what our multimethod
>dispatch could be. As we have seen with C<sort>, the dispatch system is
>a pattern matcher. But it's a pretty terrible one.
>
>I think we should replace our multimethod system with a more general
>pattern matcher, a "variadic multimethod" system of sorts. Multimethods
>need to be variadic anyway, because we want pugs's quicksort example to
>work.
>
>Here's my proposal:
>
>Inside an argument list, the first mention of a variable introduces its
>binding. Later arguments require a match. We can now define 'equal':
>
> sub equal ($x, $x) { 1 }
> sub equal ($x, $y) { "" }
>
>That's one of the MTOWs at least. The evaluation order of the patterns
>still needs to be thought out.
>
>
>

I thought Larry already declared that we are not making Perl act like ML
(yet).

-- Rod Adams


Autrijus Tang

unread,
Mar 8, 2005, 11:16:27 PM3/8/05
to Rod Adams, Luke Palmer, Language List
On Tue, Mar 08, 2005 at 04:55:28PM -0600, Rod Adams wrote:
> I thought Larry already declared that we are not making Perl act like ML
> (yet).

And that was re: type inferencing, not re: pattern matching. :)

Thanks,
/Autrijus/

Rod Adams

unread,
Mar 8, 2005, 11:51:52 PM3/8/05
to Language List
Autrijus Tang wrote:

Sorry about that. Comcast has decided I only get internet connectivity
for a random 1 minute roughly every 1/2hr today, so I can't perform any
back searches. I'll make a more detailed response to the original post
shortly.

-- Rod Adams

Luke Palmer

unread,
Mar 9, 2005, 4:39:55 AM3/9/05
to Leopold Toetsch, perl6-l...@perl.org
Leopold Toetsch writes:

> Luke Palmer <lu...@luqui.org> wrote:
>
> > I think we should replace our multimethod system with a more general
> > pattern matcher, a "variadic multimethod" system of sorts. Multimethods
> > need to be variadic anyway, because we want pugs's quicksort example to
> > work.
>
> I'd not say replace. The dispatcher will very likely be a Parrot PMC.
> The default dispatcher dispatches on types, matching variadic signatures
> should be possible too.
>
> All infix operators are multi subs. I can't imagine that we want to pay
> the penalty for simple operations like:
>
> $a = $b + $c
>
> to inspect the values of operands, constraints, rules and what not.

Having written several multi dispatch systems, I know that this is easy
to optimize. If nobody has defined + on any fancy subtypes, then we can
quickly fall back to a bitset-intersection dispatch algorithm on the
types (or even, eew, direct lookup). If + has been defined on fancy
subtypes, then we compile the quickest way to figure out whether none of
the arguments are one of them, and fall back. This is a little tricky,
but some elementary graph theory gets us there.

Essentially, what dispatcher we're using for + depends on what kinds of
+s people have defined. That's how it should be; otherwise you'll get
people globally overriding + so they can stick their own dispatcher in
there, which isn't a portable solution.

But we always have enough knowledge to optimize the hell out of this,
and they're not not handwavy "we can probably" optimizations. They're
real, and they're pretty darn easy.

Luke

Leopold Toetsch

unread,
Mar 9, 2005, 3:33:26 AM3/9/05
to Luke Palmer, perl6-l...@perl.org
Luke Palmer <lu...@luqui.org> wrote:

> I think we should replace our multimethod system with a more general
> pattern matcher, a "variadic multimethod" system of sorts. Multimethods
> need to be variadic anyway, because we want pugs's quicksort example to
> work.

I'd not say replace. The dispatcher will very likely be a Parrot PMC.


The default dispatcher dispatches on types, matching variadic signatures
should be possible too.

All infix operators are multi subs. I can't imagine that we want to pay
the penalty for simple operations like:

$a = $b + $c

to inspect the values of operands, constraints, rules and what not.

[ dispatching on rules ]

If the involved types need a more fancy dispatcher, their meta-class
should say so.

> Luke

leo

Thomas Sandlaß

unread,
Mar 9, 2005, 4:58:22 AM3/9/05
to perl6-l...@perl.org
Luke Palmer wrote:
> But we always have enough knowledge to optimize the hell out of this,
> and they're not not handwavy "we can probably" optimizations. They're
> real, and they're pretty darn easy.

I fully agree. But I like to add that a single 'where' on general
types like Int, Str or even Any can seriously harm performance
because than the dispatcher has to check it always and everywhere!
So the Perl 6 type system let's you have your rope and tie yourself.
Well, that is late binding :)
--
TSa (Thomas Sandlaß)


Luke Palmer

unread,
Mar 9, 2005, 5:17:07 AM3/9/05
to Thomas Sandlaß, perl6-l...@perl.org

Only if you define an AUTOLOAD on your subtypes. The way to think about
multimethod implementation problems is inside-out from how you think
about single dispatch. The *method* is the one that knows everything,
not the object. So definitions on subtypes of general types only check
for those subtypes when dispatching to the methods defined in them.

Luke

Thomas Sandlaß

unread,
Mar 9, 2005, 6:07:23 AM3/9/05
to Luke Palmer, perl6-l...@perl.org
HaloO Luke,

you wrote:
> [..] The *method* is the one that knows everything,


> not the object. So definitions on subtypes of general types only check
> for those subtypes when dispatching to the methods defined in them.

I stand corrected. Lax usage of Any is fair. Defining subtypes
of general types and using them to constrain e.g. params of subs
is fine, too. But defining a multi branch on a very common operator
like +, * or grep for a predicate---i.e. using where---subtype
is penalized. Sounds reasonable to me.

MfG
--
TSa (Thomas Sandlaß)


0 new messages