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