Effective February 22, 2024, Google Groups will no longer support new Usenet content. Posting and subscribing will be disallowed, and new content from Usenet peers will not appear. Viewing and searching of historical data will still be supported as it is done today.
Dismiss

Which brackets should @a.perl use?

3 views
Skip to first unread message

Markus Laker

unread,
Jan 3, 2009, 9:22:38 AM1/3/09
to perl6-l...@perl.org
This behaviour looks wrong to me:


msl@edward:~/perl/6$ cat ap1
#!/home/msl/bin/perl6

my @a = <blue light hazard>;
my $p = @a.perl;
say "\@a: {@a.elems} elements: $p";
say '@a[0]: ', @a[0];

my @b = eval $p;
say "\@b: {@b.elems} elements: $p";
say '@b[0]: ', @b[0];
say '@b[0][0]: ', @b[0][0];

msl@edward:~/perl/6$ ./ap1
@a: 3 elements: ["blue", "light", "hazard"]
@a[0]: blue
@b: 1 elements: ["blue", "light", "hazard"]
@b[0]: blue light hazard
@b[0][0]: blue
msl@edward:~/perl/6$ perl6 -v
This is Rakudo Perl 6, revision 34744 built on parrot 0.8.2-devel
for i486-linux-gnu-thread-multi.

Copyright 2006-2008, The Perl Foundation.

msl@edward:~/perl/6$


Because C<@a.perl> returns a string surrounded in square brackets, rather
than round brackets, C<eval> produces a list containing a single element:
we get one extra, unwanted level of indirection.

If C<@a.perl> were to return a string surrounded in round brackets, this
problem would be solved:


msl@edward:~/perl/6$ cat ap2
#!/home/msl/bin/perl6

my $p = '("blue", "light", "hazard")';

my @c = eval $p;
say "\@c: {@c.elems} elements: ", @c.perl;
say '@c[0]: ', @c[0];

my $c = eval $p;
say "\$c: {$c.elems} elements: ", $c.perl;
say '$c[0]: ', $c[0];

msl@edward:~/perl/6$ ./ap2
@c: 3 elements: ["blue", "light", "hazard"]
@c[0]: blue
$c: 3 elements: ["blue", "light", "hazard"]
$c[0]: blue
msl@edward:~/perl/6$


Is Rakudo's behaviour correct here?

Markus

mor...@casella.faui2k3.org

unread,
Jan 4, 2009, 12:13:39 PM1/4/09
to Markus Laker, perl6-l...@perl.org
> msl@edward:~/perl/6$ ./ap2
> @c: 3 elements: ["blue", "light", "hazard"]
> @c[0]: blue
> $c: 3 elements: ["blue", "light", "hazard"]
> $c[0]: blue
> msl@edward:~/perl/6$
>
>
> Is Rakudo's behaviour correct here?

S02 says:

"To get a Perlish representation of any object, use the .perl method. Like
the Data::Dumper module in Perl 5, the .perl method will put quotes around
strings, square brackets around list values,"

So according to this, Rakudo has it right.
But I think that a .perl()ification as ("blue", "light", "hayard",) would
make much more sense, because simple thing like

@a.push eval(@b.perl)

would then DWIM.

Chhers,
Moritz

Uri Guttman

unread,
Jan 4, 2009, 2:19:15 PM1/4/09
to mor...@casella.faui2k3.org, Markus Laker, perl6-l...@perl.org
>>>>> "m" == moritz <mor...@casella.faui2k3.org> writes:

m> S02 says:

m> "To get a Perlish representation of any object, use the .perl method. Like
m> the Data::Dumper module in Perl 5, the .perl method will put quotes around
m> strings, square brackets around list values,"

m> So according to this, Rakudo has it right.
m> But I think that a .perl()ification as ("blue", "light", "hayard",) would
m> make much more sense, because simple thing like

m> @a.push eval(@b.perl)

m> would then DWIM.

for your def of DWIM. i can see wanting an anon array to be pushed onto
@a building up a structure. your example is too simple to really cover
this as you could just push @b or a ref to @b (damn, i need to learn
more basic p6 syntax! :).

a more useful example would be serializing data trees. if you dump @b
with .perl do you want the current dumper output of a anon array or your
list of values? when serializing a tree, you must get the ref version so
that is the common and default usage. your version isn't DWIMmy there at
all.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------

Markus Laker

unread,
Jan 4, 2009, 4:06:02 PM1/4/09
to perl6-l...@perl.org
On Sun, 04 Jan 2009 14:19:15 -0500, Uri Guttman wrote:

>>>>>> "m" == moritz <mor...@casella.faui2k3.org> writes:
> m> But I think that a .perl()ification as ("blue", "light", "hayard",) would
> m> make much more sense, because simple thing like
>
> m> @a.push eval(@b.perl)
>
> m> would then DWIM.
>
> for your def of DWIM. i can see wanting an anon array to be pushed onto
> @a building up a structure.

That would be easily achievable if we made the change I'm suggesting, so
that C<@a.perl> emitted round brackets. This is how you would clone an
array, as Moritz wants to do:


msl@edward:~/perl/6$ cat uri1
#!/home/msl/bin/perl6

# Imagine that @b.perl has produced this:
my $p = "('blue', 'light', 'hazard')";

my @a;
@a.push(eval $p);
.say for @a;
msl@edward:~/perl/6$ ./uri1
blue
light
hazard
msl@edward:~/perl/6$


Adding a single backslash before `eval' pushes an anonymous array on to
@b, as you envisage wanting to do:


msl@edward:~/perl/6$ cat uri2
#!/home/msl/bin/perl6

# Imagine that @a.perl has produced this:
my $p = "('blue', 'light', 'hazard')";

my @b;
@b.push(\eval $p);
.say for @b;
msl@edward:~/perl/6$ ./uri2
blue light hazard
msl@edward:~/perl/6$


> a more useful example would be serializing data trees. if you dump @b
> with .perl do you want the current dumper output of a anon array or your
> list of values? when serializing a tree, you must get the ref version so
> that is the common and default usage. your version isn't DWIMmy there at
> all.


I think Perl 6's automatic reference-taking (though we don't call them
references any more) solves that problem for us.

If you say

my @c = eval '(1, 2, 3)';

then @c has three elements. If you say

my $c = eval '(1, 2, 3)';

then Perl constructs (if I've got the Perl 6 lingo right) an Array object
and stores it in $c. So the round brackets DTRT whether you're storing
into an array like @c or into a scalar like $c.

I'd like to use your example of serialising and unserialising to suggest
that the current behaviour is wrong:


msl@edward:~/perl/6$ cat serialise
#!/home/msl/bin/perl6

my @a = <blue light hazard>;

@a.perl.say;

msl@edward:~/perl/6$ cat unserialise
#!/home/msl/bin/perl6

my $p = =$*IN;
my @a = eval $p;
for (@a) { .say }

msl@edward:~/perl/6$ ./serialise | ./unserialise
blue light hazard
msl@edward:~/perl/6$


We serialised an array of three elements; we got back an array containing
just one. Round brackets would have solved that. (Actually, we don't
need any brackets at all, because Perl 6's list constructor is a comma,
not a set of brackets. But round brackets would be no-ops, and they
arguably make the output more human-readable.)

Markus

Uri Guttman

unread,
Jan 4, 2009, 10:37:43 PM1/4/09
to Markus Laker, perl6-l...@perl.org
>>>>> "ML" == Markus Laker <U20090103...@spamgourmet.com> writes:

ML> Adding a single backslash before `eval' pushes an anonymous array on to
ML> @b, as you envisage wanting to do:

ML> # Imagine that @a.perl has produced this:
ML> my $p = "('blue', 'light', 'hazard')";

ML> my @b;
ML> @b.push(\eval $p);

but that is manual code. what about a larger tree?

>> a more useful example would be serializing data trees. if you dump @b
>> with .perl do you want the current dumper output of a anon array or your
>> list of values? when serializing a tree, you must get the ref version so
>> that is the common and default usage. your version isn't DWIMmy there at
>> all.


ML> I think Perl 6's automatic reference-taking (though we don't call them
ML> references any more) solves that problem for us.

ML> If you say

ML> my @c = eval '(1, 2, 3)';

ML> then @c has three elements. If you say

ML> my $c = eval '(1, 2, 3)';

ML> then Perl constructs (if I've got the Perl 6 lingo right) an Array object
ML> and stores it in $c. So the round brackets DTRT whether you're storing
ML> into an array like @c or into a scalar like $c.

that fails with nested arrays. we don't want them to flatten.

my $c = eval '(1, (4, 5), 3)';

will that work as you envision? in perl5 with [] it works fine. i know
there are contexts that flatten and others that don't. but a larger tree
with assignments like that are harder to read IMO as lists inside lists
are not nesting but flattening in p5 all the time.

ML> We serialised an array of three elements; we got back an array containing
ML> just one. Round brackets would have solved that. (Actually, we don't
ML> need any brackets at all, because Perl 6's list constructor is a comma,
ML> not a set of brackets. But round brackets would be no-ops, and they
ML> arguably make the output more human-readable.)

try that again with my example above. in p5 the structure would be this:

my $c = [1, [4, 5], 3] ;

how should .perl serialize that so that eval will give back the same
structure? unless () are nesting and not flattening then you can't do it
without a \() which is longer (and uglier IMO than []).

Markus Laker

unread,
Jan 5, 2009, 3:09:05 AM1/5/09
to perl6-l...@perl.org
Uri,

On Sun, 04 Jan 2009 22:37:43 -0500, Uri Guttman wrote:

> that fails with nested arrays. we don't want them to flatten.
>
> my $c = eval '(1, (4, 5), 3)';
>
> will that work as you envision?

No, but it's not what I'm proposing. A reference must Perlify as a
reference, just as it does today, so that .perl doesn't destroy
information by flattening where you don't want it to. Here's what I
propose:


my @a = 1, 2, 3;
@a.perl.say; # (1, 2, 3)

my $ra = @a;
$ra.perl.say; # [1, 2, 3]

my @b = 1, [2, 3], 4;
@b.perl.say; # (1, [2, 3], 4)

my $rb = @b;
$rb.perl.say; # [1, [2, 3], 4]


My objection to the current behaviour is that @a and $ra Perlify to the
same string -- '[1, 2, 3]' -- losing the information that @a is an array
and $ra is a reference to an array. Therefore, if you serialise and
unserialise an array, you always get an array of a single element,
containing a reference to the real data. What you get back is not what
you put in.

Markus

mor...@casella.faui2k3.org

unread,
Jan 5, 2009, 8:43:12 AM1/5/09
to Uri Guttman, mor...@casella.faui2k3.org, Markus Laker, perl6-l...@perl.org
>>>>>> "m" == moritz <mor...@casella.faui2k3.org> writes:
>
> m> S02 says:
>
> m> "To get a Perlish representation of any object, use the .perl method.
> Like
> m> the Data::Dumper module in Perl 5, the .perl method will put quotes
> around
> m> strings, square brackets around list values,"
>
> m> So according to this, Rakudo has it right.
> m> But I think that a .perl()ification as ("blue", "light", "hayard",)
> would
> m> make much more sense, because simple thing like
>
> m> @a.push eval(@b.perl)
>
> m> would then DWIM.
>
> for your def of DWIM. i can see wanting an anon array to be pushed onto
> @a building up a structure.

DWIM in the sense that "eval($stuff.perl)" should behave the same as
$stuff itself.

since @a.push(@b) flattens @b into @a, why should I expect something
different from @a.push(eval(@b.perl))?

> your example is too simple to really cover
> this as you could just push @b or a ref to @b (damn, i need to learn
> more basic p6 syntax! :).

If people want @a.push(\@b) or @a.push([@b]), they can just write that -
and if the want to use eval + perl, they can include the brackets or
backslash just as well.

> a more useful example would be serializing data trees. if you dump @b
> with .perl do you want the current dumper output of a anon array or your
> list of values? when serializing a tree, you must get the ref version so
> that is the common and default usage. your version isn't DWIMmy there at
> all.

Maybe we can construct something magic with slice context and captures
instead?

Cheers,
Moritz

Reply all
Reply to author
Forward
0 new messages