Skip Menu |
Report information
Id: 131783
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: cpan [at] zoffix.com
Cc:
AdminCc:

Severity: (no value)
Tag: testneeded
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Subject: [LTA] :delete holes in Arrays get turned to Mus when coercing to List or Slip
Download (untitled) / with headers
text/plain 1.1k
The current behaviour kinda makes sense when you squint at it, but today we had a user[^1]who was surprised by it, so I'm filing it as a ticket, if maybe there's some Better Way this can be done with. When you :delete an element from the Array, you get nqp::null stuffed into the position, which gets converted to `is default` value when you look it up again: <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; dd @a <camelia> rakudo-moar b14721: OUTPUT: «Array @a = ["a", 42, "c"]␤» However, if you now convert that Array to a Slip or a List, the hole is left as a bare Mu and doesn't get turned into a default value, which is lost: <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; dd @a.Slip <camelia> rakudo-moar b14721: OUTPUT: «slip("a", Mu, "c")␤» <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; dd @a.List <camelia> rakudo-moar b14721: OUTPUT: «("a", Mu, "c")␤» So it makes sense that without `is default` you don't get an `is default` value, but at the same time, Mu is not a great value to deal with... [1] https://irclog.perlgeek.de/perl6/2017-07-22#i_14908846
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 1.6k
On Sat, 22 Jul 2017 18:48:38 -0700, cpan@zoffix.com wrote: Show quoted text
> The current behaviour kinda makes sense when you squint at it, but > today we had a user[^1]who was surprised by it, so I'm filing it as a > ticket, if maybe there's some Better Way this can be done with. > > When you :delete an element from the Array, you get nqp::null stuffed > into the position, which gets converted to `is default` value when you > look it up again: > > <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; > dd @a > <camelia> rakudo-moar b14721: OUTPUT: «Array @a = ["a", 42, "c"]␤» > > However, if you now convert that Array to a Slip or a List, the hole > is left as a bare Mu and doesn't get turned into a default value, > which is lost: > > <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; > dd @a.Slip > <camelia> rakudo-moar b14721: OUTPUT: «slip("a", Mu, "c")␤» > > <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; > dd @a.List > <camelia> rakudo-moar b14721: OUTPUT: «("a", Mu, "c")␤» > > So it makes sense that without `is default` you don't get an `is > default` value, but at the same time, Mu is not a great value to deal > with... > > [1] https://irclog.perlgeek.de/perl6/2017-07-22#i_14908846
And actually both .flat and .Seq do get `is default` value instead of Mu, so at the very least there's some inconsistency here: <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; dd @a.flat <camelia> rakudo-moar b14721: OUTPUT: «("a", 42, "c").Seq␤» <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; dd @a.Seq <camelia> rakudo-moar b14721: OUTPUT: «("a", 42, "c").Seq␤»
Perhaps also worth noting that this applies to other holes as well, e.g. those created by extending an array:

my @a = 42; @a[5] = 49; say |@a # 42(Mu)(Mu)(Mu)(Mu)49

In fact, this the actual problem the user had.

On 2017-07-22 18:52:03, cpan@zoffix.com wrote:
Show quoted text
> On Sat, 22 Jul 2017 18:48:38 -0700, cpan@zoffix.com wrote:
> > The current behaviour kinda makes sense when you squint at it, but
> > today we had a user[^1]who was surprised by it, so I'm filing it as a
> > ticket, if maybe there's some Better Way this can be done with.
> >
> > When you :delete an element from the Array, you get nqp::null stuffed
> > into the position, which gets converted to `is default` value when
> > you
> > look it up again:
> >
> > <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete;
> > dd @a
> > <camelia> rakudo-moar b14721: OUTPUT: «Array @a = ["a", 42, "c"]␤»
> >
> > However, if you now convert that Array to a Slip or a List, the hole
> > is left as a bare Mu and doesn't get turned into a default value,
> > which is lost:
> >
> > <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete;
> > dd @a.Slip
> > <camelia> rakudo-moar b14721: OUTPUT: «slip("a", Mu, "c")␤»
> >
> > <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete;
> > dd @a.List
> > <camelia> rakudo-moar b14721: OUTPUT: «("a", Mu, "c")␤»
> >
> > So it makes sense that without `is default` you don't get an `is
> > default` value, but at the same time, Mu is not a great value to deal
> > with...
> >
> > [1] https://irclog.perlgeek.de/perl6/2017-07-22#i_14908846
>
>
> And actually both .flat and .Seq do get `is default` value instead of
> Mu, so at the very least there's some inconsistency here:
>
> <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete;
> dd @a.flat
> <camelia> rakudo-moar b14721: OUTPUT: «("a", 42, "c").Seq␤»
> <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete;
> dd @a.Seq
> <camelia> rakudo-moar b14721: OUTPUT: «("a", 42, "c").Seq␤»


To: "Zoffix Znet (via RT)" <perl6-bugs-followup [...] perl.org>
Subject: Re: [perl #131783] [LTA] :delete holes in Arrays get turned to Mus when coercing to List or Slip
From: Elizabeth Mattijsen <liz [...] dijkmat.nl>
Date: Sun, 23 Jul 2017 13:15:30 +0200
Download (untitled) / with headers
text/plain 2.1k
Show quoted text
> On 23 Jul 2017, at 03:48, Zoffix Znet (via RT) <perl6-bugs-followup@perl.org> wrote: > > # New Ticket Created by Zoffix Znet > # Please include the string: [perl #131783] > # in the subject line of all future correspondence about this issue. > # <URL: https://rt.perl.org/Ticket/Display.html?id=131783 > > > > The current behaviour kinda makes sense when you squint at it, but today we had a user[^1]who was surprised by it, so I'm filing it as a ticket, if maybe there's some Better Way this can be done with. > > When you :delete an element from the Array, you get nqp::null stuffed into the position, which gets converted to `is default` value when you look it up again: > > <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; dd @a > <camelia> rakudo-moar b14721: OUTPUT: «Array @a = ["a", 42, "c"]␤» > > However, if you now convert that Array to a Slip or a List, the hole is left as a bare Mu and doesn't get turned into a default value, which is lost: > > <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; dd @a.Slip > <camelia> rakudo-moar b14721: OUTPUT: «slip("a", Mu, "c")␤» > > <Zoffix__> m: use nqp; my @a is default(42) = <a b c>; @a[1]:delete; dd @a.List > <camelia> rakudo-moar b14721: OUTPUT: «("a", Mu, "c")␤» > > So it makes sense that without `is default` you don't get an `is default` value, but at the same time, Mu is not a great value to deal with... > > [1] https://irclog.perlgeek.de/perl6/2017-07-22#i_14908846
The problem is really caused by the fact that an Array has a descriptor, which contains the default value and type information, and a List does not. And since a Slip isa List, we lose the descriptor when Slipping an Array. The same issue appears with: $ 6 'my @a; @a[2] = 42; dd (|@a)[0] = 44; dd @a' Cannot modify an immutable Str (Nil) Which is because Slip is a List, it uses List.AT-POS, and that one doesn’t create a WHENCE with a container to be filled at a later time. Which then goes back to: what is the use case of Slipping an Array? When do you need that? Perhaps slipping an Array should produce a warning?
Download (untitled) / with headers
text/plain 1.1k
Show quoted text
> Which then goes back to: what is the use case of Slipping an Array?
Same as slipping any other type of Iterable: Fine-grained, elegant flattening and concatenating. Compare: my @all = flat $first, @rest; my @all = $first, |@rest; When you *know* that $first is a Scalar and @rest is an Array, those two do the same thing because `flat` doesn't descend into item containers. But if those are, say, function parameters, then they can become bound to other things, e.g. the calling code could pass a List to `@rest` which *doesn't* have its elements itemized, so the version with `flat` would destroy the elements' internal structure. Even if that wasn't the case, I'd consider the `|` version more elegant than the `flat` version, because it denotes very clearly to the reader *where* exactly something is being flattened into the outer list. Show quoted text
> because Slip is a List, it uses List.AT-POS, and that one > doesn’t create a WHENCE with a container to be filled at a later time.
Couldn't `@array.Slip` be made to properly iterate @array behind the scenes (the same way that `@array.map` would iterate it), instead of reaching into @array's guts and copying its elements in a way that misinterprets some of them?
Date: Mon, 24 Jul 2017 10:54:33 +0200
From: Elizabeth Mattijsen <liz [...] dijkmat.nl>
To: perl6-bugs-followup [...] perl.org
Subject: Re: [perl #131783] [LTA] :delete holes in Arrays get turned to Mus when coercing to List or Slip
Download (untitled) / with headers
text/plain 1.3k
Show quoted text
> On 23 Jul 2017, at 22:27, Sam S. via RT <perl6-bugs-followup@perl.org> wrote: >
>> Which then goes back to: what is the use case of Slipping an Array?
> > Same as slipping any other type of Iterable: Fine-grained, elegant flattening and concatenating. > > Compare: > > my @all = flat $first, @rest; > > my @all = $first, |@rest; > > When you *know* that $first is a Scalar and @rest is an Array, those two do the same thing because `flat` doesn't descend into item containers. > > But if those are, say, function parameters, then they can become bound to other things, e.g. the calling code could pass a List to `@rest` which *doesn't* have its elements itemized, so the version with `flat` would destroy the elements' internal structure. > > Even if that wasn't the case, I'd consider the `|` version more elegant than the `flat` version, because it denotes very clearly to the reader *where* exactly something is being flattened into the outer list. >
>> because Slip is a List, it uses List.AT-POS, and that one >> doesn’t create a WHENCE with a container to be filled at a later time.
> > Couldn't `@array.Slip` be made to properly iterate @array behind the scenes (the same way that `@array.map` would iterate it), instead of reaching into @array's guts and copying its elements in a way that misinterprets some of them?
Which is exactly what 12d7d5b48add8347eb119 does. So fixed, and tests needed!


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org