On Wed, Nov 22, 2006 at 11:20:58PM +0100, Leopold Toetsch wrote:
> Am Mittwoch, 22. November 2006 21:03 schrieb Leopold Toetsch:
> > Am Mittwoch, 22. November 2006 18:03 schrieb Patrick R.Michaud:
> > > Is this a bug (I think it is), or does the underscore in
> > >
> > > :multi mean something other than "any argument"?
> >
> > The meaning is 'any PMC' [1], and it of course can't be a bug as there are
> > no specs ;)
> 
> Implementing '_' as 'any type' wouldn't be that hard. 

I'll take the position that implementing '_' as 'any type' is
the semantic we really want here.  We already have a way to
say 'any PMC':

    .sub foo :multi(pmc)

Here's a more detailed use case of why the current semantics
aren't useful.  For subroutine calls, PAST-pm tries to pass
constants directly to subroutines (when it can) rather than 
creating temporary PMCs and passing those.  For example, a HLL 
expression such as

    3 .op. 4

gets turned into PIR like

    $P0 = "infix:.op."(3, 4)

instead of

    $P0 = new .Integer
    assign $P0, 3
    $P1 = new .Integer
    assign $P0, 4
    $P2 = "infix:.op."($P0, $P1)

The present case I've run into is the Perl 6 "smart match"
operator (infix:~~), where the operation to be performed depends
on the types of the arguments.  For example, a pattern match
is defined as:

    .sub "infix:~~"  :multi(_, Sub)

For an expression such as $x ~~ /abc/, this works okay:

    find_lex $P0, '$x'             # get $x
    find_name $P1, 'abc_sub'       # get sub for /abc/
    $P2 = "infix:~~"($P0, $P1)     # call infix:~~

But for something like 'abc' ~~ /abc/, we end up with

    find_name $P1, 'abc_sub'       # get sub for /abc/
    $P2 = "infix:~~"('abc', $P1)   # call infix:~~

and it won't find the :multi(_, Sub) given above.  So far I've
only found two workarounds -- one is to convert all arguments
to PMCs before calling any sub (this is what PAST-pm is
doing now), the other is to create additional 
:multi(string|int|num, ...) subs that redispatch to the '_' 
version:

    .sub "infix:~~" :multi(int, Sub)
        .param pmc x
        .param pmc y
        .return "infix:~~"(x, y)
    .end

    .sub "infix:~~" :multi(string, Sub)
        .param pmc x
        .param pmc y
        .return "infix:~~"(x, y)
    .end

    # etc.

The first approach basically means we build a PMC for
every constant value, the second means that we end up
with three additional subs for every underscore in :multi.
And from a PIR-programmer perspective I don't see a lot
of downside to having '_' mean 'any value', but I can't
speak to the difficulty of implementing this in imcc.

Pm

Reply via email to