Skip Menu |
Report information
Id: 131783
Status: resolved
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!
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 2.1k
On Mon, 24 Jul 2017 01:54:53 -0700, elizabeth wrote: 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!
Tests added in https://github.com/perl6/roast/commit/24d5fcb486 However, the values for .List differ depending on how you access them. If you use iterator, you get a Mu for a hole, but if you use AT-POS you get a Nil.. 13:04 Zoffix m: (my @a)[1] = Mu; my @b is default(42) = @a.List; say @b 13:04 camelia rakudo-moar b8eda6: OUTPUT: «[(Mu) (Mu)]␤» 13:04 Zoffix m: (my @a)[1] = Mu; my @b is default(42) = @a.List[*]; say @b 13:04 camelia rakudo-moar b8eda6: OUTPUT: «[42 (Mu)]␤» I filed a separate ticket for that: https://rt.perl.org/Ticket/Display.html?id=132261 IRC: https://irclog.perlgeek.de/perl6-dev/2017-10-10#i_15283224


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