Re: More fun with argument passing

2003-10-05 Thread Luke Palmer
Steve Fink writes:
> 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.

Which it now is.   Although, there are some internals issues, too, so I
wonder how we can do this.  How about, when someone responds to either
an -internals- or a -language-specific question, he directs it only to
the appropriate list.

> 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]).

Yep.

> 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?

This was described in A6.  It goes:

sub g([EMAIL PROTECTED] is context(Scalar)) {...}

> 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.

But constant ones :-)

> 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!'.

No, it should give an error.  Parameters are declared constant by
default.  You'd have to:

sub h ([EMAIL PROTECTED] is rw) { @params[1] = 'tuna!' }

How to make the distinction between a constant array and an array of
constants is still unclear to me.

> 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? 

Ouch.  Yeah, I guess so.  I don't expect to see C<[EMAIL PROTECTED] is rw> a
whole lot, but that is a bit of a pickle to implement.

> 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  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?)

Both.  (In parameter order, named-only must come after positionals)  So
f(1, 2, b => 1.5) was correct.

> 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 $blue was 'b', then j would get $b to be 'red'.  Run-time positionals
are another one of those things I don't expect to see all that often
(but that might be a different story in my code >:-).

The real problem arises in:

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

If $blue happens to be 'b'.  I think the behavior then would be $b gets
2, and %h gets { b => 'red' }.  In particular, I think it's wrong to
croak with an error here.

> 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 yo

Re: More fun with argument passing

2003-10-05 Thread Steve Fink
On Oct-05, Luke Palmer wrote:
> Steve Fink writes:
> > 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.
> 
> Which it now is.   Although, there are some internals issues, too, so I
> wonder how we can do this.  How about, when someone responds to either
> an -internals- or a -language-specific question, he directs it only to
> the appropriate list.

And I guess cross-post one last time when moving a piece from one list
to another?

> > 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?)
> 
> Both.  (In parameter order, named-only must come after positionals)  So
> f(1, 2, b => 1.5) was correct.

Huh? In argument order, clearly all the positionals precede the named.
But if 2 is bound to $c, then they are out of parameter order. Or does
that not bind 2 to $c? Are both 2 and 1.5 bound to $b (and resolved as
below)?

> > 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 $blue was 'b', then j would get $b to be 'red'.  Run-time positionals
> are another one of those things I don't expect to see all that often
> (but that might be a different story in my code >:-).

Sorry, that was an implementation question, not a language question.
>From the language-level, clearly the effect you want is for 1 to be
bound to $a and 'red' to be bound to either $b or %c{$blue}, depending
on whether $blue eq "b". The question is in what order the parameters
should be passed. Both work, but both cause problems.

> The real problem arises in:
> 
> j(1, 2, $blue => 'red')
> 
> If $blue happens to be 'b'.  I think the behavior then would be $b gets
> 2, and %h gets { b => 'red' }.  In particular, I think it's wrong to
> croak with an error here.

Larry had some discussion of this:

 However, it is erroneous to simultaneously bind a parameter both by
 position and by name. Perl may (but is not required to) give you a
 warning or error about this. If the problem is ignored, the
 positional parameter takes precedence, since the name collision might
 have come in by accident as a result of passing extra arguments
 intended for a different routine. Problems like this can arise when
 passing optional arguments to all the base classes of the current
 class, for instance. It's not yet clear how fail-soft we should be
 here.

Oh, and in discussing this, I'm wondering about one bit of vocabulary:
do you bind an argument to a parameter, a parameter to an argument, or
do you bind an argument and parameter together? E6 binds arguments to
parameters. What if you are binding multiple arguments to a single
parameter, as is the case with slurpy params?

It doesn't matter, really, but in my documentation and discussion I'd
like to be consistent, just because this stuff is already a ways
beyond my mental capacity and anything that simplifies things is
greatly appreciated!