Re: Referencing a caller's slurpy array.
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 above, or do I need to be : defining another form of C 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 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 : [EMAIL PROTECTED]) returns Lazy Does that look about right? -- Rod Adams
Re: Referencing a caller's slurpy array.
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 above, or do I need to be : defining another form of C 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
Re: Referencing a caller's slurpy array.
Luke Palmer wrote: Rod Adams writes: In S29, I currently have C as: multi sub grep (Any|Junction $test : [EMAIL PROTECTED]) 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 above, or do I need to be defining another form of C that's more agreeable to autogeneration? If so, what makes a sub more agreeable to auto method generation? -- Rod Adams
Re: Referencing a caller's slurpy array.
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 as: > > multi sub grep (Any|Junction $test : [EMAIL PROTECTED]) 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
Re: Referencing a caller's slurpy array.
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 } In S29, I currently have C as: multi sub grep (Any|Junction $test : [EMAIL PROTECTED]) 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 : [EMAIL PROTECTED]) or multi sub grep (: Code +&test = &defaulttest , [EMAIL PROTECTED]) would make more sense than: multi sub grep (: Code *&test, [EMAIL PROTECTED]) At least to me it does. If you see some advantage to that way, please inform me of it. It might change C away from: multi sub map (Code $expression : [EMAIL PROTECTED]) returns List { gather { while @values { take $expression .( splice(@values, 0, $expression.arity) ); } } } -- Rod Adams
Re: Referencing a caller's slurpy array.
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
Re: Referencing a caller's slurpy array.
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
Re: Referencing a caller's slurpy array.
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 [EMAIL PROTECTED] = @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