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

Owner: Nobody
Requestors: zefram [at] fysh.org
Cc:
AdminCc:

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



To: rakudobug [...] perl.org
From: Zefram <zefram [...] fysh.org>
Subject: [BUG] Set.new confused by Nil
Date: Thu, 9 Mar 2017 20:02:04 +0000
Download (untitled) / with headers
text/plain 381b
Show quoted text
> Set.new(Nil).perl
set(Any) Show quoted text
> set(Nil).perl
set(Any) Show quoted text
> set(Nil).WHICH
Set|Any|U16962232 Attempting to put Nil into a Set instead puts Any into one. Happens with both Set.new() and set() constructors. The .WHICH result shows that it really is the set construction that mangled the value, not .perl. There's no reason for Nil not to be a distinguishable value in a set. -zefram
Date: Thu, 9 Mar 2017 15:12:26 -0500
CC: bugs-bitbucket [...] rt.perl.org
Subject: Re: [perl #130970] [BUG] Set.new confused by Nil
From: Brandon Allbery <allbery.b [...] gmail.com>
To: perl6-compiler <perl6-compiler [...] perl.org>
Download (untitled) / with headers
text/plain 1.2k
Erm. Isn't Nil a silent Failure? Insisting that it be propagated and retained in all circumstances basically asserts that it must be a distinct concrete value, and specifically *not* any form of Failure. Could someone clarify this?

(At present my understanding is that it is a silent Failure and most if not all of today's Nil tickets are at best missing the point.)

On Thu, Mar 9, 2017 at 3:03 PM, Zefram <perl6-bugs-followup@perl.org> wrote:
Show quoted text
# New Ticket Created by  Zefram
# Please include the string:  [perl #130970]
# in the subject line of all future correspondence about this issue.
# <URL: https://rt.perl.org/Ticket/Display.html?id=130970 >


> Set.new(Nil).perl
set(Any)
> set(Nil).perl
set(Any)
> set(Nil).WHICH
Set|Any|U16962232

Attempting to put Nil into a Set instead puts Any into one.  Happens with
both Set.new() and set() constructors.  The .WHICH result shows that
it really is the set construction that mangled the value, not .perl.
There's no reason for Nil not to be a distinguishable value in a set.

-zefram



--
brandon s allbery kf8nh                               sine nomine associates
allbery.b@gmail.com                                  ballbery@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net
To: Brandon Allbery via RT <perl6-bugs-followup [...] perl.org>
From: Zefram <zefram [...] fysh.org>
Subject: Re: [perl #130970] [BUG] Set.new confused by Nil
Date: Thu, 9 Mar 2017 20:55:15 +0000
Download (untitled) / with headers
text/plain 1.1k
Brandon Allbery via RT wrote: Show quoted text
>Erm. Isn't Nil a silent Failure?
It may well represent such a thing, but it is also a reified object. Putting objects into sets is an operation that's applicable to any kind of object, and which (for comparison) does in fact work on objects of the Failure class. Expecting an object to be propagated doesn't assert that it doesn't represent failure; rather, it's just embracing the reification. The great benefit of reification is that the object can be processed in all the familiar ways that are used on ordinary value objects. If you want to impose a restriction that failure objects can't go into some of the places I've tried to put Nil, then in some cases that would be a sensible decision. It would make perfect sense to restrict Range endpoints, for example, but it doesn't make any sense to restrict the domain of Sets. But in any case, wherever such a restriction is desirable it should be enforced by signalling an exception: silently substituting a different value sucks. And if your logic for rejecting Nil is that it represents failure, then presumably the same logic would lead you to reject objects of the Failure class too, and maybe also Exception. -zefram
Download (untitled) / with headers
text/plain 2.6k
On Thu, 09 Mar 2017 12:55:58 -0800, zefram@fysh.org wrote: Show quoted text
> Brandon Allbery via RT wrote:
> >Erm. Isn't Nil a silent Failure?
> > It may well represent such a thing, but it is also a reified object. > Putting objects into sets is an operation that's applicable to any kind > of object, and which (for comparison) does in fact work on objects of the > Failure class. Expecting an object to be propagated doesn't assert that > it doesn't represent failure; rather, it's just embracing the reification. > The great benefit of reification is that the object can be processed in > all the familiar ways that are used on ordinary value objects. > > If you want to impose a restriction that failure objects can't go into > some of the places I've tried to put Nil, then in some cases that would > be a sensible decision. It would make perfect sense to restrict Range > endpoints, for example, but it doesn't make any sense to restrict the > domain of Sets. But in any case, wherever such a restriction is desirable > it should be enforced by signalling an exception: silently substituting > a different value sucks. And if your logic for rejecting Nil is that > it represents failure, then presumably the same logic would lead you to > reject objects of the Failure class too, and maybe also Exception. > > -zefram >
The reason this is happening is not that Nil is a pseudo-Failure. It is that Nil is also semantically special as a RHS of an assignment or as a parameter. $ perl6 -e 'my @a; @a = Nil,Nil; @a.perl.say' [Any, Any] $ perl6 -e 'my Int @a; @a = Nil,Nil; @a.perl.say' Array[Int].new(Int, Int) $ perl6 -e 'my @a = Array.new(Nil,Nil); @a.perl.say' [Any, Any] $ perl6 -e 'my @a = Array[Int].new(Nil,Nil); @a.perl.say' [Int, Int] This is mentioned in S02. Set, as of right now, cannot be parameterized so you only get to see the Any case there. The usual "solution" to this in the Array case is to directly bind the element. This is actually discouraged as it is in violation of the GLR "gentleman's agreement" that Array elements are Scalars. Set being immutable, getting a Nil into a set element would require some internals incantation. Nil is not supposed to be used as a generic kickaround Mu instantiation -- it is just not a normal value. Or philosphically, Per S02, Nil 'means "there is no value here"', so having a set that contains it as an element is incongruous. We only let it out into Lists/Seqs because it would be impossible to use otherwise. If there is a compelling use-case for allowing Nil in a Set, it should probably require using set() rather than Set.new() as we can call that a literal... you'll note List.new wont transcribe Nil either.
Subject: Re: [perl #130970] [BUG] Set.new confused by Nil
From: Zefram <zefram [...] fysh.org>
To: "Brian S. Julin via RT" <perl6-bugs-followup [...] perl.org>
Date: Tue, 5 Sep 2017 08:35:01 +0100
Download (untitled) / with headers
text/plain 2.8k
Brian S. Julin via RT wrote: Show quoted text
>It is that Nil is also semantically special as a RHS of an assignment >or as a parameter.
... Show quoted text
>This is mentioned in S02.
Some of the specialness mentioned in S02 doesn't happen, such as .ACCEPTS returning Nil, and getting the default value of an optional parameter. Those issues probably don't change the logic of this ticket, though. Show quoted text
>Set, as of right now, cannot be parameterized so you only get to see >the Any case there.
False analogy. The intentional behaviour of the Array is that (by default) it contains a bunch of Scalar containers, and it is those containers that (by default) have the funny treatment of Nil. Set, otoh, doesn't overtly involve any Scalar containers, and in fact immutability is an advertised feature. So there's no API reason to import Scalar's behaviour around Nil. Show quoted text
>Or philosphically, Per S02, Nil 'means "there is no value here"',
And yet Nil is a reified object, and so very much *is* a value that is here. It may indicate the absence of a value in some higher-level protocol in which Nil is not a relevant value. But down here in the base language Nil is a visible object. Show quoted text
>so having a set that contains it as an element is incongruous.
Again, that may be so in some higher-level situation in which Nil is not a value of interest. If you're expecting a set of Ints then getting a set containing Nil would be incongruous. But where Nil is a value, it would be incongruous to be unable to put it in a set. It's literally an axiom of set theory that for every object there exists a set containing that object. (Note that you need a set theory that includes urelements, to match the Perl 6 situation.) Show quoted text
>If there is a compelling use-case for allowing Nil in a Set,
I find the intrinsic concept of the set to be pretty compelling. Show quoted text
>probably require using set() rather than Set.new() as we can >call that a literal.
I don't follow this argument. There doesn't seem to be any rule against .new() methods accepting a Nil argument as Nil: Show quoted text
> Pair.new("foo", Nil).value.WHICH
Nil|U15269208 Trying things out now, I see that the behaviour of the test cases with which I started this ticket has changed, and that currently set() and Set.new() do actually behave differently. (In the original bug report I didn't distinguish between set() and Set.new(), not seeing any difference.) set() now accepts a Nil element, and Set.new() accepts Nil as a sole argument; the substitution of Any now happens only for Set.new() and only when there's at least one other argument: Show quoted text
> set(Nil)
set(Nil) Show quoted text
> set(3,Nil)
set(3 Nil) Show quoted text
> set(Nil,Nil)
set(Nil) Show quoted text
> Set.new(Nil)
set(Nil) Show quoted text
> Set.new(3,Nil)
set((Any) 3) Show quoted text
> Set.new(Nil,Nil)
set((Any)) That's pretty weird. The subject line of this ticket still seems applicable. Show quoted text
> you'll note List.new wont transcribe >Nil either.
That looks like a separate bug. -zefram
Download (untitled) / with headers
text/plain 4.6k
On Tue, 05 Sep 2017 03:21:07 -0700, zefram@fysh.org wrote: Show quoted text
> Brian S. Julin via RT wrote:
> >It is that Nil is also semantically special as a RHS of an assignment > >or as a parameter.
> ...
> >This is mentioned in S02.
> > Some of the specialness mentioned in S02 doesn't happen, such as .ACCEPTS > returning Nil, and getting the default value of an optional parameter. > Those issues probably don't change the logic of this ticket, though. >
> >Set, as of right now, cannot be parameterized so you only get to see > >the Any case there.
> > False analogy. The intentional behaviour of the Array is that (by > default) it contains a bunch of Scalar containers, and it is those > containers that (by default) have the funny treatment of Nil. Set, otoh, > doesn't overtly involve any Scalar containers, and in fact immutability > is an advertised feature. So there's no API reason to import Scalar's > behaviour around Nil. >
> >Or philosphically, Per S02, Nil 'means "there is no value here"',
> > And yet Nil is a reified object, and so very much *is* a value that > is here. It may indicate the absence of a value in some higher-level > protocol in which Nil is not a relevant value. But down here in the > base language Nil is a visible object. >
> >so having a set that contains it as an element is incongruous.
> > Again, that may be so in some higher-level situation in which Nil is not > a value of interest. If you're expecting a set of Ints then getting a > set containing Nil would be incongruous. But where Nil is a value, it > would be incongruous to be unable to put it in a set. It's literally an > axiom of set theory that for every object there exists a set containing > that object. (Note that you need a set theory that includes urelements, > to match the Perl 6 situation.) >
> >If there is a compelling use-case for allowing Nil in a Set,
> > I find the intrinsic concept of the set to be pretty compelling. >
> >probably require using set() rather than Set.new() as we can > >call that a literal.
> > I don't follow this argument. There doesn't seem to be any rule against > .new() methods accepting a Nil argument as Nil: >
> > Pair.new("foo", Nil).value.WHICH
> Nil|U15269208 > > Trying things out now, I see that the behaviour of the test cases with > which I started this ticket has changed, and that currently set() > and Set.new() do actually behave differently. (In the original bug > report I didn't distinguish between set() and Set.new(), not seeing any > difference.) set() now accepts a Nil element, and Set.new() accepts Nil > as a sole argument; the substitution of Any now happens only for Set.new() > and only when there's at least one other argument: >
> > set(Nil)
> set(Nil)
> > set(3,Nil)
> set(3 Nil)
> > set(Nil,Nil)
> set(Nil)
> > Set.new(Nil)
> set(Nil)
> > Set.new(3,Nil)
> set((Any) 3)
> > Set.new(Nil,Nil)
> set((Any)) > > That's pretty weird. The subject line of this ticket still seems > applicable. >
> > you'll note List.new wont transcribe > >Nil either.
> > That looks like a separate bug. > > -zefram
OK, I can see your argument for the difference between Set and Array here. Also, having now had a look at the current implementation I cannot argue with confidence that it's "that way for a reason." I'd suggest some core people have a lively alcohol-fueled discussion about which of set(), Set.new(), and List.new() should have an "is raw" added to their candidates, or work directly on a Capture. Syntactically it may not be possible to get some reified objects into a set's keys through normal means. What syntax would we use to get Empty into a Set, for example? I'd just offer that some reified objects in Perl6 come with attached syntax-like behaviors, though perhaps in the specific case of Nil this ticket may be a reasonable ask... apparently it does seem to be comfortable in object hash keys. But for things like Empty, we'd need some special constructor, and depending on what Nil is *supposed* to do when passed into slurpies and what flavors of slurpy let set() and Set.new() behave sanely (?), Nil might, too. Considering Nil's default-finding behavior seems to have never been implemented, I'm less sure the answer to that has been thoroughly pondered. As to the set-theory argument, I don't get the feeling Perl6 is aiming for a pure-FP level of calculus, and I don't think it is necessarily true that there is a "base language" which prevents Perl6 from using reified objects as means to implement what would otherwise be done with syntax when that is an efficient way to do things, just to adhere to a theoretical principle. The closest we have to a base language is the types that have to BOOTSTRAP, and Set isn't one of them.


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