(1,(2,3),4)[2]

1 view
Skip to first unread message

Autrijus Tang

unread,
May 11, 2005, 4:54:27 PM5/11/05
to perl6-l...@perl.org
In a somewhat related topic:

pugs> (1,(2,3),4)[2]
4

Because the invocant to .[] assumes a Singular context.
I'm not sure how any invocant can assume a Plural context anyway,
so this behaviour seems correct. Is it, though? :)

Thanks,
/Autrijus/

Autrijus Tang

unread,
May 11, 2005, 5:08:06 PM5/11/05
to Luke Palmer, Autrijus Tang, perl6-l...@perl.org
On Wed, May 11, 2005 at 03:00:15PM -0600, Luke Palmer wrote:
> On 5/11/05, Autrijus Tang <autr...@autrijus.org> wrote:
> > In a somewhat related topic:
> >
> > pugs> (1,(2,3),4)[2]
> > 4
> >
> > Because the invocant to .[] assumes a Singular context.
>
> Right, but the *inside* of the invocant is still a list, so it's in
> list context. I think that line should return 3.

You're totally right, and I was clearly wahnsinnig. It now returns 3.

Thanks,
/Autrijus/

Luke Palmer

unread,
May 11, 2005, 5:00:15 PM5/11/05
to Autrijus Tang, perl6-l...@perl.org
On 5/11/05, Autrijus Tang <autr...@autrijus.org> wrote:
> In a somewhat related topic:
>
> pugs> (1,(2,3),4)[2]
> 4
>
> Because the invocant to .[] assumes a Singular context.

Right, but the *inside* of the invocant is still a list, so it's in


list context. I think that line should return 3.

Luke

Matt Fowles

unread,
May 11, 2005, 5:48:04 PM5/11/05
to Luke Palmer, Autrijus Tang, perl6-l...@perl.org
All~

I am confused as to why exactly this is the case. Are you saying that
nested lists like this flatten? That would certainly catch me off
guard. Would you mind explaining that to me a little more?

Thanks,
Matt
--
"Computer Science is merely the post-Turing Decline of Formal Systems Theory."
-???

Aaron Sherman

unread,
May 11, 2005, 6:24:38 PM5/11/05
to Matt Fowles, Perl6 Language List
On Wed, 2005-05-11 at 17:48, Matt Fowles wrote:

> On 5/11/05, Luke Palmer <lrpa...@gmail.com> wrote:
> > On 5/11/05, Autrijus Tang <autr...@autrijus.org> wrote:
> > > In a somewhat related topic:
> > >
> > > pugs> (1,(2,3),4)[2]
> > > 4
> > >
> > > Because the invocant to .[] assumes a Singular context.
> >
> > Right, but the *inside* of the invocant is still a list, so it's in
> > list context. I think that line should return 3.
>
> I am confused as to why exactly this is the case. Are you saying that
> nested lists like this flatten? That would certainly catch me off
> guard. Would you mind explaining that to me a little more?

I'm confused as well. How does that play with Larry's comment:

http://groups-beta.google.com/group/perl.perl6.language/browse_frm/thread/54a1135c012b97bf/d17b4bc5ae7db058?q=list+comma&rnum=5&hl=en#d17b4bc5ae7db058

--
Aaron Sherman <a...@ajs.com>
Senior Systems Engineer and Toolsmith
"It's the sound of a satellite saying, 'get me down!'" -Shriekback


Juerd

unread,
May 11, 2005, 7:22:43 PM5/11/05
to Autrijus Tang, perl6-l...@perl.org
(reformatted to keep initialization with test)

Autrijus Tang skribis 2005-05-12 7:04 (+0800):
> my @a = (1,2,[3,4]);
> is(+@a, 3, 'Array length, nested []');

ok 1

> my $a = (1,2,[3,4]);
> is(+$a, 3, 'Array ref length, nested []');

ok 2

> my @b = [1,2,[3,4]];
> is(+@b, 1, 'Array length, nested [], outer []s');

ok 3

> my $b = [1,2,[3,4]];
> is(+$b, 3, 'Array ref length, nested [], outer []s');

ok 4

> my @c = (1,2,(3,4));
> is(+$c, 4, 'Array ref length, nested ()');

ok 5

> my $c = (1,2,(3,4));
> is(+@c, 4, 'Array length, nested ()');

ok 6

> my @d = [1,2,(3,4)];
> is(+@d, 1, 'Array length, nested (), outer []s');

ok 7

> my $d = [1,2,(3,4)];
> is(+$d, 4, 'Array ref length, nested (), outer []s');

ok 8

> Please sanity-check. :-)

All sane! :)


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

Autrijus Tang

unread,
May 11, 2005, 7:04:48 PM5/11/05
to Luke Palmer, Autrijus Tang, perl6-l...@perl.org
On Wed, May 11, 2005 at 03:00:15PM -0600, Luke Palmer wrote:

Okay. Here is the current (all-passing) t/data_types/nested_arrays.t:

{


my @a = (1,2,[3,4]);

my $a = (1,2,[3,4]);

my @b = [1,2,[3,4]];

my $b = [1,2,[3,4]];

my @c = (1,2,(3,4));
my $c = (1,2,(3,4));
my @d = [1,2,(3,4)];
my $d = [1,2,(3,4)];

is(+@a, 3, 'Array length, nested []');

is(+$a, 3, 'Array ref length, nested []');

is(+@b, 1, 'Array length, nested [], outer []s');

is(+$b, 3, 'Array ref length, nested [], outer []s');

is(+$c, 4, 'Array ref length, nested ()');


is(+@c, 4, 'Array length, nested ()');

is(+@d, 1, 'Array length, nested (), outer []s');

is(+$d, 4, 'Array ref length, nested (), outer []s');
}


Please sanity-check. :-)

Thanks,
/Autrijus/

Larry Wall

unread,
May 11, 2005, 7:49:47 PM5/11/05
to perl6-l...@perl.org
On Thu, May 12, 2005 at 07:04:48AM +0800, Autrijus Tang wrote:
: Please sanity-check. :-)

Looks good to me. Though that should perhaps not be confused with sanity.

Larry

Larry Wall

unread,
May 11, 2005, 8:02:07 PM5/11/05
to Perl6 Language List
On Wed, May 11, 2005 at 06:24:38PM -0400, Aaron Sherman wrote:
: I'm confused as well. How does that play with Larry's comment:
:
: http://groups-beta.google.com/group/perl.perl6.language/browse_frm/thread/54a1135c012b97bf/d17b4bc5ae7db058?q=list+comma&rnum=5&hl=en#d17b4bc5ae7db058

Well, that approach would also work. I'm just not sure it's what
people would expect. It's a little retroactive for .[] to change the
context of the expressions in (). These days I think I'd rather have
something out front that specifically says you want a list of scalars.
Perhaps

scalar(1,(2,3),4)

should be our list of scalars context, and produce [1,[2,3],4]. Or maybe
something else should indicate LoS.

Larry

Juerd

unread,
May 18, 2005, 6:50:03 PM5/18/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-05-18 21:54 (+0200):

> Juerd wrote:
> >> my @b = [1,2,[3,4]];
> >> is(+@b, 1, 'Array length, nested [], outer []s');
> Isn't that a bit inconvenient? To get e.g. 2 out of @b
> one has to write @b[0][1] while for $b a $b[1] suffices.

http://learn.perl.org/library/beginning_perl/

Parens and square brackets are very different things.

The above is more commonly written as

my @b = ([1,2,[3,4]);

Having arrayrefs flatten in list context, or having [] to be able mean
something other than constructing an arrayref, is a change that requires
the very fundaments of Perl to change very heavily, beginning by
eliminating lists entirely, and using only arrays.

I believe I said it before, but I'll do it again: Perl is not Python.
Just that the two languages are both powerful, and both begin with a P,
and in some respects even syntactically look like eachother (hey, that's
what we get for loving ASCII), doesn't mean any theory applicable to one
automatically makes sense for the other.

> And @x = @b maintains this superficial level of indirection?

ARRAY = LIST is the syntax for assigning to an array. Note that the RHS
is list context, not Array context.

> Does @x = @b[] remove one level? How does that compare

No. As far as I know, @b[] and @b are the synonymous.

> my @b = (1,2,[3,4]);
> is equivalent to


> my $b = [1,2,[3,4]];

No, that's not equivalent. $b contains a reference to an array, while @b
itself is an array.

Hoping the box diagram worked the last time, I'll try again:

+-- @b +-- $b (this array has no name;
| | it is "anonymous")
V V
+----------+ +------------+ +----------+
| elements | | reference ----> | elements |
+----------+ |------------+ +----------+
ARRAY SCALAR ARRAY

> which in turn is equivalent to
> my $b = (1,2,[3,4]);

That is only because the comma operator is in scalar context. The parens
here merely GROUP, for precedence. my $b = eval "1,2,[3,4]" would be
exactly the same. Just to show you the parens are NOT constructors of
the list.

> $b = @b

No, that assigns a *reference to $b* to @b, without any copying of
elements.

> Am I insane?

No, you just STILL can't cope with Perl's notion of names, containers
and values, and you don't realise that () and [] are not related, more
specifically: that () has absolutely nothing to do with arrays or lists.

These are mistakes many Perl 5 beginners make, especially those coming
from Python.

Juerd

unread,
May 19, 2005, 5:04:32 PM5/19/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-05-19 21:06 (+0200):

> >The above is more commonly written as
> >
> > my @b = ([1,2,[3,4]);
> Assuming you meant @b = ([1,2,[3,4]]) what do the parens accomplish
> here?

Thanks for the correction. That is indeed what I meant.

The parens do absolutely nothing, except indicate to a less skilled
reader that the [] aren't enclosing @b's future elements.

> Would it even need to be @b = (,[1,2,[3,4]]) to have the list
> contructing comma?

A single scalar in list context acts as a single item list, so a
specific list constructor is not needed.

> Does the following hold: @a = (1,2,3); @b = @a; +@b == 1?

No.

@a = (1,2,3);

The array @a now contains 3 elements: 1, 2 and 3.

@b = @a;

@a is in list context. An array in list context, evaluates to a list of
its elements. Three elements are assigned to @b. Assignment copies the
values.

+@b == 1;

This expression is false. @b is in Num context. An array in numeric
context evaluates to its number of arguments. The number of arguments of
@b is 3, because it was just assigned three elements.

Do note that @a[0] == @b[0], but they are different variables:
assignment copies.

> My pivot question here is if +[1,2,[3,4]] == +(1,2,[3,4]) == 3 and

That is: +[ LIST ] == +(ITEM, ITEM, ITEM). The comma in scalar context
makes generates an anonymous array and returns a reference to that.
Effectively, this makes () apparently equal to [] in this statement.

> why then is @a = [1,2,[3,4]]; +@a == 1 but $a = [1,2,[3,4]]; +$a == 3.

Because @a contains one element and @$a contains three elements. $a is
not an array, it is a reference to an array, just like @a[0].

+@a[0] is 3, just like +@$a (shortened as +$a).

> Perl6 has automatic deref and ref

An array in scalar context evaluates to a reference to itself.

A hash in scalar context evaluates to a reference to itself.

An array in list context evaluates to a list of its elements.

A hash in list context evaluates to a list of its elements (as pairs).

Array context is a scalar context.

A subroutine argument with the @ sigil represents an array that is
passed by reference. It can be accessed directly, without explicit
dereferencing.

A subroutine argument with the % sigil represents a hash that is
passed by reference. It can be accessed directly, without explicit
dereferencing.

sub ($bar) { the array is @$bar } # non-array allowed in call
sub (Array $bar) { the array is @$bar }
sub (@bar) { the array is @bar }

$anyofthose.(@array) is the same as $anyofthose.(\@array)

sub (*@bar) { arguments are in list context, @bar has aliases }

$thatthing.(@array) # passes the elements, not @array itself
$thatthing.(\@array) # passes a reference to @array into @bar[0]
$thatthing.(15) # passes 15 into @bar[0]

> Otherwise $a = @b in Perl6 weren't the equivalent of Perl5's $a = \@a.

I hate the term "automatic referencing" because it sounds much more
magical than it actually is.

In Perl 5, @array in scalar context returned the number of elements.

In Perl 6, @array in scalar context returns a reference.

In Perl 6, you can further specify scalar context:

* In Num context, @array returns its number of elements.
* In Str context, @array returns its elements joined on whitespace.
* In Bool context, @array returns true iff it has elements.
* In Array context, @array returns a reference.
* In Scalar context, @array returns a reference.

> BTW, how does @a = <one two three> compare to $a = <one two three>?

@a is an array, $a is a reference to another. The elements of the arrays
are equal, but not the same.

> Is +@a == 3?

Yes.

> Is $a[1] == 'two'?

Yes. Do note that this is really @$a[1] or $a.[1].

> this is the Perl6 language list, not a Perl5 beginners list.

Thank you for this reassurance.

> And I see a lot of things changed from Perl5 to Perl6, including
> referential semantics.

They haven't changed as much as you think. In fact, only how arrays and
hashes behave in scalar context has really changed.

Juerd

unread,
May 25, 2005, 5:03:38 AM5/25/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-05-25 10:47 (+0200):
> I have understand what you mean and how you---and other p6l'er---
> derive +@a == 1 from @a = [1,2,3]. But allow me to regard this
> as slightly inconsistent, asymmetric or some such.

If you STILL don't understand that it has nothing to do with
inconsistency or asymmetry, then please allow me to at this point give
up and stop trying to explain.

() do not construct lists, inside () is an expression, () does not
provide context. [] constructs arrays, inside [] is an expression that
is a list, [] does provide list context.

() and [] are as alike as [] and {} or <> and (), or ** and ++.

Your expectation, not the language, is wrong.

> Isn't hash context missing in the list above? How does
> %a = ( a => 1, b => 2, c => 3 ) # @a = (1,2,3)

HASH = THREE PAIRS

> compare with
> %b = { a => 1, b => 2, c => 3 } # @b = [1,2,3]

HASH = ONE SCALAR

That probably does roughly the same as:

%b;
%b{ { a => 1, b => 2, c => 3 } } = undef;

Hopefully with a warning complaining about the odd number of elements in
the list.

> 3 == +%a == +%b

No.

> %a<a> == 1 == %b<a>

No, there is no %b{'a'}, only a $b{ $a_certain_hashref }.

Juerd

unread,
May 25, 2005, 9:02:58 AM5/25/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-05-25 13:53 (+0200):

> >>%a = ( a => 1, b => 2, c => 3 ) # @a = (1,2,3)
> >HASH = THREE PAIRS
> I look at it as &infix:{'='}:( Hash, List of Pair : --> Ref of Hash )
> and then try to understand how it behaves. BTW, I'm neither sure
> of the type of the second invocant parameter nor of the return type.
> Even the position of the : is contestable.

If assigning a ref to a hash uses the hashref's elements, then the same
is to be expected for an array. Because this behaviour is unwanted for
arrays (because you then can't assign a single arrayref anymore without
doubling the square brackets, communicating an entirely wrong thing),
hashes have to concede as well, even though %a = $href may not make
sense.

> And +[1,2,3] seems to mean &prefix:<+>:(Ref of Array: --> Num)
> while +(1,2,3) is &prefix:<+>:(List: --> Num). More interesting

The + forces scalar Num context. So it can probably be written as
something resembling

sub &prefix:<+> (Num $foo) { $foo }

Prefix + doesn't take a list. If you use comma in scalar context, an
array reference is created. This makes +[] and +() practically equal,
but that doesn't mean [] and () are always exchangeable, or even that
they have anything to do with eachother. In +[], the [] make the
arrayref, while in +(), the comma does that. If you have +() without
comma, you don't have an arrayref, because () only groups.

> are the &infix:<,> inside

I recall having read something about , being "listfix", not infix. The
same would be true for Y and | and & and ^.

Mark Reed

unread,
May 25, 2005, 10:49:20 AM5/25/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
[1,2,3] is not an array or a list. It is a reference to an anonymous array.
It is not 3 values; it¹s 1 value, which happens to point to a list of size
3. If you assign that to an array via something like @a = [1,2,3], I would
expect at least a warning and possibly a compile-time error.

If it does work, it probably gets translated into @a = ([1,2,3]), which
creates an array of size 1 whose first (and only) element is a reference to
an array of size 3. That would give this result:

+@a == 1;

@a[0] == [1,2,3];
@a[1] == undef;
@a[0][0] == 1;
@a[0][1] == 2;
@a[0][2] == 3;

I¹m not sure about +(@a[0]), but I¹m guessing it would == 3.

On 2005-05-25 04:47, "TSa (Thomas Sandlaß)" <Thomas....@orthogon.com>
wrote:

> Juerd wrote:
>> > An array in scalar context evaluates to a reference to itself.
>> >
>> > A hash in scalar context evaluates to a reference to itself.
>> >
>> > An array in list context evaluates to a list of its elements.
>> >
>> > A hash in list context evaluates to a list of its elements (as pairs).
>> >
>> > Array context is a scalar context.
>

> I have understand what you mean and how you---and other p6l'er---
> derive +@a == 1 from @a = [1,2,3]. But allow me to regard this
> as slightly inconsistent, asymmetric or some such.
>

> Isn't hash context missing in the list above? How does
>

> %a = ( a => 1, b => 2, c => 3 ) # @a = (1,2,3)
>

> compare with
>
> %b = { a => 1, b => 2, c => 3 } # @b = [1,2,3]
>
> Does that mean

>
> 3 == +%a == +%b

> == +{ a => 1, b => 2, c => c }
> == +( a => 1, b => 2, c => c )
>
> holds and the access of the hash works as expected:
>
> %a<a> == 1 == %b<a> # and @a[0] == 1, but @b[0][0] == 1
>
> What would actually be the equivalent syntax to @b?
> Is it %b<><a> or %%b<a> or even (*%b)<a>?
> It will hardly be %b{undef}<a>, though.


Austin Hastings

unread,
May 25, 2005, 1:18:45 PM5/25/05
to Rod Adams, perl6-l...@perl.org

--- Rod Adams <r...@rodadams.net> wrote:
> TSa (Thomas Sandlaß) wrote:
>
> >
> > You mean @a = [[1,2,3]]? Which is quite what you need for multi
> > dimensional arrays anyway @m = [[1,2],[3,4]] and here you use
> > of course @m[0][1] to pull out the 2. I'm not sure if this
> automatically
> > makes the array multi-dimensional to the type system though. That
> is
> > if @m[0,1] returns 2 as well or if it returns the list (1,2) or
> whatever.
> > Is @m[0..3] valid and what does it return? And what's the type of
> that
> > return value(s)? I can imagine many things ranging from a two
> element
> > array of refs to two element arrays up to a flattened list of 4
> values.
> >
>
> @m[0,1] is an array slice of two elements, in this case two arrayrefs
>
> [1,2], and [3,4].
> @m[0;1] is a multidim deref, referencing the 4.
>

Referencing the 2, I hope?


> -- Rod Adams

=Austin

Rod Adams

unread,
May 25, 2005, 1:15:04 PM5/25/05
to perl6-l...@perl.org
TSa (Thomas Sandlaß) wrote:

>
> You mean @a = [[1,2,3]]? Which is quite what you need for multi
> dimensional arrays anyway @m = [[1,2],[3,4]] and here you use
> of course @m[0][1] to pull out the 2. I'm not sure if this automatically
> makes the array multi-dimensional to the type system though. That is
> if @m[0,1] returns 2 as well or if it returns the list (1,2) or whatever.
> Is @m[0..3] valid and what does it return? And what's the type of that
> return value(s)? I can imagine many things ranging from a two element
> array of refs to two element arrays up to a flattened list of 4 values.
>

@m[0,1] is an array slice of two elements, in this case two arrayrefs
[1,2], and [3,4].
@m[0;1] is a multidim deref, referencing the 4.

@m[0..3] is valid, returning arrayref x 2, undef x 2.


Personally, I strongly believe that assigning an arrayref to an array
should dereference the arrayref, and send that to the array. Otherwise,
you get silly things like:

$a = [1,2,3];
@a = $a;
say +@a; # 1

I would prefer to not have people be forced to write that as "@a = $a[];".

I don't see the big problem with having to double up the brackets to
assign an arrayref to an array element.

-- Rod Adams

Rod Adams

unread,
May 25, 2005, 1:22:42 PM5/25/05
to perl6-l...@perl.org
Austin Hastings wrote:

Doh!

Yes, the 2.

-- Rod Adams

Juerd

unread,
May 25, 2005, 1:54:04 PM5/25/05
to Mark Reed, TSa (Thomas Sandlaß), perl6-l...@perl.org
Mark Reed skribis 2005-05-25 10:49 (-0400):

> [1,2,3] is not an array or a list. It is a reference to an anonymous array.
> It is not 3 values; it零 1 value, which happens to point to a list of size

Just for accuracy: it points to an array, which is still not a list in
our jargon.

> 3. If you assign that to an array via something like @a = [1,2,3], I would
> expect at least a warning and possibly a compile-time error.
>
> If it does work, it probably gets translated into @a = ([1,2,3]), which

That's not a translation. Parens, when not postfix, serve only one
purpose: group to defeat precedence. $foo and ($foo) are always the same
thing, regardless of the $foo.

> I雋 not sure about +(@a[0]), but I雋 guessing it would == 3.

Because parens only group, and [0] here has tighter precedence than the
prefix + anyway, +(@a[0]) and +@a[0] are exactly the same.

Because @a[0] is a reference to an array, that array is @{ @a[0] }. +@{
@a[0] } is also the same as +@a[0].

The numeric value of an array reference is the same as that of its
array.

Juerd

unread,
May 25, 2005, 2:19:50 PM5/25/05
to Mark Reed, Juerd, TSa (Thomas Sandlaß), perl6-l...@perl.org
Mark Reed skribis 2005-05-25 14:09 (-0400):

> > That's not a translation. Parens, when not postfix, serve only one
> > purpose: group to defeat precedence. $foo and ($foo) are always the same
> > thing, regardless of the $foo.
> So, you could then do this to make an array of size 3 in Perl6?
> @a = 1,2,3;

You could, if you changed the precedence of , to be tighter than =.

However, by default, = has higher precedence than ,, so that you need
parens to override this decision: @a = (1,2,3);

Rod Adams

unread,
May 25, 2005, 2:38:27 PM5/25/05
to perl6-l...@perl.org
Juerd wrote:

>Mark Reed skribis 2005-05-25 14:09 (-0400):
>
>
>>>That's not a translation. Parens, when not postfix, serve only one
>>>purpose: group to defeat precedence. $foo and ($foo) are always the same
>>>thing, regardless of the $foo.
>>>
>>>
>>So, you could then do this to make an array of size 3 in Perl6?
>> @a = 1,2,3;
>>
>>
>
>You could, if you changed the precedence of , to be tighter than =.
>
>However, by default, = has higher precedence than ,, so that you need
>parens to override this decision: @a = (1,2,3);
>
>

Or use

@a <== 1,2,3;

-- Rod Adams

Mark Reed

unread,
May 25, 2005, 2:09:13 PM5/25/05
to Juerd, TSa (Thomas Sandlaß), perl6-l...@perl.org


On 2005-05-25 13:54, "Juerd" <ju...@convolution.nl> wrote:

>> 3. If you assign that to an array via something like @a = [1,2,3], I would
>> expect at least a warning and possibly a compile-time error.
>>
>> If it does work, it probably gets translated into @a = ([1,2,3]), which
>
> That's not a translation. Parens, when not postfix, serve only one
> purpose: group to defeat precedence. $foo and ($foo) are always the same
> thing, regardless of the $foo.

So, you could then do this to make an array of size 3 in Perl6?

@a = 1,2,3;


Wolverian

unread,
May 25, 2005, 2:50:27 PM5/25/05
to perl6-l...@perl.org
On Wed, May 25, 2005 at 01:38:27PM -0500, Rod Adams wrote:
> Or use
>
> @a <== 1,2,3;

I would just like to say that I like this idiom immensely.

my @foo <== 1, 2, 3;

reads extremely well to me, especially since I've always disliked the
usage of '=' as an operator with side effects. (I'm strange like that.)

--
wolverian

signature.asc

Uri Guttman

unread,
May 25, 2005, 7:07:02 PM5/25/05
to perl6-l...@perl.org
>>>>> "w" == wolverian <wo...@sci.fi> writes:

w> On Wed, May 25, 2005 at 01:38:27PM -0500, Rod Adams wrote:
>> Or use
>>
>> @a <== 1,2,3;

w> I would just like to say that I like this idiom immensely.

w> my @foo <== 1, 2, 3;

w> reads extremely well to me, especially since I've always disliked the
w> usage of '=' as an operator with side effects. (I'm strange like that.)

please don't use <== for simple assignments as it will confuse too many
newbies and auch. it (and its sister ==>) are for pipelining ops like
map/grep and for forcing assignment to the slurpy array arg of funcs
(hey, i think i said that correctly! :). = is still fine for basic
assignment and everyone will understand it immediately.

the only advantage in the above case is the different prececences of =
and <== which allows dropping of parens with the latter. i don't
consider that so important a win as to be used often. and they are at
equal huffman levels as the =() is matched in length by <==.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

Wolverian

unread,
May 25, 2005, 7:11:02 PM5/25/05
to perl6-l...@perl.org
On Wed, May 25, 2005 at 07:07:02PM -0400, Uri Guttman wrote:
> please don't use <== for simple assignments as it will confuse too many
> newbies and auch. it (and its sister ==>) are for pipelining ops like
> map/grep and for forcing assignment to the slurpy array arg of funcs
> (hey, i think i said that correctly! :). = is still fine for basic
> assignment and everyone will understand it immediately.

I thought the op is visually so obvious it wouldn't need any
explanation, even for newbies.

Too bad what I _think_ is often not what actually _is_.

--
wolverian

signature.asc

Uri Guttman

unread,
May 25, 2005, 7:34:49 PM5/25/05
to perl6-l...@perl.org
>>>>> "w" == wolverian <wo...@sci.fi> writes:

w> On Wed, May 25, 2005 at 07:07:02PM -0400, Uri Guttman wrote:
>> please don't use <== for simple assignments as it will confuse too many
>> newbies and auch. it (and its sister ==>) are for pipelining ops like
>> map/grep and for forcing assignment to the slurpy array arg of funcs
>> (hey, i think i said that correctly! :). = is still fine for basic
>> assignment and everyone will understand it immediately.

w> I thought the op is visually so obvious it wouldn't need any
w> explanation, even for newbies.

w> Too bad what I _think_ is often not what actually _is_.

well, = has massive history on its side and almost all commonly used
languages use it for assignment (pascal is NOT common anymore,
thankfully and lisp isn't common enough :). so there is zero learning
curve for that. you do need to learn about perl's precedences which need
() for assigning a list. but <== may seem obvious to you and for sure to
anyone here but imagining what newbies would make of it boggles me. if
there is a way to misunderstand it and abuse it, it will happen. :) so
consider it just a style rule that i would encourage. damian should add
it to his P6BP book when it comes out next christmas. :)

Stuart Cook

unread,
May 25, 2005, 11:50:20 PM5/25/05
to perl6-l...@perl.org
On 5/26/05, Juerd <ju...@convolution.nl> wrote:
> You could, if you changed the precedence of , to be tighter than =.
>
> However, by default, = has higher precedence than ,, so that you need
> parens to override this decision: @a = (1,2,3);

Is giving "=" a higher precedence than "," still considered A Good Thing?

I'm not familiar with the reasoning behind the current situation, but
I'm struggling to come up with any good reasons for keeping it.

Consider the alternative:

my $a, $b = 1, 2; # $b should contain 2, not 1
my @foo = 3, 4, 5; # @foo should contain (3, 4, 5), not (list 3)

What justification for the status quo could be so compelling that we
feel the need to prevent both of these from doing the 'natural' thing?


Stuart

Stuart Cook

unread,
May 26, 2005, 12:30:30 AM5/26/05
to perl6-l...@perl.org
On 5/26/05, Stuart Cook <sco...@gmail.com> wrote:
> my $a, $b = 1, 2; # $b should contain 2, not 1
> my @foo = 3, 4, 5; # @foo should contain (3, 4, 5), not (list 3)
>
> What justification for the status quo could be so compelling that we
> feel the need to prevent both of these from doing the 'natural' thing?

(Scanning through the the history of this thread, I noticed the link
to Larry's comment about the precedence of "=" and ",". I personally
would still prefer them to be changed, but I guess it's not a big
deal, as long as we have warnings to catch obvious-but-wrong code like
my suggestions. When in doubt, use parens...)

Markus Laire

unread,
May 26, 2005, 4:03:37 AM5/26/05
to perl6-l...@perl.org
Rod Adams wrote:
> TSa (Thomas Sandlaß) wrote:
>
>>
>> You mean @a = [[1,2,3]]? Which is quite what you need for multi
>> dimensional arrays anyway @m = [[1,2],[3,4]] and here you use
>> of course @m[0][1] to pull out the 2. I'm not sure if this automatically
>> makes the array multi-dimensional to the type system though. That is
>> if @m[0,1] returns 2 as well or if it returns the list (1,2) or whatever.
>> Is @m[0..3] valid and what does it return? And what's the type of that
>> return value(s)? I can imagine many things ranging from a two element
>> array of refs to two element arrays up to a flattened list of 4 values.
>>
>
> @m[0,1] is an array slice of two elements, in this case two arrayrefs
> [1,2], and [3,4].
> @m[0;1] is a multidim deref, referencing the 4.
>
> @m[0..3] is valid, returning arrayref x 2, undef x 2.

I think you got these wrong. With @m = ([1,2],[3,4]) these would be
true, but with @m = [[1,2],[3,4]] we have an additional reference there.

Here @m has single array-ref, not 2 array-refs.

pugs gives this:

pugs> my @m = [[1,2],[3,4]]
({ref:<Array>})
pugs> @m[0,1]
({ref:<Array>}, undef)
pugs> @m[0..3]
({ref:<Array>}, undef, undef, undef)
# @m[0;1] form doesn't work in r3723

and

pugs> my @m = ([1,2],[3,4])
({ref:<Array>}, {ref:<Array>})
pugs> @m[0,1]
({ref:<Array>}, {ref:<Array>})
pugs> @m[0..3]
({ref:<Array>}, {ref:<Array>}, undef, undef)

--
Markus Laire

Markus Laire

unread,
May 26, 2005, 4:16:59 AM5/26/05
to perl6-l...@perl.org
Rod Adams wrote:
> Austin Hastings wrote:
>> --- Rod Adams <r...@rodadams.net> wrote:
>>> TSa (Thomas Sandlaß) wrote:
>>>
>>>> @m = [[1,2],[3,4]]
>>>
>>> @m[0;1] is a multidim deref, referencing the 4.
>>
>> Referencing the 2, I hope?
>>
> Doh!
>
> Yes, the 2.

Really?

@m here has _single_ array-ref so
@m[0] returns that single array-ref - [[1,2],[3,4]]
@m[0;1] then returns array-ref [3,4]
@m[0;0] would return [1,2]
@m[0;0;1] would return 2

Double-checking with pugs: (multi-dim with ; doesn't work yet)

pugs> my @m = [[1,2],[3,4]]
({ref:<Array>})

pugs> @m[0]


({ref:<Array>}, {ref:<Array>})

pugs> @m[0][1]
(3, 4)
pugs> @m[0][0]
(1, 2)
pugs> @m[0][0][1]
2

@m = [[1,2],[3,4]] IS NOT same as @m = ([1,2],[3,4])

pugs> my @m = ([1,2],[3,4])
({ref:<Array>}, {ref:<Array>})

pugs> @m[0]
(1, 2)
pugs> @m[0][1]
2

--
Markus Laire

Rod Adams

unread,
May 26, 2005, 5:15:07 AM5/26/05
to perl6-l...@perl.org
Markus Laire wrote:

> Rod Adams wrote:
>
>> TSa (Thomas Sandlaß) wrote:
>>
>>>
>>> You mean @a = [[1,2,3]]? Which is quite what you need for multi
>>> dimensional arrays anyway @m = [[1,2],[3,4]] and here you use
>>> of course @m[0][1] to pull out the 2. I'm not sure if this
>>> automatically
>>> makes the array multi-dimensional to the type system though. That is
>>> if @m[0,1] returns 2 as well or if it returns the list (1,2) or
>>> whatever.
>>> Is @m[0..3] valid and what does it return? And what's the type of that
>>> return value(s)? I can imagine many things ranging from a two element
>>> array of refs to two element arrays up to a flattened list of 4 values.
>>>
>>
>> @m[0,1] is an array slice of two elements, in this case two arrayrefs
>> [1,2], and [3,4].
>> @m[0;1] is a multidim deref, referencing the 4.
>>
>> @m[0..3] is valid, returning arrayref x 2, undef x 2.
>
>
> I think you got these wrong. With @m = ([1,2],[3,4]) these would be
> true, but with @m = [[1,2],[3,4]] we have an additional reference there.


From S02: "Array and hash variable names in scalar context
automatically produce references."

Since [...] produces a scalar arrayref, we end up with an arrayref one
both sides of the =.

Now, I see two ways it could shake down from here:

1) the lhs ref acquires the value of the rhs ref.
2) both sides perform one level of dereferencing, and the list of
elements from the rhs is copied over to the lhs. Having one one side
dereference and not the other makes no sense at all.

Either way, I see the following as all being semantically equivalent:

@m = ([1,2],[3,4]);
@m = [[1,2],[3,4]];
@m = (1,2; 3,4);
@m = [1,2; 3,4];
@m = list([1,2],[3,4]);
@m = (); @m[0]=[1,2]; @m[1]=[3,4];
@m[] = ([1,2],[3,4]);
@m <== [1,2], [3,4];
@m <== (1,2; 3,4);


If I understand Juerd correctly, the logical extension would be to have
@m = 5;
be the same as:
@m = list(5);

Thus saying that a lhs @ forces list context on the rhs, where I think
having the rhs dictate context on the rhs makes a lot more sense.

Basically, I'm disagreeing with some of what Juerd has said.

-- Rod Adams


Juerd

unread,
May 26, 2005, 5:30:09 AM5/26/05
to Rod Adams, perl6-l...@perl.org
Rod Adams skribis 2005-05-26 4:15 (-0500):

> From S02: "Array and hash variable names in scalar context
> automatically produce references."
> Since [...] produces a scalar arrayref, we end up with an arrayref one
> both sides of the =.

No.

There is no scalar context on the LHS of the assignment operator.

And, assigning to a reference is impossible, as a reference is a VALUE,
not a VARIABLE (container).

Assigning to a reference thus makes no sense in the same way that
assigning a new value to the number 42 makes no sense. It is possible
with some tricks, but you really shouldn't ever want to do this.

> If I understand Juerd correctly, the logical extension would be to have
> @m = 5;
> be the same as:
> @m = list(5);

The RHS of an array assignment is in list context. "list" is an operator
that does nothing more than force list context. In this case, it is
entirely redundant. But, of course, valid.

Rob Kinyon

unread,
May 26, 2005, 9:04:10 AM5/26/05
to Stuart Cook, perl6-l...@perl.org
> Is giving "=" a higher precedence than "," still considered A Good Thing?
>
> I'm not familiar with the reasoning behind the current situation, but
> I'm struggling to come up with any good reasons for keeping it.
>
> Consider the alternative:
>
> my $a, $b = 1, 2; # $b should contain 2, not 1

I read this as
(my $a), ($b=1), 2;

The comma separates clauses in English (and other languages). Why
should it not be so in Perl?

If you need parens, then use them. I believe it was Larry who said
"When in doubt, parenthesize. At the very least, people can bounce on
them with % in vi."

Rod Adams

unread,
May 26, 2005, 2:02:56 PM5/26/05
to perl6-l...@perl.org
Juerd wrote:

>Rod Adams skribis 2005-05-26 4:15 (-0500):
>
>
>>From S02: "Array and hash variable names in scalar context
>>automatically produce references."
>>Since [...] produces a scalar arrayref, we end up with an arrayref one
>>both sides of the =.
>>
>>
>
>No.
>
>There is no scalar context on the LHS of the assignment operator.
>
>And, assigning to a reference is impossible, as a reference is a VALUE,
>not a VARIABLE (container).
>
>Assigning to a reference thus makes no sense in the same way that
>assigning a new value to the number 42 makes no sense. It is possible
>with some tricks, but you really shouldn't ever want to do this.
>
>
>

You're right. It was late, and my brain missed a few details. I saw
"arrayref = arrayref", and C took over.

>>If I understand Juerd correctly, the logical extension would be to have
>> @m = 5;
>>be the same as:
>> @m = list(5);
>>
>>
>
>The RHS of an array assignment is in list context. "list" is an operator
>that does nothing more than force list context. In this case, it is
>entirely redundant. But, of course, valid.
>
>

Of course it works that way. Why else would there be a want() function?


-- Rod Adams

Juerd

unread,
May 27, 2005, 10:41:43 AM5/27/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-05-27 16:22 (+0200):
> This argumentation breaks down as soon as you regard &infix:{'='} as
> an operator like many others.

Which we don't, making this discussion much easier for everyone.

Juerd

unread,
May 27, 2005, 10:46:53 AM5/27/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-05-27 15:44 (+0200):
> Could the ones who know it, enlighten me *why* it has to be so?
> What does it buy the newbie, average, expert Perl6 programmer?
> The answer "that's how Perl5 did it" is a good default, but
> never hindered @Larry to change things.

Because the alternative is to drop context.

If we drop context, we have to use an array where we now use a list. And
"list" automatically becomes an alias for "array" in our jargon.

Also, arrays will then probably no longer have any referenceless
version, and always be objects and thus references.

Then we lose the point for having different sigils, and everything gets
a dollar sign.

The end result is very different from Perl, and can no longer be thought
of even as derrived from Perl, in my opinion.