Re: Using lists containing arrays as lvalues
HaloO, Ingo Blechschmidt wrote: But there is a problem with the ordinary assignment form: ($head, @tail) = foo(); If the LHS is an ordinary list (i.e., if we don't use help from the grammar/macros), What is a 'ordinary List' to you? I thought (,) constructs a Lazy list? then the @tail would get flattened before it reached the assignment operator. This is turn would cause the statement not to DWIM: my ($head, @tail) = foo(); # is really my ($head, @tail); ($head, @tail) = foo(); # is really (as @tail is empty) Aren't you making the silent transition here from the Array type to the List type? I would argue that the LHS is a Lazy that stores internal refs to $head and @tail until it is actually iterated. What I don't know is how lvalue iteration is distinguished from rvalue iteration. Then foo is called and the = is dispatched according to the type of the return value. The outcome hinges on that and on the type of ($head, @tail) which could be the 2-Tupel (Item,Array) or if you want 'List of ::X' ::X has to be the LUB of Item and Array, e.g. Object. Now assume foo() returns (1,2,3) which is a List of Int. Now infix:= just iterates the LHS and RHS. LHS is iterated for lvalues, of course. This results in the three assignments: $head= 1; @tail[0] = 2; # lvalue delivered from LHS list @tail[1] = 3; Which is what you expected, or not? For two scalars ($x,$y) = (1,2,3) the above nicely throws a undef assignment exception: $x = 1; $y = 2; undef = 3; # iterator ran out of values ($head, ())= foo(); # is really ($head)= foo(); # is really $head = foo(); # !!! for this I think we need an easier solution... Perhaps flattenning foo instead of adding a slurp, or making yadda yadda in lvalue throw it's arguments away silently: my ($foo, $bar, ...) := foo(); What has become of nullary * for list construction? my ($foo, $bar, *) := foo(); -- $TSa.greeting := HaloO; # mind the echo!
Re: Using lists containing arrays as lvalues
On Sat, Aug 27, 2005 at 08:19:00PM +0200, Ingo Blechschmidt wrote: : But there is a problem with the ordinary assignment form: : : ($head, @tail) = foo(); : : If the LHS is an ordinary list (i.e., if we don't use help from the : grammar/macros), then the @tail would get flattened before it reached : the assignment operator. This is turn would cause the statement not to : DWIM: : : my ($head, @tail) = foo(); # is really : : my ($head, @tail); : ($head, @tail) = foo(); # is really (as @tail is empty) : : ($head, ())= foo(); # is really : : ($head)= foo(); # is really : : $head = foo(); # !!! Yes, a list in lvalue context must propagate lvalueness to its components. You have to do this anyway to know when autovivication is permissible. The fact that you don't know it's an lvalue till you see the = means you can't just propagate the information down via the first pass of recursive descent. This is why Perl 5 makes separate top-down passes on portions of its tree when it has enough context to do that. Perl 6 will not be immune from this necessity... : for this I think we need an easier solution... Perhaps flattenning : foo instead of adding a slurp, or making yadda yadda in lvalue throw : it's arguments away silently: : : my ($foo, $bar, ...) := foo(); : : I like that! :) That could be made to work, but we've claimed for cultural continuity that assignment will work the same in Perl 6 as it was in Perl 5, so it's not the solution for you problem. Larry
Re: Using lists containing arrays as lvalues
On Sat, Aug 27, 2005 at 19:16:55 +0200, Ingo Blechschmidt wrote: my ($head, [EMAIL PROTECTED]) := foo(); if foo returns a list of scalars =2 this is like parameter unpacking: my ($head, [EMAIL PROTECTED]) = *foo(); if foo returns a scalar and an array as a list of two scalars, the second one being a ref to an array: my ($head, @tail) = foo(); I.e. we use binding's property that the LHS is a subroutine signature. (Note that I do not talk about the LHS being a list of scalars (e.g. ($a, $b, $c) = foo()), this post only speaks about using lists containing @arrays as lvalues). BTW, for simplicities sake perhaps there is an MMD on infix:,, one for lvalue context, the other for read only context? discarding any additional arguments, i.e. assuming my ($foo, $bar, [EMAIL PROTECTED]) := foo(); for this I think we need an easier solution... Perhaps flattenning foo instead of adding a slurp, or making yadda yadda in lvalue throw it's arguments away silently: my ($foo, $bar, ...) := foo(); -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: : neeyah! pgpfVkAEM6Cwm.pgp Description: PGP signature
Re: Using lists containing arrays as lvalues
Hi, Yuval Kogman wrote: On Sat, Aug 27, 2005 at 19:16:55 +0200, Ingo Blechschmidt wrote: my ($head, [EMAIL PROTECTED]) := foo(); if foo returns a list of scalars =2 this is like parameter unpacking: my ($head, [EMAIL PROTECTED]) = *foo(); [...] Right, but I wanted to drive at the difficulty of making this work, sorry if I was unclear. ($head, [EMAIL PROTECTED]) := foo(); # (Note: := here, not =) This is not a problem, because :='s LHS is a subroutine signature, which means the necessary magic is already there. But there is a problem with the ordinary assignment form: ($head, @tail) = foo(); If the LHS is an ordinary list (i.e., if we don't use help from the grammar/macros), then the @tail would get flattened before it reached the assignment operator. This is turn would cause the statement not to DWIM: my ($head, @tail) = foo(); # is really my ($head, @tail); ($head, @tail) = foo(); # is really (as @tail is empty) ($head, ())= foo(); # is really ($head)= foo(); # is really $head = foo(); # !!! for this I think we need an easier solution... Perhaps flattenning foo instead of adding a slurp, or making yadda yadda in lvalue throw it's arguments away silently: my ($foo, $bar, ...) := foo(); I like that! :) --Ingo -- Linux, the choice of a GNU | self-reference, n. - See self-reference generation on a dual AMD | Athlon!|