On Wed, Feb 20, 2013 at 4:46 PM, Aristotle Pagaltzis <pagaltzis@gmx.de> wrote: > * Ruslan Zakirov <ruz@bestpractical.com> [2013-02-20 13:35]: >> grep is a special function with (&@) prototype > > Only very notionally, not in any way in terms of how it really works. > >> but this prototype doesn't describe it completly. It doesn't tell >> where to lookup $_ (and probably other variables) within the code >> block binded to & in the protototype. > > The block in a `grep` is simply not a function. Consider what this does: > > sub foo { grep { return; 1 } 1..4 } > > Then consider what this does: > > use List::Util 'reduce'; > sub foo { reduce { return; 1 } 1..4 } You're right - lightweight blocks are not functions. This means that builtin grep actually has prototype different from (&@). It is something closer to ([{}s]@) where {} is for lightweight blocks and "s" is for statements. sort for example has even trickier prototype where first argument is optional, it's either block or a bareword without comma after, so it's closer to ([{}b]?;@) where "b" is for bareword and ? makes them optional. If we talk about implementing builtin like functions in pure perl then all builtins should have correct prototype that exactly express its arguments and dictates to perl how to compile code that follows function name. In theory even `if` and `else` can get a prototype :) Should differences between lightweight blocks and functions influence variables scoping? My previous ideas still stand. I just don't see how mentioned difference between blocks and functions changes the fact that prototypes at this moment lack ability to clarify where $_ comes from within function and/or block that is passed into prototyped function. Well, one way forward is to implement "{}" prototype and make scoping of $_ behave differently for "&" and "{}". So reduce can be implemented in several ways: 1) sub reduce({};@) {...} my $_ = 10; reduce { ... } qw(foo bar); # valid reduce sub { ... } qw(foo bar) # invalid reduce \&foo, qw(foo bar) # invalid 2) reduce([{}&];@) { } all of above valid, but $_ in second and third cases can suffer from my $_; and will have to deal with it like in the following examples: perl -E 'sub foo(&) { local $_ = 1; shift->() } my $_ = 10; foo sub { say $_ }' 10 perl -E 'sub foo(&) { local $_ = 1; shift->() } my $_ = 10; foo sub { our $_; say $_ }' 1 This hardcoded difference makes it possible to get solution without implementing my ":our($_)" idea. Less flexible, but can please all camps after all. Also, this whole thread misses the fact that $a and $b used in sort fall into pretty much the same basket. > (That difference is one of a number of reasons that Rafaƫl is wrong > in his response to me that such lightweight blocks would be useless > without lexical $_.) > > > -- > Aristotle Pagaltzis // <http://plasmasturm.org/> -- Best regards, Ruslan.Thread Previous | Thread Next