Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Reimplement :with for List.(uniq|squish) (keep :as available)
Yes, it was removed from the spec, but the alternative for doing [eqv] based
uniqueness using *.perl is 1. still not possible now (because .perl doesn't
always give an accurate representation), and 2. very resource intensive,
because a whole structure needs to be stringified first before being able to
find out that they're different.  Whereas [eqv] is very quickly able to find
out whether two structures are different.

So, do I believe it belongs in the spec?  Yes!  :-)
  • Loading branch information
lizmat committed Aug 4, 2013
1 parent 59e521e commit 8d851b7
Showing 1 changed file with 46 additions and 16 deletions.
62 changes: 46 additions & 16 deletions src/core/List.pm
Expand Up @@ -378,57 +378,87 @@ my class List does Positional { # declared in BOOTSTRAP
proto method uniq(|) {*}
multi method uniq() {
my $seen := nqp::hash();
my str $which;
my str $target;
map {
$which = nqp::unbox_s($_.WHICH);
if nqp::existskey($seen, $which) {
$target = nqp::unbox_s($_.WHICH);
if nqp::existskey($seen, $target) {
Nil;
}
else {
nqp::bindkey($seen, $which, 1);
nqp::bindkey($seen, $target, 1);
$_;
}
}, @.list;
}
multi method uniq( :&as!, :&with! ) {
my @seen; # should be Mu, but doesn't work in settings :-(
my Mu $target;
map {
$target = &as($_);
if first( { with($target,$_) }, @seen ) =:= Nil {
@seen.push($target);
$_;
}
else {
Nil;
}
}, @.list;
}
multi method uniq( :&as! ) {
my $seen := nqp::hash();
my str $which;
my str $target;
map {
$which = &as($_);
if nqp::existskey($seen, $which) {
$target = &as($_).WHICH;
if nqp::existskey($seen, $target) {
Nil;
}
else {
nqp::bindkey($seen, $which, 1);
nqp::bindkey($seen, $target, 1);
$_;
}
}, @.list;
}
multi method uniq( :&with! ) {
nextwith() if &with === &[===]; # use optimized version

my @seen; # should be Mu, but doesn't work in settings :-(
my Mu $target;
map {
$target := $_;
if first( { with($target,$_) }, @seen ) =:= Nil {
@seen.push($target);
$_;
}
else {
Nil;
}
}, @.list;
}

my @secret;
proto method squish(|) {*}
multi method squish() {
multi method squish( :&as!, :&with = &[===] ) {
my $last = @secret;
my str $which;
map {
if $_ === $last {
$which = &as($_);
if with($which,$last) {
Nil;
}
else {
$last = $_;
$last = $which;
$_;
}
}, @.list;
}
multi method squish( :&as! ) {
multi method squish( :&with = &[===] ) {
my $last = @secret;
my str $which;
map {
$which = &as($_);
if $which === $last {
if with($_,$last) {
Nil;
}
else {
$last = $which;
$last = $_;
$_;
}
}, @.list;
Expand Down

0 comments on commit 8d851b7

Please sign in to comment.