Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

\(...)?

1 view
Skip to first unread message

Ingo Blechschmidt

unread,
Sep 6, 2005, 1:46:57 PM9/6/05
to perl6-l...@perl.org
Hi,

# Perl 5
my @array_of_references = \($foo, $bar, $baz);
print 0+@array_of_references; # prints 3
print ${ $array_of_references[1] }; # prints $bar

# Perl 6
my @array = \($foo, $bar, $baz);
say +@array;
# 3 (like Perl 5)?
# Or 1, making \(...) similar to [...]?

If \(...) still constructs a list of references, are the following
assumptions correct?

\(@array); # same as
\@array;
# (As () is only used for grouping in this case.)
# Correct?

\(@array,); # same as
map { \$_ } @array;
# (As &postcircumfix:{'\\(', ')'} is called here.)
# Correct?


--Ingo

--
Linux, the choice of a GNU | Row, row, row your bits, gently down
generation on a dual AMD | the stream...
Athlon! |

Juerd

unread,
Sep 6, 2005, 3:15:18 PM9/6/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo Blechschmidt skribis 2005-09-06 19:46 (+0200):

> If \(...) still constructs a list of references, are the following
> assumptions correct?

IIRC, the RHS of \ is in scalar context, and the comma in scalar context
(the parens are just for precedence), creates an arrayref.

Which is interesting (and imho, a bad idea), because:

> \(@array); # same as

\(@array) and \@array are the same thing

> \(@array,); # same as

\(@array,) is [ @array ], NOT map { \$_ } @array


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

Ingo Blechschmidt

unread,
Sep 6, 2005, 3:24:40 PM9/6/05
to perl6-l...@perl.org
Hi,

Juerd wrote:
> Ingo Blechschmidt skribis 2005-09-06 19:46 (+0200):
>> If \(...) still constructs a list of references, are the following
>> assumptions correct?
>
> IIRC, the RHS of \ is in scalar context, and the comma in scalar
> context (the parens are just for precedence), creates an arrayref.
>
> Which is interesting (and imho, a bad idea), because:
>
>> \(@array); # same as
>
> \(@array) and \@array are the same thing

Agreed.

>> \(@array,); # same as
>
> \(@array,) is [ @array ], NOT map { \$_ } @array

I'm not sure of the []s, remember &postcirumfix:<[ ]> creates *new*
containers:

[@array][0] = $bar;
# @array[0] unchanged

Compare this to:

(@array,)[0] = $bar;
# @array[0] changed to $bar

So, I think, if we ditch Perl 5's special \(...),

\(@array,); # should be the same as
\do { (@array,) };

This has the consequence that

(\(@array,))[0] = $bar;

changes @array[0].


--Ingo

--
Linux, the choice of a GNU | Mr. Cole's Axiom: The sum of the
generation on a dual AMD | intelligence on the planet is a constant;
Athlon! | the population is growing.

Larry Wall

unread,
Sep 7, 2005, 12:05:43 PM9/7/05
to perl6-l...@perl.org
We can do whatever we like with \ since it's really a *macro* that
imposes lvalue context (or at least, indirection in the abstract, if
we were ever to allow it in an outer lvalue context). In the case of
\($a,$b) it is also distributing that context over the items in the
list without copying.

The only questions in my mind are whether Perl 5's \($a,$b) is
what people expect (it's arguably counterintuitive to newbies),
and whether there's some other construct that would more naturally
construct a list of references. It's not just \« though, since it
has to *parse* as a list of lvalues. Maybe a siglet can degenerate to
that, but there are problems with that approach too. Unless someone
can come up with a better proposal, \($a,$b) is the default winner
on the basis of prior Perl 5 art.

Larry

Juerd

unread,
Sep 7, 2005, 1:11:36 PM9/7/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo Blechschmidt skribis 2005-09-06 21:24 (+0200):

> > \(@array,) is [ @array ], NOT map { \$_ } @array
> I'm not sure of the []s, remember &postcirumfix:<[ ]> creates *new*
> containers:

That was the point.

> [@array][0] = $bar;
> (@array,)[0] = $bar;

AFAIK, these are the same thing, because the left side of [0] is in
Array context, which is a scalar context, in which comma creates a new
anonymous array ref.

Ingo Blechschmidt

unread,
Sep 9, 2005, 7:59:52 AM9/9/05
to perl6-l...@perl.org
Hi,

Juerd <juerd <at> convolution.nl> writes:
> Ingo Blechschmidt skribis 2005-09-06 21:24 (+0200):
> > > \(@array,) is [ @array ], NOT map { \$_ } @array
> > I'm not sure of the []s, remember &postcirumfix:<[ ]> creates *new*
> > containers:
>
> That was the point.
>
> > [@array][0] = $bar;
> > (@array,)[0] = $bar;
>
> AFAIK, these are the same thing, because the left side of [0] is in
> Array context, which is a scalar context, in which comma creates a new
> anonymous array ref.

To prevent misconceptions: You think that both

[@array][0] = $bar; # and
(@array,)[0] = $bar;

change @array[0] to $bar, right?

If so, I have to disagree. Consider:

(my $arrayref = [1,2,3])[1] = 42;

If &postcircumfix:<[ ]> did *not* create new containers, this
statement would fail ("Can't modify constant item 2") instead of
setting $arrayref[1] to 42.

Similarily,

(my $arrayref = [$foo])[0] = 42;

would not set $arrayref[0] to 42 and leave $foo untouched, but
would set $foo to 42. I don't think this is correct.


To clarify my view with code: I think &postcirumfix:<[ ]> could
be implemented like this:

sub *postcircumfix:<[ ]> (*@elems) {
# Explicitly copy @elems:
my @array = @elems;
return \@array;
}

And, presuming that I've understood you correctly, then you
would implement &postcirumfix:<[ ]> like this:

sub *postcircumfix:<[ ]> (*@elems) {
# Do *not* copy @elems here
return \@elems;
}


(But note that I may be completely wrong, of course.)


--Ingo

Juerd

unread,
Sep 9, 2005, 8:35:07 AM9/9/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo Blechschmidt skribis 2005-09-09 11:59 (+0000):

> > > > \(@array,) is [ @array ], NOT map { \$_ } @array
> > > I'm not sure of the []s, remember &postcirumfix:<[ ]> creates *new*
> > > containers:
> > That was the point.
> > > [@array][0] = $bar;
> > > (@array,)[0] = $bar;
> > AFAIK, these are the same thing, because the left side of [0] is in
> > Array context, which is a scalar context, in which comma creates a new
> > anonymous array ref.
> To prevent misconceptions: You think that both
> [@array][0] = $bar; # and
> (@array,)[0] = $bar;
> change @array[0] to $bar, right?

No, neither does.

[@array][0] = $bar fills a new array with the elements of @array, and then
overwrites the first. The array is then discarded.

(@array,)[0] = $bar does the same, IIRC, because the LHS of .[0] is
object and thus scalar context, possibly specifically Array context, and
the comma operator then behaves as if it has [] around it: it creates an
anonymous array. Again, it's just the elements of @array that are used.

Now, (@array)[0] = $bar does assign to @array[0].

I think the comma operator in scalar context should not create arrays,
because that is wildly confusing for most people, and a dangerous trap
even for those who do grok it. We already have [] for creating anonymous
arrays, and here a second WTDI isn't buying us anything. Especially the
apparent similarity in the different (@array) and (@array,) is something
we should try to avoid.

> (my $arrayref = [1,2,3])[1] = 42;

[1, 42, 3]. With () for grouping, not lists, and [] working on
references as well as the original, you're assigning to $arrayref[1],
not the nonexistent second element of the nonexistent list.

> sub *postcircumfix:<[ ]> (*@elems) {

Do postfix list operators exist in Perl 6? AFAIK, the only thing that
can create a list is list context, and I'm very unsure how anything that
can handle both a list and an item can be postfix.



> And, presuming that I've understood you correctly

Which I don't think you have.

Ingo Blechschmidt

unread,
Sep 9, 2005, 9:12:19 AM9/9/05
to perl6-l...@perl.org
Hi,

Juerd wrote:
> Ingo Blechschmidt skribis 2005-09-09 11:59 (+0000):
>> > > > \(@array,) is [ @array ], NOT map { \$_ } @array
>> > > I'm not sure of the []s, remember &postcirumfix:<[ ]> creates
>> > > *new* containers:
>> > That was the point.
>> > > [@array][0] = $bar;
>> > > (@array,)[0] = $bar;
>> > AFAIK, these are the same thing, because the left side of [0] is in
>> > Array context, which is a scalar context, in which comma creates a
>> > new anonymous array ref.
>> To prevent misconceptions: You think that both
>> [@array][0] = $bar; # and
>> (@array,)[0] = $bar;
>> change @array[0] to $bar, right?
>
> No, neither does.
>
> [@array][0] = $bar fills a new array with the elements of @array, and
> [then
> overwrites the first. The array is then discarded.

Agreed.

> (@array,)[0] = $bar does the same, IIRC, because the LHS of .[0] is
> object and thus scalar context, possibly specifically Array context,
> and the comma operator then behaves as if it has [] around it: it
> creates an anonymous array. Again, it's just the elements of @array
> that are used.

Ah! I think I got your point now! :)

I agree that the comma operator creates an anonymous array, but I do not
agree that it behaves as if it has [] around it.

Creating an anonymous array does not require creating new containers --
if I've understood things correctly, then the comma operator creates
arrayrefs (in appropriate contexts), but does *not* create new
containers. By contrast, the [] operator always creates arrayrefs
holding new containers.

(The comma operator *may not* create new container containers, because

($foo, $bar)[1] = $baz;

should change $bar to $baz (you reminded me of this property of
&infix:<,> in
http://www.nntp.perl.org/group/perl.perl6.language/22924).)

> Now, (@array)[0] = $bar does assign to @array[0].

Of course, as in this case neither the comma operator nor the []
operator is used, the () are only used for grouping.

> I think the comma operator in scalar context should not create arrays,
> because that is wildly confusing for most people, and a dangerous trap
> even for those who do grok it. We already have [] for creating
> anonymous arrays, and here a second WTDI isn't buying us anything.

I'd probably agree *if* &cirumfix:<[ ]> and &infix:<,> really did the
same thing (creating arrays containing new containers), but, IIUC,
&infix:<,> does not create new containers while &postcirumfix:<[ ]>
does.

>> (my $arrayref = [1,2,3])[1] = 42;
>
> [1, 42, 3]. With () for grouping, not lists, and [] working on
> references as well as the original, you're assigning to $arrayref[1],
> not the nonexistent second element of the nonexistent list.

I agree.

>> sub *postcircumfix:<[ ]> (*@elems) {
>
> Do postfix list operators exist in Perl 6? AFAIK, the only thing that
> can create a list is list context, and I'm very unsure how anything
> that can handle both a list and an item can be postfix.

D'oh, I meant &circumfix:<[ ]>, not &postcircumfix:<[ ]>.

&circumfix:<[ ]> is the operator used in [1,2,3], &postcirumfix:<[ ]> is
the operator used in @array[$index].


--Ingo

Juerd

unread,
Sep 9, 2005, 10:40:11 AM9/9/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo Blechschmidt skribis 2005-09-09 15:12 (+0200):

> I agree that the comma operator creates an anonymous array, but I do not
> agree that it behaves as if it has [] around it.
>
> Creating an anonymous array does not require creating new containers --

So comma in scalar context creates an array of aliases? That would be a
welcome difference.

> should change $bar to $baz (you reminded me of this property of
> &infix:<,> in

Infix? Infix operators are binary, comma is not.

> > I think the comma operator in scalar context should not create arrays,

Provided the new insight about comma creating an array of aliases rather
than copies, I retract this.

Larry Wall

unread,
Sep 9, 2005, 11:02:07 AM9/9/05
to perl6-l...@perl.org
On Fri, Sep 09, 2005 at 04:40:11PM +0200, Juerd wrote:
: Ingo Blechschmidt skribis 2005-09-09 15:12 (+0200):

: > I agree that the comma operator creates an anonymous array, but I do not
: > agree that it behaves as if it has [] around it.
: >
: > Creating an anonymous array does not require creating new containers --
:
: So comma in scalar context creates an array of aliases? That would be a
: welcome difference.

It might at that. Though doubtless there is a downside I'm not seeing yet...

Larry

Ingo Blechschmidt

unread,
Sep 9, 2005, 10:58:37 AM9/9/05
to perl6-l...@perl.org
Hi,

Juerd wrote:
> Ingo Blechschmidt skribis 2005-09-09 15:12 (+0200):
>> I agree that the comma operator creates an anonymous array, but I do
>> not agree that it behaves as if it has [] around it.
>>
>> Creating an anonymous array does not require creating new containers
>> --
>
> So comma in scalar context creates an array of aliases?

Exactly! :)

(Presuming that I understood things correctly, of course.)

> That would be a welcome difference.

I like that behaviour, too. :)

>> should change $bar to $baz (you reminded me of this property of
>> &infix:<,> in
>
> Infix? Infix operators are binary, comma is not.

I took the name from Pugs's PIL. The signature of &infix:<,> is (*@xs),
so it isn't strictly binary, of course.

I think the name &infix:<,> is based on the names of the chained
comparators:

1 < 2 < 3; # is really
&infix:{"<"}(1, 2, 3);

(This is, as far as I know, not specced. Take it as an report on Pugs's
internals.)


--Ingo

--

Linux, the choice of a GNU | Row, row, row your bits, gently down

generation on a dual AMD | stream...
Athlon! |

Ingo Blechschmidt

unread,
Sep 9, 2005, 11:35:42 AM9/9/05
to perl6-l...@perl.org
Hi,

($foo, $bar) = ($grtz, $baka);
say $foo, $bar;
# <newbie>Hm, $foo and $bar are changed to $grtz respectively
# $baka... So assigning to a list really assigns to the
# elements of the list! So the comma operator constructs
# a list of aliases, neat!

# Now let's see whether the following works as well:
($foo, $bar)[0] = $grtz;
# Ok, no error message.

say $foo;
# ...but why was $foo not changed?
# I thought the comma operator constructs a list of
# aliases...?</newbie>

Also note that the comma operator creating a list of aliases does *not*
affect regular [...] or assignment to an array:

(1,2,3)[1]++; # "Can't modify constant item 2"

my @a = (1,2,3); # @a's STORE method recognized that the RHS
# is an aggregate, so it created new containers.
@a[1]++; # No error
say @a[1]; # 3

[1,2,3][1]++; # No error, &circumfix:<[ ]> assigned to an
# array internally, so new containers were
# created.

--Ingo

--

Linux, the choice of a GNU | Row, row, row your bits, gently down

generation on a dual AMD | the stream...
Athlon! |

Larry Wall

unread,
Sep 9, 2005, 11:58:22 AM9/9/05
to perl6-l...@perl.org
On Fri, Sep 09, 2005 at 05:35:42PM +0200, Ingo Blechschmidt wrote:
: my @a = (1,2,3); # @a's STORE method recognized that the RHS

: # is an aggregate, so it created new containers.

The decision to copy is made by the =, not by @a. This also copies:

($a,$b) = ($b,$a)

This is how Perl 5 assignment works, and we're trying not to break that...

Larry

Larry Wall

unread,
Sep 9, 2005, 12:05:24 PM9/9/05
to perl6-l...@perl.org
On Fri, Sep 09, 2005 at 04:58:37PM +0200, Ingo Blechschmidt wrote:
: Hi,
:
: Juerd wrote:
: > Infix? Infix operators are binary, comma is not.

That infix operators are always binary is just a cultural assumption
based on the historical restriction to right-associative and
left-associative operators. But we've now got list-associative as
well, which is one of the reasons we changed the syntactic category
from binop: to infix: instead. (And also because uniop: didn't distinguish
prefix from postfix operators.)

: I took the name from Pugs's PIL. The signature of &infix:<,> is (*@xs),


: so it isn't strictly binary, of course.

Infix is fine for that. The associativity is a trait of the operator
that doesn't appear in a mere reference to it.

: I think the name &infix:<,> is based on the names of the chained


: comparators:
:
: 1 < 2 < 3; # is really
: &infix:{"<"}(1, 2, 3);
:
: (This is, as far as I know, not specced. Take it as an report on Pugs's

Which is also, of course, what

[<] 1,2,3

turns into--unless it just turns directly into bool::true. :-)

Larry

Juerd

unread,
Sep 9, 2005, 12:09:55 PM9/9/05
to perl6-l...@perl.org
Larry Wall skribis 2005-09-09 8:58 (-0700):

> The decision to copy is made by the =, not by @a. This also copies:
> ($a,$b) = ($b,$a)
> This is how Perl 5 assignment works, and we're trying not to break that...

This is all true.

However, back to the scalar case, assuming the comma/alias thing:

my $a = [ $foo, $bar ]; # RHS copies values

my $a = ($foo, $bar); # RHS does not copy values

my @a = ($foo, $bar); # RHS does not copy values: consistent

It is fun to see that my whitespace style (whitespace in constructors,
but not in parens, because they do not construct) works very well in
Perl 6: it is not the parens that construct the array in scalar context,
it is something else.

Ingo Blechschmidt

unread,
Sep 11, 2005, 9:32:02 AM9/11/05
to perl6-l...@perl.org
Hi,

Larry Wall wrote:
> The only questions in my mind are whether Perl 5's \($a,$b) is
> what people expect (it's arguably counterintuitive to newbies),
> and whether there's some other construct that would more naturally
> construct a list of references. It's not just \« though, since it
> has to *parse* as a list of lvalues. Maybe a siglet can degenerate to
> that, but there are problems with that approach too. Unless someone
> can come up with a better proposal, \($a,$b) is the default winner
> on the basis of prior Perl 5 art.

So...:

\@array; # Ref to array

\(@array); # List of refs to @array's elements, i.e. same as
map { \$_ } @array;
# Weird (violating the "parens are only for grouping" rule), but
# consistent with Perl 5.

Correct?


--Ingo

--
Linux, the choice of a GNU | Row, row, row your bits, gently down the
generation on a dual AMD | stream...
Athlon! |

TSa

unread,
Sep 19, 2005, 4:52:28 AM9/19/05
to perl6-l...@perl.org
HaloO,

Ingo Blechschmidt wrote:
> \@array; # Ref to array
>
> \(@array); # List of refs to @array's elements, i.e. same as
> map { \$_ } @array;
> # Weird (violating the "parens are only for grouping" rule), but
> # consistent with Perl 5.
>
> Correct?

I opt for 'no'. () should just group and \((((@array)))) is a sillily
written arrayref. If you want @array to flatten lazily for enreferencing
this should be \(*@array) which works without parens as well: \*@array
---and is one char shorter than \(@array). And of course there is eager
flattening enreferencing: \**@array.

BTW, I like the ubiquitous interpretation of prefix * as infinite arity
marker at call sites as above and in sig definitions.
--
$TSa.greeting := "HaloO"; # mind the echo!

TSa

unread,
Sep 19, 2005, 7:01:36 AM9/19/05
to perl6-l...@perl.org
HaloO Larry,

you wrote:
> We can do whatever we like with \ since it's really a *macro* that

Could you explain me the rational why \ and other ops like =,
:= are not normal overloadable, possibly MMD operators?


> imposes lvalue context (or at least, indirection in the abstract, if
> we were ever to allow it in an outer lvalue context). In the case of
> \($a,$b) it is also distributing that context over the items in the
> list without copying.

With the precedence of \ higher than that of comma the parens are
again needed to prevent the parsing as ((\ $a),($b)). Thus with
a multi \ in mind \($a,$b) just dispatches to the list version
of \. Since comma builds a lazy list the $a and $b are not evaluated
right on the spot.


> The only questions in my mind are whether Perl 5's \($a,$b) is
> what people expect (it's arguably counterintuitive to newbies),
> and whether there's some other construct that would more naturally
> construct a list of references. It's not just \« though, since it
> has to *parse* as a list of lvalues.

Why does it have to parse as lvalue list? My understanding of List
as Code subtype means that handling a lazy list means traversing
or iterating it. Why shouldn't there be a lvalue traversal that
in the end makes

($x, $y) = \($a, $b);

actually mean

$x = \$a; $y = \$b;

My point revolves around the question: "how much snapshotting does
lazy list creation perform?". I mean it's clear that

$val_snap = ($a, $b); # List of Item

prevents the content of $a and $b become invalid (but the variables
could be made to point elsewhere of course). Then

say $val_snap;

should just produce the same result as

say $a, $b;

while

$ref_snap = \($a, $b); # either: Ref of List of Item
# or: List of Ref of Item
hooks onto the containers and

say $ref_snap;

well either prints info about $ref_snap beeing a (list of) ref(s)
or is so kind to deref it and print the content of $a and $b at that
time. So the only thing we have to agree on the type of &prefix:<\>.
Either it is the generic :(List of Item --> Ref of List of Item) or
the more Perl 5 stylish :(List of Item --> List of Ref of Item).

The above distinction between Ref of List and List of Ref then
needs to be reflected almost everywhere. Basically the choice we
have to make is if \($a,$b) is primarily a List or a Ref :)
The respective other info can then be found by derefing or
iteration.

> Maybe a siglet can degenerate to
> that, but there are problems with that approach too. Unless someone
> can come up with a better proposal, \($a,$b) is the default winner
> on the basis of prior Perl 5 art.

I actually like \($a,$b) and I hope it means the same as \ ($a,$b)
note the whitespace!

Ingo Blechschmidt

unread,
Sep 19, 2005, 10:21:43 AM9/19/05
to perl6-l...@perl.org
Hi,

TSa <Thomas.Sandlass <at> orthogon.com> writes:
> Ingo Blechschmidt wrote:
> > \@array; # Ref to array
> >
> > \(@array); # List of refs to @array's elements, i.e. same as
> > map { \$_ } @array;
> > # Weird (violating the "parens are only for grouping" rule), but
> > # consistent with Perl 5.
> >
> > Correct?
>
> I opt for 'no'. () should just group and \((((@array)))) is a sillily
> written arrayref. If you want @array to flatten lazily for enreferencing
> this should be \(*@array) which works without parens as well: \*@array
> ---and is one char shorter than \(@array). And of course there is eager
> flattening enreferencing: \**@array.

I like this very much! :)

> BTW, I like the ubiquitous interpretation of prefix * as infinite arity
> marker at call sites as above and in sig definitions.

I agree completely :).

I'd like to violate the "parens are only for grouping" rule only if
absolutely necessary, and make more use of prefix *.

So...:

\@array; # Reference to array, of course
\(@array); # same
\(((@array))); # same

\(1,2,3); # Reference to a list promoted to an array (!)
\(((1,2,3))); # same

\*@array; # List of references to @array's elements
\*(((@array))); # same

\*(1,2,3); # List of references to @array's elements
\*(((1,2,3))); # same

Opinions?


--Ingo

Jonathan Scott Duff

unread,
Sep 19, 2005, 10:50:29 AM9/19/05
to Ingo Blechschmidt, perl6-l...@perl.org
On Mon, Sep 19, 2005 at 02:21:43PM +0000, Ingo Blechschmidt wrote:
> So...:
>
> \@array; # Reference to array, of course
> \(@array); # same
> \(((@array))); # same
>
> \(1,2,3); # Reference to a list promoted to an array (!)
> \(((1,2,3))); # same
>
> \*@array; # List of references to @array's elements
> \*(((@array))); # same
>
> \*(1,2,3); # List of references to @array's elements
> \*(((1,2,3))); # same
>
> Opinions?

Off the cuff, I'd say that works for me. Also, wouldn't we have this?

\list 1,2,3 # reference to a list promoted to an array

-Scott
--
Jonathan Scott Duff
du...@pobox.com

TSa

unread,
Sep 19, 2005, 11:05:46 AM9/19/05
to perl6-l...@perl.org
HaloO,

Ingo Blechschmidt wrote:
> So...:
>
> \@array; # Reference to array, of course
> \(@array); # same
> \(((@array))); # same
>
> \(1,2,3); # Reference to a list promoted to an array (!)
> \(((1,2,3))); # same

The thing that is unclear to me here and

> \*@array; # List of references to @array's elements
> \*(((@array))); # same
>
> \*(1,2,3); # List of references to @array's elements
> \*(((1,2,3))); # same

here is if you can write through the ref into a automagically created
array or not. I would like to maintain it as error case. Actually I
don't like to think of \(1,2,3) as array at all. Note that * is a no-op
in *(1,2,3) because it is already a list. Hence the cases should have the
same meaning.

Should [\] 1,2,3; be allowed? I know \ is no infix op and as such not
amenable to the list reducing itemizer. But it could allow the types

\ (1,2,3); # List of Ref of Int (which is a Code subtype)
[\] 1,2,3; # Ref of List of Int (which is an Item subtype)

But that might be too far fetched. Even the subtyping of List below Code
is not confirmed by @Larry.

TSa

unread,
Sep 19, 2005, 11:13:49 AM9/19/05
to perl6-l...@perl.org
HaloO,

Ingo Blechschmidt wrote:
> \*@array; # List of references to @array's elements
> \*(((@array))); # same

Yes, and of course

\((*((@array)))); # same
\ (* (@array)); # same

Well, until someone invents &infix:<(*> :)

Juerd

unread,
Sep 19, 2005, 11:15:08 AM9/19/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo Blechschmidt skribis 2005-09-19 14:21 (+0000):

> \(1,2,3); # Reference to a list promoted to an array (!)
> \(((1,2,3))); # same

Except that it has to be a reference to a reference, because (1,2)
(in scalar context) already evaluates to a reference, because it can't
be a pure array.

A list isn't a thing like an array. It's always the result of something:
list context.

Could you think of a formal specification of \ the way you want it, that
doesn't exist of only examples? What context does it give its RHS? What
do you want , in that comma to do? Are parens in any way special when
used with \? What is the precedence of \?

TSa

unread,
Sep 19, 2005, 12:16:30 PM9/19/05
to perl6-l...@perl.org
HaloO,

Juerd wrote:
> Could you think of a formal specification of \ the way you want it, that
> doesn't exist of only examples?

I can't speak for Ingo, but here's mine.


> What context does it give its RHS?

I still have difficulties to understand this concept
but I think that \ is simply

sub &*prefix:<\> (Item *$to_enref --> Ref ^ List[Ref]) {...}
# For the type inferencer it were a great thing to leave
# the hint that Item --> Ref and List --> List, but how do
# I write that? Is it (*$t, *@rest --> @rest ?? List !! Ref)?

with some low-level implementation performing the enreferencing
on the engine level. There will be some more details like the
precedence trait and a bunch of named params to define how the
enreferncing shall be performed. In particular if it is a writable
ref! The latter should then look e.g. as follows:

$x = \:rw $y; # (almost?) same as $x := $y


> What do you want , in that comma to do?

I don't understand that question. Comma does what it does---everywhere.
It syntactically instructs the compiler to generate code that builds
a list from the expressions that comma happens to separate.


> Are parens in any way special when used with \?

No. The generic rules apply. Hmm, which perhaps means that

\($x,$y); # same as \ .($x,$y)

returns a List of Ref, but

\ ($x,$y);

returns a Ref of List because the whitespace before (,)
forces the list into itemhood and as such is enreferenced
as a single thing. *But* both might evaluate to the same
thing later on anyway because deref and list iteration is
part of the default coercions in Perl6.


> What is the precedence of \?

Higher than comma.


The above "spec" actually can be applied to other ops as well.
E.g.

++($x,$y);

would work if ++ had an infinite arity signature and corresponding
implementation that handles list iteration. In other words operators
are in no way more special than

foo($x,$y);

which raises the question if for a unary

sub foo($item) {...}

hyperation works as expected:

foo« 1,2,3; # call &foo three times

Chromatic

unread,
Sep 19, 2005, 4:15:04 PM9/19/05
to TSa, perl6-l...@perl.org
On Mon, 2005-09-19 at 13:01 +0200, TSa wrote:

> Why shouldn't there be a lvalue traversal that
> in the end makes
>
> ($x, $y) = \($a, $b);
>
> actually mean
>
> $x = \$a; $y = \$b;

Does this not go from one sequence point (evaluate the rhs sufficiently,
then perform the lvalue assignments) to multiple sequence points? I'm
not sure you can always reason effectively about the lack of side
effects here.

-- c

Juerd

unread,
Sep 19, 2005, 4:19:25 PM9/19/05
to TSa, perl6-l...@perl.org
TSa skribis 2005-09-19 18:16 (+0200):

> sub &*prefix:<\> (Item *$to_enref --> Ref ^ List[Ref]) {...}
> # For the type inferencer it were a great thing to leave
> # the hint that Item --> Ref and List --> List, but how do
> # I write that? Is it (*$t, *@rest --> @rest ?? List !! Ref)?

Does the type "List" exist? What is it? How does it fit in the
hierarchy?

> >What do you want , in that comma to do?
> I don't understand that question. Comma does what it does---everywhere.

/in that comma/in that context/

> It syntactically instructs the compiler to generate code that builds
> a list from the expressions that comma happens to separate.

Well, that's not exactly accurate.

In list context, comma provides list context to LHS and RHS, and those
lists together are flattened. (It's not exactly binary, but it doesn't
hurt to explain it as such.)

In scalar context, commas provide scalar context to the expressions they
separate (or list context? If so, what to do with parenthesized
expressions?), and the entire thing is returned as a reference to a
newly created array (of aliases, perhaps).

What it does in void context is unimportant, but it would make sense if
it provided void context to each of the expressions.

Comma doesn't "build a list". Lists can only exist in list context, and
in fact, it's a list even without any comma:

my @foo = bar(); # here, what &bar returns is a list, without any
# comma.

> \($x,$y); # same as \ .($x,$y)

This would mean that \ is a function rather than a standard \W operator,
and that the parens here aren't the normal grouping parens, but instead
parens to enclose arguments. If this is the case, I suggest we rename \
to something that actually LOOKS like a function, that is: something
with a \w+ name. This all would imply that its precedence is lower than
comma.

TSa

unread,
Sep 20, 2005, 12:42:17 PM9/20/05
to perl6-l...@perl.org
HaloO chromatic,

I think you are right. I just used the two forms to illustrate my idea.
But since the default list is lazy while item evaluation is eager my
first case should probably be written as

**($x, $y) = \**($a,$b);

and even then might not give the interleaved execution sequence:

1: $x as lvalue
2: \$a as rvalue
3: $y as lvalue
4: \$b as rvalue

but 1,3,2,4. OTOH, it is the programmer's choice. The only thing that
he should be aware of is how much undeterminsm is in which alternative.

And I wonder if

[=] **zip( $x, $y ; \($a,$b) );

results in the 1,2,3,4 sequence deterministically.

TSa

unread,
Sep 20, 2005, 1:06:52 PM9/20/05
to perl6-l...@perl.org
HaloO Juerd,

you wrote:
> Does the type "List" exist? What is it? How does it fit in the
> hierarchy?

I've put it below Sub in my type lattice. But that is not official,
of course.


> In list context, comma provides list context to LHS and RHS, and those
> lists together are flattened. (It's not exactly binary, but it doesn't
> hurt to explain it as such.)
>
> In scalar context, commas provide scalar context to the expressions they
> separate (or list context? If so, what to do with parenthesized
> expressions?), and the entire thing is returned as a reference to a
> newly created array (of aliases, perhaps).
>
> What it does in void context is unimportant, but it would make sense if
> it provided void context to each of the expressions.
>
> Comma doesn't "build a list". Lists can only exist in list context, and
> in fact, it's a list even without any comma:

Please help me to understand how the context starts to exist.
I currently see a circular definition of comma and list context
in your explaination. I for my part try to break it with the
strict notion: "when you see a comma you are looking at a list".
What list is up to more text to the left and right of the comma.
And I believe the parser essentially does the same.


> my @foo = bar(); # here, what &bar returns is a list, without any
> # comma.

That @foo is of syntactic type Array is clear. That bar is called
without parameters is obvious as well. But where do you derive the
the return type from? That could at most come from type information
of bar e.g. :( Void --> Blubber) and then the question arises if
a Blubber is assignable to an Array or not. Well, or if a Blubber
can listify. Or as a fall-back itemize with the item beeing trivially
listified as a one element list which then ends up providing the sole
content of the @foo.


>> \($x,$y); # same as \ .($x,$y)
>
>
> This would mean that \ is a function rather than a standard \W operator,
> and that the parens here aren't the normal grouping parens, but instead
> parens to enclose arguments. If this is the case, I suggest we rename \
> to something that actually LOOKS like a function, that is: something
> with a \w+ name. This all would imply that its precedence is lower than
> comma.

Ups, I always thought that this is what all the operator categories
and related things are for: to get an easy way to define operators!
E.g. after

my &foo ::= &prefix:<\>;

enreferencing should work with

($x,$y) = foo($a,$b);

or not?

Juerd

unread,
Sep 20, 2005, 2:47:49 PM9/20/05
to TSa, perl6-l...@perl.org
TSa skribis 2005-09-20 19:06 (+0200):

> Please help me to understand how the context starts to exist.

What do you mean?

Do you want to know what things provide list context?

- hash assignment
- array assignment
- arrayref constructor []
- hashref constructor {}
- slurpy parameters
- list assignment (indeed circular... anyone?)

> strict notion: "when you see a comma you are looking at a list".

But that's not if and only if. What other ways are there to create
lists? Please take into account the entire Perl 6 world, not just the
subsubject at hand (comma operator).

> >my @foo = bar(); # here, what &bar returns is a list, without any
> > # comma.
> That @foo is of syntactic type Array is clear. That bar is called
> without parameters is obvious as well. But where do you derive the
> the return type from?

List is not a type. The return *type* is not visible in this snippet.
However, what is returned, is a list.

Lists are ordered collections of scalars. The elements can have types,
a list itself cannot.

bar() evaluates to a list because it is in list context. List context
here is created by the array assignment.

There is no such thing as "returns List" or "--> List", because there is
no type List. List thus also does not have sub or super types.

> That could at most come from type information of bar e.g. :( Void -->
> Blubber) and then the question arises if a Blubber is assignable to an
> Array or not. Well, or if a Blubber can listify.

Assignable to arrays is everything, because everything can be in list
context and then form a list. A single scalar, when in list context,
forms a list of one element.

Because there is no List type, there is also no such thing as coercion
to or from List. "Listification" is a useless word IMO, but I guess it
could be used to describe things that are in list context: in this case,
everything can "listify".

> my &foo ::= &prefix:<\>;
> enreferencing should work with
> ($x,$y) = foo($a,$b);
> or not?

I think this works, but I was discussing syntax: the function of parens
after \, and how to look at \ compared to other \W and \w+ operators,
syntax wise.

Ingo Blechschmidt

unread,
Sep 21, 2005, 11:24:38 AM9/21/05
to perl6-l...@perl.org
Hi,

(sorry for the long delay.)

Juerd <juerd <at> convolution.nl> writes:

> Ingo Blechschmidt skribis 2005-09-19 14:21 (+0000):
> > \(1,2,3); # Reference to a list promoted to an array (!)
> > \(((1,2,3))); # same
>
> Except that it has to be a reference to a reference, because (1,2)
> (in scalar context) already evaluates to a reference, because it can't
> be a pure array.

See my definition of &prefix:<\> below. Parentheses used for grouping
do not change the context.

> Could you think of a formal specification of \ the way you want it,
> that doesn't exist of only examples? What context does it give its
> RHS?

multi prefix:<\> (Item $item) {...}
multi prefix:<\> (@array) {...}
multi prefix:<\> (%hash) {...}
# (The necessary magic needed for dealing with the proposed
# \*@array, which would be equivalent to map { \$_ } @array,
# is not included here.)

So:

\$obj; # $obj in item context
\@array; # @array in Array context (so @array doesn't auto-ref
# to a reference to itself, which would cause the problem
# you mentioned (that \@array would evaluate to a ref
# pointing to a ref))
\%hash; # analogous

> What do you want , in that comma to do?

sub infix:<,> (*@things is rw) { @things }
# The "is rw" should refer to the parameters, i.e.
# &infix:<,> returns aliases:
# ($a, $b)[0] = $c; # same as $a = $c
# ($a, $b)[0] =:= $a; # true

So the comma operator supplies list context to its arguments (because
of the slurpy @things) and returns an array. It can't return a list,
because, as you've said, lists aren't real data types.

Because the comma operator supplies list context, (@a, @b) flattens
@a and @b, so it's like @a.concat(@b).

(Of course, there is still the comma operator which separates arguments.
This operator is not the &infix:<,> we talk about, e.g.:

foo(1,2,3); # &infix:<,> *not* called
foo (1,2,3); # same as
foo( (1,2,3) ); # &infix:<,> called

(BTW, is the argument-separator comma operator accessible by a
subroutine, like most other operators are? (I think not.)))

> Are parens in any way special when used with \?

No:

\($obj); # same as
\$obj;

\((($obj))); # same as
\$obj;

\($a, $b); # same as
do {
my @temp = ($a, $b);
\@temp;
}

\((($a, $b))); # is really
prefix:<\>(((($a, $b)))); # is really
prefix:<\>( ($a, $b) ); # is really
# (Inner parentheses needed to prevent the comma to be treated
# as the other comma operator which separates arguments.)
prefix:<\>(&infix:<,>($a, $b)); # same as
do {
my @temp = ($a, $b);
\@temp;
}

> What is the precedence of \?

The comma operator should bind tighter than \:

\$a, $b # same as
(\$a), $b


BTW, &list ::= &infix:<,>:

($a,); # could be considered ugly
list $a; # same effect, but could be considered not ugly


I hope this mail makes sense :)


--Ingo

Matt Fowles

unread,
Sep 21, 2005, 11:37:32 AM9/21/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo~

On 9/21/05, Ingo Blechschmidt <ibl...@web.de> wrote:
>
> foo(1,2,3); # &infix:<,> *not* called
> foo (1,2,3); # same as
> foo( (1,2,3) ); # &infix:<,> called

Do you mean this to read?

foo(1,2,3); # &infix:<,> *not* called

foo .(1,2,3); # &infix:<,> *not* called

foo (1,2,3); # &infix:<,> called


foo( (1,2,3) ); # &infix:<,> called

Matt
--
"Computer Science is merely the post-Turing Decline of Formal Systems Theory."
-Stan Kelly-Bootle, The Devil's DP Dictionary

Ingo Blechschmidt

unread,
Sep 21, 2005, 1:44:49 PM9/21/05
to perl6-l...@perl.org
Hi,

Matt Fowles wrote:
> On 9/21/05, Ingo Blechschmidt <ibl...@web.de> wrote:
>> foo(1,2,3); # &infix:<,> *not* called
>> foo (1,2,3); # same as
>> foo( (1,2,3) ); # &infix:<,> called
>
> Do you mean this to read?
>
> foo(1,2,3); # &infix:<,> *not* called
> foo .(1,2,3); # &infix:<,> *not* called
>
> foo (1,2,3); # &infix:<,> called
> foo( (1,2,3) ); # &infix:<,> called

Right. Should have added an extra \n.


--Ingo

Juerd

unread,
Sep 21, 2005, 2:09:54 PM9/21/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo Blechschmidt skribis 2005-09-21 17:24 (+0200):

> multi prefix:<\> (Item $item) {...}
> multi prefix:<\> (@array) {...}
> multi prefix:<\> (%hash) {...}

I keep forgetting. What's the rule for determining that the (Item $item)
is used, rather than (@array), when one uses \$aref? It'd be bad if
$aref dereferenced first :)

Is "Item" really a type? Isn't the type actually Scalar? (I thought one
of the reasons to use "item context" instead of "scalar context" was
that "Scalar" and "scalar" looked too much alike -- having both "item"
and "Item" would reintroduce this problem.)

> # (The necessary magic needed for dealing with the proposed
> # \*@array, which would be equivalent to map { \$_ } @array,
> # is not included here.)

Also, the magic for handling multiple arguments is missing.

What's the syntax for accepting a variable number of arguments, each of
which can be anything, regardless of context? How do you find out what
you got (array or scalar)?

Does it even make sense to implement \ in Perl? Does it make sense to
try and figure out a Perl signature for it?

> Because the comma operator supplies list context, (@a, @b) flattens
> @a and @b, so it's like @a.concat(@b).

Ah, comma supplies list context regardless of the context the comma is
in? Is this current, or part of your proposal? I thought comma would
propagate context.

> BTW, &list ::= &infix:<,>:

This clarifies much. Thanks.

Ingo Blechschmidt

unread,
Sep 21, 2005, 2:47:01 PM9/21/05
to perl6-l...@perl.org
Hi,

Juerd wrote:
> Ingo Blechschmidt skribis 2005-09-21 17:24 (+0200):
>> multi prefix:<\> (Item $item) {...}
>> multi prefix:<\> (@array) {...}
>> multi prefix:<\> (%hash) {...}
>
> I keep forgetting. What's the rule for determining that the (Item
> $item) is used, rather than (@array), when one uses \$aref? It'd be
> bad if $aref dereferenced first :)

IIRC the rules aren't really there yet (but there're various proposals).
But, as you say, the rules will have to make sure that \@array calls the
&prefix:<\> with the signature of (@array).

> Is "Item" really a type?

I think so, see http://use.perl.org/~autrijus/journal/25337,
http://use.perl.org/~autrijus/journal/25365, and some
http://svn.openfoundry.org/pugs/examples/:
> Any is now really Any (includes Junction);
> the role hierarchy looks like this:
> Any
> / \
> Item Junction

>> # (The necessary magic needed for dealing with the proposed
>> # \*@array, which would be equivalent to map { \$_ } @array,
>> # is not included here.)
>
> Also, the magic for handling multiple arguments is missing.

This magic isn't needed, as there is no way to pass multiple arguments
to &prefix:<\> (except by explicitly calling &prefix:<\>, of course):

\(1,2,3); # is really
\infix:<,>(1,2,3); # thus &prefix:<\> gets a single array,
# not three arguments.

> What's the syntax for accepting a variable number of arguments, each
> of which can be anything, regardless of context? How do you find out
> what you got (array or scalar)?

I'm not 100% sure what you mean by "regardless of context" in this, err,
context, but I'll try anyway:

# Naive approach (doesn't work)
sub foo (*@args) {...}

foo @array_containing_only_one_element;
foo @array_containing_only_one_element[0];
# XXX -- &foo can't tell the difference between these two
# invocations.


# Better approach
multi bar (@array) {...}
multi bar (*@args) {...}

bar @array_containing_only_one_element; # first variant called
bar @array_containing_only_one_element[0]; # second variant called


# But I don't think it's possible to make
bar @foo, @baz;
# cause @args to be bound to (\@foo, \@baz), as slurpy parameters
# automatically flatten @?ARGUMENTS (unspecced variable).
# I started a thread about this a while ago, but can't find a link
# to it...

> Does it even make sense to implement \ in Perl? Does it make sense to
> try and figure out a Perl signature for it?

It definitely makes sense to figure out an appropriate signature, as
a signature can help us to better understand what context \ supplies
to its parameters, how many arguments it accepts, etc.

It may or not may make sense to actually implement &prefix:<\> in Perl,
depending on the compiler, the backend, and the runtime.

>> Because the comma operator supplies list context, (@a, @b) flattens
>> @a and @b, so it's like @a.concat(@b).
>
> Ah, comma supplies list context regardless of the context the comma is
> in? Is this current, or part of your proposal? I thought comma would
> propagate context.

Well, (@a, @b) always evaluated to "@a.concat(@b)", so I guess the
comma operator supplies list context even in the current spec:

my @c = (@a, @b); # same as @c = @a.concat(@b)
my $c = (@a, @b); # flattens @a and @b as well (but, of course,
# $c contains a reference after the assignment.)

&infix:<,> definitely supplies list context in my proposal, as
&infix:<,> has a signature of (*@xs), and slurpy parameters supply
list context. (See, figuring out &infix:<,>'s signature does make
sense :))

> This clarifies much. Thanks.

:)


--Ingo

0 new messages