Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sets (and Bags and Mixes) are exposing allomorphs and are generally very type sensitive #5842

Closed
p6rt opened this issue Nov 30, 2016 · 5 comments

Comments

@p6rt
Copy link

p6rt commented Nov 30, 2016

Migrated from rt.perl.org#130222 (status was 'rejected')

Searchable as RT130222$

@p6rt
Copy link
Author

p6rt commented Nov 30, 2016

From @dwarring

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?

@p6rt
Copy link
Author

p6rt commented Nov 30, 2016

From @zoffixznet

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&#8203;::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

@p6rt
Copy link
Author

p6rt commented Nov 30, 2016

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Nov 30, 2016

@zoffixznet - Status changed from 'open' to 'rejected'

@p6rt p6rt closed this as completed Nov 30, 2016
@p6rt
Copy link
Author

p6rt commented Dec 2, 2016

From @dwarring

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​:

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&#8203;::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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant