Re: map { $_ = $_ } @foo
Autrijus Tang wrote: map { $_ = $_; } @foo; This works too: map { ;$_ = $_ } @foo; But () is still only a grouper, so this won't do: map { ($_ = $_) } @foo; Does this make sense? A lot! BTW, is it possible to distinguish methods and subs from the toplevel, too? That little inference might help to solve the topic versus invocant problem by not requiring to alias $_ to $?SELF. I imagine map { .foo } @objects; to be interpreted as map method { $?SELF.foo } @objects; The distinguisher were the need of having a defined $?SELF in the closure. My idea is the following: | number of | as | class | invocants | multi| +---+--+ Sub | 0 | 0 | $?SELF | undef | := @?SELF[0] | @?SELF | undef | invocants| +---+--+ Method | 1 | 1 | $?SELF | invocant | := @?SELF[0] | @?SELF | undef | invocants| +---+--+ I used the @?SELF array mostly for illustrating my idea concerning $?SELF, but it might be usefull for things like multi sub foo { # use @?SELF here } as a catch-all for an unspecified number of parameters of type Any. The type of a method's $?SELF is derived from the lexical class scope. Subs in a class are just scoped there. A multi sub in a class is also just scoped there and the class has no impact on the specificity of any of the parameter types. -- TSa (Thomas Sandlaß)
Re: map { $_ = $_ } @foo
On Sun, Apr 24, 2005 at 04:39:04PM -0700, Larry Wall wrote: : Larry suggested that to keep it from being collapsed, we somehow : augment toplevel AST: : : map { $_ = $_; } @foo; : map { +($_ = $_) } @foo; Uh, I'm not sure what + would return for a Pair, but I'm pretty sure it's not a pair. A little P5ism sneaking in there? :-) Aye, indeed. :-) : But here is a new idea: Since the parser knows that the bare block is : followed by no trailing comma, how about we using it as a disambiguating : device, and define that it never collapses? : : map { $_ = $_ } @foo; # closure : map { $_ = $_ }, @foo; # hash A block can be arbitrarily long. I worry about disambiguating it by something could come lines later. It's the /x problem all over again. Plus, I think many folks would rather think of the closure comma as optional rather than mandatorily missing. Besides, if they can't keep the {...} straight, they're not gonna keep the comma straight either. Okay, I concur. r2319 now renders the trailing comma / adverbial colon orthogonal to closure collapsing again; I have also implemented your top-level-expression rule from an easlier thread. So to disambiguate, one has to write this now: map { $_ = $_; } @foo; This works too: map { ;$_ = $_ } @foo; But () is still only a grouper, so this won't do: map { ($_ = $_) } @foo; Does this make sense? Thanks, /Autrijus/ pgppdAs3gEUYk.pgp Description: PGP signature
map { $_ = $_ } @foo
A while ago I posted a conflict between a block containing a pair constructor, vs. a hash constructor: map { $_ = $_ } @foo; Larry suggested that to keep it from being collapsed, we somehow augment toplevel AST: map { $_ = $_; } @foo; map { +($_ = $_) } @foo; But here is a new idea: Since the parser knows that the bare block is followed by no trailing comma, how about we using it as a disambiguating device, and define that it never collapses? map { $_ = $_ } @foo; # closure map { $_ = $_ }, @foo; # hash And maybe it can be extended over adverbial blocks, too: @foo.map:{ $_ = $_ }; # closure Also as control structure body, just for consistency's sake: for @foo { $^x = $^y }; Is it a sane approach? I have just tentatively implemented it as r2305 if people would like to experiment with this proposal. Thanks, /Autrijus/ pgpGr0w8m9W9k.pgp Description: PGP signature
Re: map { $_ = $_ } @foo
On Mon, Apr 25, 2005 at 02:13:26AM +0800, Autrijus Tang wrote: : A while ago I posted a conflict between a block containing a pair : constructor, vs. a hash constructor: : : map { $_ = $_ } @foo; : : Larry suggested that to keep it from being collapsed, we somehow : augment toplevel AST: : : map { $_ = $_; } @foo; : map { +($_ = $_) } @foo; Uh, I'm not sure what + would return for a Pair, but I'm pretty sure it's not a pair. A little P5ism sneaking in there? :-) : But here is a new idea: Since the parser knows that the bare block is : followed by no trailing comma, how about we using it as a disambiguating : device, and define that it never collapses? : : map { $_ = $_ } @foo; # closure : map { $_ = $_ }, @foo; # hash A block can be arbitrarily long. I worry about disambiguating it by something could come lines later. It's the /x problem all over again. Plus, I think many folks would rather think of the closure comma as optional rather than mandatorily missing. Besides, if they can't keep the {...} straight, they're not gonna keep the comma straight either. : And maybe it can be extended over adverbial blocks, too: : : @foo.map:{ $_ = $_ }; # closure : : Also as control structure body, just for consistency's sake: : : for @foo { $^x = $^y }; : : Is it a sane approach? I have just tentatively implemented it as r2305 : if people would like to experiment with this proposal. I really think for clarity it has to be disambiguated by either something syntactic on the front or something semantic at the top level. It's probably pretty easy to catch the error of saying map { $_ = $_ } @foo; when you mean map { hash $_ = $_ } @foo; or map { list $_ = $_ } @foo; because map wants a closure as its first argument, not a hash. I still kinda like the rule that it's a hash if the top-level looks like some kind of list of pairs. It optimizes for the common case. Closures returning pairs are a rarity. Larry
Re: map { $_ = $_ } @foo
At 4:39 PM -0700 4/24/05, Larry Wall wrote: On Mon, Apr 25, 2005 at 02:13:26AM +0800, Autrijus Tang wrote: : A while ago I posted a conflict between a block containing a pair : constructor, vs. a hash constructor: : : map { $_ = $_ } @foo; : And maybe it can be extended over adverbial blocks, too: : : @foo.map:{ $_ = $_ }; # closure Why not just always use the ':' when you are giving a block. The block is essentially an adverb for a map|grep|sort anyway. Whereas, no ':' means its a hash-ref. (Presumably each of map|grep|sort will have a reasonable default adverb if no ':{}' is given.) I really think for clarity it has to be disambiguated by either something syntactic on the front or something semantic at the top level. I agree. See my previous paragraph for an example. I still kinda like the rule that it's a hash if the top-level looks like some kind of list of pairs. It optimizes for the common case. I agree. Closures returning pairs are a rarity. Larry This is beside the point but ... Perhaps one of the new Perl 6 features makes this unnecessary, but I often found myself doing just that when I wanted an effective method to test multiple times if an element is in an array, like this: my %foo = map:{ ( $_ = 1 ) } @bar; if( %foo{'abc'} ) ... if( %foo{'def'} ) ... if( %foo{'zrs'} ) ... That closure is returning a pair for each array element. -- Darren Duncan
Re: map { $_ = $_ } @foo
On Sun, Apr 24, 2005 at 06:14:35PM -0700, Darren Duncan wrote: : At 4:39 PM -0700 4/24/05, Larry Wall wrote: : On Mon, Apr 25, 2005 at 02:13:26AM +0800, Autrijus Tang wrote: : : A while ago I posted a conflict between a block containing a pair : : constructor, vs. a hash constructor: : : : : map { $_ = $_ } @foo; : : : And maybe it can be extended over adverbial blocks, too: : : : : @foo.map:{ $_ = $_ }; # closure : : Why not just always use the ':' when you are giving a block. The : block is essentially an adverb for a map|grep|sort anyway. Whereas, : no ':' means its a hash-ref. (Presumably each of map|grep|sort will : have a reasonable default adverb if no ':{}' is given.) There are lots of blocks that shouldn't take colons. : I really think for clarity it has to be disambiguated by either : something syntactic on the front or something semantic at the top level. : : I agree. See my previous paragraph for an example. : : I still : kinda like the rule that it's a hash if the top-level looks like some : kind of list of pairs. It optimizes for the common case. : : I agree. : : Closures : returning pairs are a rarity. : Larry : : This is beside the point but ... : : Perhaps one of the new Perl 6 features makes this unnecessary, but I : often found myself doing just that when I wanted an effective method : to test multiple times if an element is in an array, like this: : : my %foo = map:{ ( $_ = 1 ) } @bar; : if( %foo{'abc'} ) ... : if( %foo{'def'} ) ... : if( %foo{'zrs'} ) ... : : That closure is returning a pair for each array element. How 'bout: [EMAIL PROTECTED] »=« 1; That seems a lot clearer to me. If you don't like hyper, how about [EMAIL PROTECTED] = (1..2:by(0)); :-) Larry