Skip Menu |
Report information
Id: 130222
Status: rejected
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: david.warring <david.warring [at] gmail.com>
Cc:
AdminCc:

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



Subject: Sets (and Bags and Mixes) are exposing allomorphs and are generally very type sensitive
From: David Warring <david.warring [...] gmail.com>
Date: Thu, 1 Dec 2016 07:18:27 +1300
To: rakudobug [...] perl.org
Download (untitled) / with headers
text/plain 951b
One example from this stack overflow question: question http://stackoverflow.com/questions/40814933/how-do-the-perl-6-set-operations-compare-elements

my $num_set = set( < 1 2 3 4 > );
say "set: ", $num_set.perl;
say "4 is in set: ", 4  $num_set; # False
say "IntStr 4 is in set: ", IntStr.new(4, "Four")  $num_set; $ True
As noted is the thread it's unexpected and a likely trap that's difficult to explain to beginners.
The current implementation is supposed to make it easy to form sets of general objects. But in practice even that's fragile. Consider:
my $v = 42;
my $s = set($v);
$v does role {};
say $v ∈ $s; # False
Applying a role to the object has had the side effect. Its no longer recognized as being an element in the set.
I suspect the general idea of using .WHICH as a discriminator between elements isn't working well in practice.
Maybe we should pull this back and use something simpler and more inclusive such as .Str? 
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 3.2k
On Wed, 30 Nov 2016 10:18:50 -0800, david.warring wrote: Show quoted text
> One example from this stack overflow question: question > http://stackoverflow.com/questions/40814933/how-do-the-perl-6-set- > operations-compare-elements > > my $num_set = set( < 1 2 3 4 > ); > say "set: ", $num_set.perl; > say "4 is in set: ", 4 ∈ $num_set; # False > say "IntStr 4 is in set: ", IntStr.new(4, "Four") ∈ $num_set; $ True > > As noted is the thread it's unexpected and a likely trap that's > difficult to explain to beginners. > > The current implementation is supposed to make it easy to form sets of > general objects. But in practice even that's fragile. Consider: > > my $v = 42; > my $s = set($v); > $v does role {}; > say $v ∈ $s; # False > > I suspect the general idea of using .WHICH as a discriminator between > elements isn't working well in practice. > > Maybe we should pull this back and use something simpler and more > inclusive such as .Str?
Thanks for taking time writing this up, however, I'm going to reject this ticket. There's little reason to make a major, breaking change to a large feature of the language, making it much less powerful, just because a single beginner used poor documentation and got confused. The author of that SO question created another ticket (RT#130184) and the documentation has since been amended to explain that `< ... >` quoters differ from qw// quoters and that they create allomorphs. Feel free to submit further improvements to either allomorphs or set bag mixes page (https://github.com/perl6/doc/blob/master/doc/Language/setbagmix.pod6 ) I'd even argue the allomorphs alone are the cause of that person's confusion and not setties and baggies using object identity to discern their elements. And aside from edge case where the angle brackets double as numeric literals, they're pretty easy to explain to beginners: for numbers, you get a subclass of Str and a particular Numeric, since the parser doesn't know which one you meant and making them all Str would make the feature less useful. If you meant a specific numeric type, coerce the stuff you get, if you meant always Str, use qw// quoters instead (there's also http://modules.perl6.org/dist/Quantum::Collapse module). If a set based on .Str is needed, one can use set <1 2 3 4>».Str. The proposal to use .Str instead of object identity would make ['a', 'b', 'c'] be equivalent to element ['a', ['b', ['c']]], or [[['a'], 'b',] 'c'], or string 'a b c', or class Foo { method Str { 'a b c '} }. In fact, it'll also treat all of these as the same object: class { method bar {} }, class {}, class { has $!foo }; class A {}; class B is A {} because all of their .Str is an empty string. This would make the feature rather error prone. Show quoted text
> Applying a role to the object has had the side effect. Its no longer > recognized as being an element in the set.
That's because it's a completely different object. Even with the .Str proposal that can be effected, since `"foo"` and `"foo" but "bar"` would not be considered the same items in the set, since their .Str values are different. In summation, I don't think power should be stripped from features for the sole reason of making them more palatable to absolute beginners. Improved documentation is the correct solution. Cheers, ZZ
Download (untitled) / with headers
text/plain 3.6k
No worries. I wasn't coming from just stripping them out completely (they are a good feature), but just somehow having them disabled by default to reduce the element of surprise. Something like how the Hash family operates. Cheers, David On Wed, 30 Nov 2016 11:28:49 -0800, cpan@zoffix.com wrote: Show quoted text
> On Wed, 30 Nov 2016 10:18:50 -0800, david.warring wrote:
> > One example from this stack overflow question: question > > http://stackoverflow.com/questions/40814933/how-do-the-perl-6-set- > > operations-compare-elements > > > > my $num_set = set( < 1 2 3 4 > ); > > say "set: ", $num_set.perl; > > say "4 is in set: ", 4 ∈ $num_set; # False > > say "IntStr 4 is in set: ", IntStr.new(4, "Four") ∈ $num_set; $ True > > > > As noted is the thread it's unexpected and a likely trap that's > > difficult to explain to beginners. > > > > The current implementation is supposed to make it easy to form sets > > of > > general objects. But in practice even that's fragile. Consider: > > > > my $v = 42; > > my $s = set($v); > > $v does role {}; > > say $v ∈ $s; # False > > > > I suspect the general idea of using .WHICH as a discriminator between > > elements isn't working well in practice. > > > > Maybe we should pull this back and use something simpler and more > > inclusive such as .Str?
> > Thanks for taking time writing this up, however, I'm going to reject > this ticket. > > There's little reason to make a major, breaking change to a large > feature of the language, making it much less powerful, just because a > single beginner used poor documentation and got confused. > > The author of that SO question created another ticket (RT#130184) and > the documentation has since been amended to explain that `< ... >` > quoters differ from qw// quoters and that they create allomorphs. Feel > free to submit further improvements to either allomorphs or set bag > mixes page > (https://github.com/perl6/doc/blob/master/doc/Language/setbagmix.pod6 > ) > > I'd even argue the allomorphs alone are the cause of that person's > confusion and not setties and baggies using object identity to discern > their elements. And aside from edge case where the angle brackets > double as numeric literals, they're pretty easy to explain to > beginners: for numbers, you get a subclass of Str and a particular > Numeric, since the parser doesn't know which one you meant and making > them all Str would make the feature less useful. If you meant a > specific numeric type, coerce the stuff you get, if you meant always > Str, use qw// quoters instead (there's also > http://modules.perl6.org/dist/Quantum::Collapse module). > > If a set based on .Str is needed, one can use set <1 2 3 4>».Str. The > proposal to use .Str instead of object identity would make ['a', 'b', > 'c'] be equivalent to element ['a', ['b', ['c']]], or [[['a'], 'b',] > 'c'], or string 'a b c', or class Foo { method Str { 'a b c '} }. In > fact, it'll also treat all of these as the same object: class { method > bar {} }, class {}, class { has $!foo }; class A {}; class B is A {} > because all of their .Str is an empty string. > > This would make the feature rather error prone. >
> > Applying a role to the object has had the side effect. Its no longer > > recognized as being an element in the set.
> > That's because it's a completely different object. Even with the .Str > proposal that can be effected, since `"foo"` and `"foo" but "bar"` > would not be considered the same items in the set, since their .Str > values are different. > > In summation, I don't think power should be stripped from features for > the sole reason of making them more palatable to absolute beginners. > Improved documentation is the correct solution. > > Cheers, > ZZ


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