[sf-perl] push() practice: misplaced semicolon creates list elements within array?

William Michels wjm1 at caa.columbia.edu
Wed May 1 14:39:53 PDT 2019


Thank you yary.

I'm not sure we've seen any clarification on this. There's a reference to
"Literal Lists" in the Perl 6 docs that looks related, but I don't have a
"plain-speak" explanation for how semicolons, lists, push() and arrays
inter-relate.

https://docs.perl6.org/language/list

Hoping a Perl_6 guru can chime in?

Thank you.

--Bill.



On Sun, Apr 14, 2019 at 1:26 PM yary <not.com at gmail.com> wrote:

> Looks like perl6 semicolon has different meaning in a list vs a capture.
> In a list, it "makes sense to me"
>
> > perl6 --version
> This is Rakudo Star version 2018.10 built on MoarVM version 2018.10
> implementing Perl 6.c.
> >perl6
> To exit type 'exit' or '^D'
> > ('a').perl
> "a"
> > ('a';).perl
> "a"
> > ('a', 'b' ;).perl
> ("a", "b")
> > ('a', 'b' ; 'c').perl
> (("a", "b"), "c")
> > ('a', 'b' ; 'c' ;).perl
> (("a", "b"), "c")
> > ('a', 'b' ; 'c' ; ;).perl
> (("a", "b"), "c", Nil)
> > ('a', 'b' ; 'c' , ; ;).perl
> (("a", "b"), ("c",), Nil)
>
> - the rule "a single thing is a scalar, a single thing followed by a comma
> is a list" applies in the last example
>
> But there's inconsistency with captures.
>
> >\('a').perl
> \("a")
> > \('a';).perl; # Unexpected empty list at end
> \(("a",), ())
> > \('a', 'b' ;).perl; # Unexpected empty list at end
> \(("A", "b"), ())
> > \('a', 'b' ; 'c').perl; # unexpected "c" as list
> \(("a", "b"), ("c",))
> > \('a', 'b' ; 'c' ;).perl; # "c" as list, and empty list at end
> \(("a", "b"), ("c",), ())
> > \('a', 'b' ; 'c' ; ;).perl; # "c" as list, and 2 empty lists instead of
> single nil at end
> \(("a", "b"), ("c",), (), ())
> > \('a', 'b' ; 'c' , ; ;).perl; # 2 empty lists instead of single nil at
> end
> \(("a", "b"), ("c",), (), ())
>
> This cries for an explanation, or a bug report.
>
> -y
>
>
> On Sun, Apr 14, 2019 at 11:57 AM Joseph Brenner <doomvox at gmail.com> wrote:
>
>> Just in case it wasn't clear from Bill's discussion, I think the
>> reason this case seems weird is normally we expect trailing separators
>> to be ignored, as with the extra comma here:
>>
>>    > my @monsters = ('ghidora', 'mothera', 'wolfman', 'zuckerberg',);
>>   [ghidora mothera wolfman zuckerberg]
>>
>> If you do this, and type in a trailing semi-colon in the wrong place,
>> you stumble across some odd behavior:
>>
>>    > @monsters.push('tingler';)
>>   [ghidora mothera wolfman zuckerberg (tingler) ()]
>>
>> It seems a bit LTA, though it might be unavoidable because this is valid:
>>
>>    my @monsters = ('ghidora', 'mothera'; 'frankenstein',
>> 'wolfman';'purple-people-eater')
>>    [(ghidora mothera) (frankenstein wolfman) purple-people-eater]
>>
>> Though even here, the behavior seems a bit strange, because
>> "purple-people-eater" ended up as an element in the top-level list.
>> Hm, no empty list is appended if you do this:
>>
>>   my @monsters = ('ghidora', 'mothera'; 'frankenstein', 'wolfman';)
>>   [(ghidora mothera) (frankenstein wolfman)]
>>
>> But the push method seems to interpret it differently:
>>
>>   @monsters.push('purple-people-eater';)
>>   [(ghidora mothera) (frankenstein wolfman) (purple-people-eater) ()]
>>
>>
>>
>> On 4/14/19, William Michels via perl6-users <perl6-users at perl.org> wrote:
>> > Hello,
>> >
>> > I've been working through Patrick Michaud's excellent videos from the
>> > The Perl Conference 2016. At about 35:45 of the following 2016 video
>> > (Part 1 of 2), Patrick discusses arrays:
>> >
>> > https://www[dot]youtube[dot]com/watch?v=ySch4xpoPA0
>> >
>> > At this point in the video, Patrick also discusses push() and pop()
>> > calls on arrays. For practice I tried pushing and popping strings in
>> > the REPL. However, I discovered an unusual property when I misplaced a
>> > semicolon during call to push(). See what happens below when a
>> > semicolon is included within the parentheses of push():
>> >
>> > "This is Rakudo version 2018.12 built on MoarVM version 2018.12
>> > implementing Perl 6.d."
>> >
>> >> my @countries = "UK", "Spain", "Slovakia", "Sweden";
>> > [UK Spain Slovakia Sweden]
>> >> @countries.push("Finland");
>> > [UK Spain Slovakia Sweden Finland]
>> >> my @countries = "UK", "Spain", "Slovakia", "Sweden";
>> > [UK Spain Slovakia Sweden]
>> >> @countries.push("Finland";)
>> > [UK Spain Slovakia Sweden (Finland) ()]
>> >> my @countries = "UK", "Spain", "Slovakia", "Sweden";
>> > [UK Spain Slovakia Sweden]
>> >> @countries.push("Finland";);
>> > [UK Spain Slovakia Sweden (Finland) ()]
>> >
>> > Misplacing a semicolon within the push() call adds two elements to the
>> > array. When I examine these two elements, I see that they are both
>> > "List" elements:
>> >
>> >> @countries[3].WHAT
>> > (Str)
>> >> @countries[4].WHAT
>> > (List)
>> >> @countries[5].WHAT
>> > (List)
>> >
>> > Apparently, multiple semicolons within push() will add multiple list
>> > elements to the end of the intended array:
>> >
>> >> my @countries = "UK", "Spain", "Slovakia", "Sweden";
>> > [UK Spain Slovakia Sweden]
>> >> @countries.push("Finland";;);
>> > [UK Spain Slovakia Sweden (Finland) () ()]
>> >> my @countries = "UK", "Spain", "Slovakia", "Sweden";
>> > [UK Spain Slovakia Sweden]
>> >> @countries.push(;;;;;;;);
>> > [UK Spain Slovakia Sweden () () () () () () () ()]
>> >
>> > It is surprising to me that "List" elements are appended to the array
>> > with push() as described above. If one tries to add one or more
>> > elements via indexing and there 'aren't enough elements' so to speak
>> > (by accident or design), the array grows by inserting "Any" elements,
>> > not "List" elements:
>> >
>> >> my @countries = "UK", "Spain", "Slovakia", "Sweden";
>> > [UK Spain Slovakia Sweden]
>> >> @countries[5] = "Finland";
>> > Finland
>> >> say @countries
>> > [UK Spain Slovakia Sweden (Any) Finland]
>> >>
>> >> my @countries = "UK", "Spain", "Slovakia", "Sweden";
>> > [UK Spain Slovakia Sweden]
>> >> @countries[6..7] = "Finland", "Norway";
>> > (Finland Norway)
>> >> say @countries
>> > [UK Spain Slovakia Sweden (Any) (Any) Finland Norway]
>> >
>> > I've briefly checked pop() to see if there are similar issues, but 1)
>> > placing a string within the parentheses of pop() will throw an error,
>> > and 2) placing a semicolon within the parentheses of pop() will throw
>> > an error. However, these error message are slightly different. A
>> > string argument to pop() will result in an error that says "Too many
>> > positionals passed; expected 1 argument but got 2" while a semicolon
>> > argument to pop() will result in an error that says "Too many
>> > positionals passed; expected 1 argument but got 3".
>> >
>> >> my @countries = "UK", "Spain", "Slovakia", "Sweden";
>> > [UK Spain Slovakia Sweden]
>> >> @countries.pop("Finland")
>> > Too many positionals passed; expected 1 argument but got 2
>> >   in block <unit> at <unknown file> line 1
>> >
>> >> @countries.pop(;)
>> > Too many positionals passed; expected 1 argument but got 3
>> >   in block <unit> at <unknown file> line 1
>> >
>> >>
>> >
>> >
>> > Any help appreciated,
>> >
>> > Bill.
>> >
>> > William Michels, Ph.D.
>> >
>> > PS Thanks to Joe Brenner for talking over this Perl6 code with me.
>> >
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.pm.org/pipermail/sanfrancisco-pm/attachments/20190501/295461a7/attachment.html>


More information about the SanFrancisco-pm mailing list