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

Referencing a caller's slurpy array.

11 views
Skip to first unread message

Rod Adams

unread,
Mar 15, 2005, 2:54:09 AM3/15/05
to Perl6 Language List
A06 says:

If you |shift| or |pop| without an argument, it shifts or pops whatever
slurpy array is in scope.


Shall we assume that @_ is always an alias for this array, so I can say
something like:

multi sub pop (Array ?@array = @caller::_) returns Scalar

?

btw, is ?@ legal in a signature? It's not specifically mentioned in
A/S04, but it makes sense it would be allowed along with ?%.

-- Rod Adams

Larry Wall

unread,
Mar 16, 2005, 1:01:12 PM3/16/05
to Perl6 Language List
On Tue, Mar 15, 2005 at 01:54:09AM -0600, Rod Adams wrote:
: A06 says:
:
: If you |shift| or |pop| without an argument, it shifts or pops whatever
: slurpy array is in scope.
:
:
: Shall we assume that @_ is always an alias for this array, so I can say
: something like:
:
: multi sub pop (Array ?@array = @caller::_) returns Scalar
:
: ?

Well, the alternative would be to have an explicit compiler variable like
@?SLURPY, but maybe using @_ for that is more parsimonious.

: btw, is ?@ legal in a signature? It's not specifically mentioned in

: A/S04, but it makes sense it would be allowed along with ?%.

Certainly. The zone markers are as orthogonal to sigils as we can
make 'em. Though I'm not sure we've given a meaning to *&foo yet.
I suppose that would have to mean that the next slurpy parameter has
to be a sub ref.

Larry

Larry Wall

unread,
Mar 16, 2005, 1:55:18 PM3/16/05
to Perl6 Language List
On Wed, Mar 16, 2005 at 11:53:43AM -0700, Luke Palmer wrote:
: Larry Wall writes:
: > Certainly. The zone markers are as orthogonal to sigils as we can

: > make 'em. Though I'm not sure we've given a meaning to *&foo yet.
: > I suppose that would have to mean that the next slurpy parameter has
: > to be a sub ref.
:
: Uhmm... isn't *&foo the adverbial block? That is, isn't it where grep
: gets its code block in:
:
: @list.grep:{ $_ % 2 }

Maybe it can mean either of those things without conflict, as long
as you don't try to make it mean both. :{...} is just short for a
named parameter that happens to bind to the *&foo looking parameter,
but as with ordinary list operators, they can be passed positionally
as well as by name.

But yes, to be perfectly frank, I'd forgotten about that. Doubtless
a sign of premature senility.

Larry

Luke Palmer

unread,
Mar 16, 2005, 1:53:43 PM3/16/05
to Perl6 Language List
Larry Wall writes:
> Certainly. The zone markers are as orthogonal to sigils as we can
> make 'em. Though I'm not sure we've given a meaning to *&foo yet.
> I suppose that would have to mean that the next slurpy parameter has
> to be a sub ref.

Uhmm... isn't *&foo the adverbial block? That is, isn't it where grep


gets its code block in:

@list.grep:{ $_ % 2 }

Luke

Rod Adams

unread,
Mar 16, 2005, 2:22:02 PM3/16/05
to Perl6 Language List
Luke Palmer wrote:

In S29, I currently have C<grep> as:

multi sub grep (Any|Junction $test : *@values) returns List {
gather {
for @values -> $x {
take $x if $x ~~ $test;
}
}
}


If you wish to supply a closure for C<$test>, you're free to do so.


If I were building it to accept just a closure, I would think:

multi sub grep (Code &test : *@values)

or

multi sub grep (: Code +&test = &defaulttest , *@values)


would make more sense than:

multi sub grep (: Code *&test, *@values)


At least to me it does. If you see some advantage to that way, please
inform me of it. It might change C<map> away from:

multi sub map (Code $expression : *@values) returns List {
gather {
while @values {
take $expression
.( splice(@values, 0, $expression.arity) );
}
}
}


-- Rod Adams

Luke Palmer

unread,
Mar 16, 2005, 6:55:05 PM3/16/05
to Rod Adams, Perl6 Language List
Rod Adams writes:
> >Uhmm... isn't *&foo the adverbial block? That is, isn't it where grep
> >gets its code block in:
> >
> > @list.grep:{ $_ % 2 }
> >
> >
> >
> In S29, I currently have C<grep> as:
>
> multi sub grep (Any|Junction $test : *@values) returns List {
> gather {
> for @values -> $x {
> take $x if $x ~~ $test;
> }
> }
> }

That's the listop form. I was referring to the method form:

multi sub grep (@array: *&code) returns List {
...
}

The fact that there is a conflict in context in the argument points out
one of the weaknesses of the current multi declaraition semantics.
Currently, it would just default to list context.

I think the *compiler* should be able to tell the difference between the
two forms without having to go to runtime method dispatch (perhaps it
still does dispatch, but if you're in the latter form, you don't even
try to dispatch to the former routine). But that's a big brainstorm
that needs to happen, and I'm not prepared to do that right now.

Luke

Rod Adams

unread,
Mar 17, 2005, 12:49:12 AM3/17/05
to Perl6 Language List
Luke Palmer wrote:

>Rod Adams writes:
>
>
>>In S29, I currently have C<grep> as:
>>
>>multi sub grep (Any|Junction $test : *@values) returns List {
>> gather {
>> for @values -> $x {
>> take $x if $x ~~ $test;
>> }
>> }
>>}
>>
>>
>
>That's the listop form. I was referring to the method form:
>
> multi sub grep (@array: *&code) returns List {
> ...
> }
>
>

Got it. I'll be adding that form to various functions shortly.

Could I please get a list of what forms I need to be defining in S29?

Right now I have:
- General non-OO form.
- adverbial code block form (where applicable).


I haven't gotten a solid answer on when and how Perl will autogenerate
methods from subs.

For instance, would

@array.grep(/foo/);

generate a call to the list op C<grep> above, or do I need to be
defining another form of C<grep> that's more agreeable to
autogeneration? If so, what makes a sub more agreeable to auto method
generation?

-- Rod Adams

Larry Wall

unread,
Mar 17, 2005, 3:29:38 AM3/17/05
to Perl6 Language List
On Wed, Mar 16, 2005 at 11:49:12PM -0600, Rod Adams wrote:
: I haven't gotten a solid answer on when and how Perl will autogenerate
: methods from subs.

In general I don't think of it as autogeneration at all, but as
failover to a different dispatcher. I can't think of a case where an
ordinary sub implies an ordinary method or an ordinary method implies
an ordinary sub. Multi subs can live in both worlds simultaneously
when they're defined within a class, but in that case it's a single
definition that is visible to both dispatchers. There may end up being
some hanky-panky of an autogeneration nature going on to optimize the
more common failover cases, and we've cut ourselves a little slack in
how we handle single argument functions and/or argumentless methods,
but by and large we should just be able to get away with a single
MMD definition for most purposes, and separate definitions where the
valence actually changes.

: For instance, would


:
: @array.grep(/foo/);
:
: generate a call to the list op C<grep> above, or do I need to be
: defining another form of C<grep> that's more agreeable to
: autogeneration? If so, what makes a sub more agreeable to auto method
: generation?

Well, grep is one of those cases where you really need two different
definitions because you have conflicting invocants. If within the
Array class you write a multi sub like this:

multi sub grep (Array @array, Selector $for) {...}

then it can be called either as @array.grep(/foo/) or
grep(@array,/foo/), but never as grep(/foo/,@array).

At least, not unless we install some mechanism like active/passive
voice into Perl, in which case the passive voice could be autogenerated
from the active voice, albeit with a modified verb. But for now
I think two definitions are appropriate, with some thought about
bifurcating the verb into "do to" and "done by" variants if there's
likely to be MMD confusion. The .grep variant should probably just
be an ordinary method rather than a "squinting" multi method to avoid
confusion with the standard listop form.

If we find ourselves with double declarations all over the place, then
maybe we can look for some autogeneration relief.

Larry

Rod Adams

unread,
Mar 20, 2005, 6:36:13 PM3/20/05
to Perl6 Language List
Larry Wall wrote:

>On Wed, Mar 16, 2005 at 11:49:12PM -0600, Rod Adams wrote:
>: I haven't gotten a solid answer on when and how Perl will autogenerate
>: methods from subs.
>
>In general I don't think of it as autogeneration at all, but as
>failover to a different dispatcher. I can't think of a case where an
>ordinary sub implies an ordinary method or an ordinary method implies
>an ordinary sub. Multi subs can live in both worlds simultaneously
>when they're defined within a class, but in that case it's a single
>definition that is visible to both dispatchers. There may end up being
>some hanky-panky of an autogeneration nature going on to optimize the
>more common failover cases, and we've cut ourselves a little slack in
>how we handle single argument functions and/or argumentless methods,
>but by and large we should just be able to get away with a single
>MMD definition for most purposes, and separate definitions where the
>valence actually changes.
>
>

Okay, I'm now in the process of going through what I'd written of S29 to
take this into account.

First up was

multi sub abs (: Num ?$x = $CALLER::_ ) returns Num

Which I presently have in Math::Basic.
I could easily see someone wanting to do

my Num $x = -12.4;
$x.=abs;

Which would suggest I need to add something that looks like:

multi sub Num::abs (Num $x) returns Num

Which I think means that I have two write a method version for every
function that takes a $_ default, since the optional parameter happens
after the colon, and therefore isn't part of the invocant. I'm fine
with writing them double, I just want to be sure it's necessary.

>: For instance, would
>:
>: @array.grep(/foo/);
>:
>: generate a call to the list op C<grep> above, or do I need to be
>: defining another form of C<grep> that's more agreeable to
>: autogeneration? If so, what makes a sub more agreeable to auto method
>: generation?
>
>Well, grep is one of those cases where you really need two different
>definitions because you have conflicting invocants. If within the
>Array class you write a multi sub like this:
>
> multi sub grep (Array @array, Selector $for) {...}
>
>then it can be called either as @array.grep(/foo/) or
>grep(@array,/foo/), but never as grep(/foo/,@array).
>
>

For C<grep> I now have:

multi sub Perl6::Array::grep (@values : Code *&test) returns Lazy

multi sub Perl6::Array::grep (@values, Any|Junction $test) returns Lazy

multi sub Perl6::Lists::grep (Any|Junction $test : *@values) returns Lazy

Does that look about right?

-- Rod Adams

0 new messages