Ok, I'm back to argument passing. I'm starting a new thread because
I'm lazy and I have to scroll back too far in my mailer to see the old
arg passing thread. :-) And yes, most of this message should also be
on -languages.

Could somebody tell me where I go wrong:

If you have a prototype
  sub f ($a, $b, $c) { ... }
then you should pass $a in P5, $b in P6, etc. So the code will look
like:
 .param $a
 .param $b
 .param $c

If you declare a sub without a prototype, it should default to ([EMAIL PROTECTED]).

A slurpy array parameter puts its corresponding arguments in a list
context, which is the same as a flattening context. This is stated in
E6 and S6, though not in A6 as I read it (but it doesn't disagree
either.)

Let's add a prototype-less sub for use in discussion:
  sub g { ... }

Is there any way to create a prototype that, when called with any
number of array variables, would pass all of the arrays as objects?
So, for example, f(@x, @y, @z) would do the right thing for exactly
three arrays, but couldn't handle f(@x,@y,@z,@w). g(@x, @y, @z) seems
to flatten all of them together. I'm sure something like
g([EMAIL PROTECTED],[EMAIL PROTECTED],[EMAIL PROTECTED]) would work, but what if I 
want to do the call without
backslashes?

The calls f(1, 2, 3) and g(1, 2, 3) should both generate
  .arg 1
  .arg 2
  .arg 3
...except instead of constant ints, you'd probably need PMCs.

Splatted array params are aliases to the actual args. So

  sub h ([EMAIL PROTECTED]) { @params[1] = 'tuna!'; }
  h($x, $y, $z);

should set $y to 'tuna!'.

Would h(@x) set @x[1] to 'tuna!'? If so, then does

  h(@x, $y)

change $y's value depending on the number of elements in @x? It seems
that @params is either a magical array where lookups trigger a runtime
computation of where that index would be found in the original
argument list, or it is an array of references to either variables or
<variable,key> pairs, and all of those references are built at runtime
immediately when the call is made. (Which rather defeats the default
laziness of arrays.) Actually, "proxies" might be a more accurate
term. You should be able to pass @params into another function just
like any other array, or do

  $gloof = (rand(100) < 30) ? @params : @normal_array;

Or maybe h(@x) does NOT set @x[1] to 'tuna!'?

Ok, the whole aliasing thing was something of a tangent. Back to f()
and h(), which are really f($,$,$) and h(*@).

I can use names to pass required arguments, but all positional args
must precede all named args. So then is this legal:

 f(1, 2, b => 1.5)

or must all of the positional args referred to by named parameters
follow those passed positionally? (There are two orders -- argument
order and parameter order. In which of those two must all positionals
precede the named params?)

In

 sub j($a, ?$b, *%c) { ... }

can I actually pass %c after the rest of the params? If I call it with

 j(1, $blue => 'red')

then does that compile down to

 .param 1
 .param named_arg_table

? How is the callee supposed to know whether the 2nd param is $b or
%c? What if $blue happened to be "b"?

If I do it the other way around,

 .param named_arg_table
 .param 1

then at least I can always assume the named args are passed first, and
use the arg count to directly determine whether $b was passed or not.
But then all Perl6 subroutines would have to take a named arg table as
their first argument, by convention, and cross-language calls would
need to be aware of this -- even when calling unprototyped. ("Oh,
yeah, if you're calling a Perl6 routine you have to pass an empty
hashtable as the first param.")

I have a first cut at Perl6 parameter passing. It doesn't do runtime
context, the named params are in there but I assume they don't work,
and it reflects my earlier misconception that a [EMAIL PROTECTED] array should
NOT flatten its arguments. Or, in other words, I compile

  sub g { ... }
  g(10,20,30)

down to

  $P0[0] = 10
  $P0[1] = 20
  $P0[2] = 30
  .arg (empty hash)
  .arg $P0

and
  
  sub f ($a, $b, $c) { ... }
  f(10,20,30)

down to

  .arg (empty hash)
  .arg 10
  .arg 20
  .arg 30

which means that if you call f($a,$b,$c) without its prototype, then
it compiles to the former code which results in $a getting 3 (the
length of the @_ array), while $b and $c get bad values that seg fault
parrot.

I'm hesitating to manually pull all of the [EMAIL PROTECTED] elements out of
P5..P15 + P3[0..] until someone makes me a little more confident that
it's the right thing to do. And even then, perhaps it should be
handled by some kind of .flattened_param declaration. But neither
would handle the magical aliasing I talked about above, if that is
required. And it's also slowing down the callee in what could easily
be a common case.

The patch for this is mixed in with some other stuff I've been working
on, but the relevant part is more or less

 Addcontext.pm   |  137 +++++++++++++++++-
 Builtins.pm     |  411 ++++++++++++++++++++++++++++++--------------------------
 Context.pm      |   40 +++++
 IMCC.pm         |  377 +++++++++++++++++++++++++++++++++++++++++++--------
 IMCC/Binop.pm   |   92 ++++++++++++
 IMCC/prefix.pm  |  244 ++++++++++++++++++++++++++-------
 Nodes.pm        |   64 ++++++++
 Parser.pm       |   35 +++-
 TestCompiler.pm |    6 
 Tree.pm         |   96 ++++++++++++-
 Util.pm         |    3 

and my changes are a complete mess. I've gone back and forth many
times trying to figure out the correct scheme to handle some
percentage of the Perl6 wackiness, and it would probably still take
major revision to do runtime context, or even be useful for parsing
unparenthesized function calls.

Reply via email to