Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
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

0 new messages