Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Re^4: reduce like iterators

by furry_marmot (Pilgrim)
on Jan 18, 2011 at 23:52 UTC ( #883017=note: print w/replies, xml ) Need Help??

in reply to Re^3: reduce like iterators
in thread reduce like iterators

Shoot! I totally get the semi-predicate problem, and you stated the problem clearly in the OP, but I thought I had a brainwave and rewrote my UPDATED code, which had actually accounted for the problem.

So anyway, I re-read the entire thread and I sort of get why you'd want, say, a $^PRE special variable. But it is so trivial, I don't see why you'd bother. You are simply dealing with a list in pairwise fashion, using a previous value to evaluate a current value. Eliminating adjacent dupes is trivial...

@new = map { $p ne $_ ? $p = $_ : () } @orig;
except for an initial undefined value, but only because $p is initially undefined. So you define it and it works. And it's easy to remember.
$p = 'supercalifragilistic'; @new = map { $p ne $_ ? $p = $_ : () } @orig;
You could define a uniq_adj function...
use strict; sub uniq_adj { my $p = 'supercalifragilistic'; return map { $p ne $_ ? $p = $_ : () } @_; } my @orig = (undef, undef, qw(a a b b c 0 c d d u u 0 0 "0" "0" '0' + '0')); my @new = uniq_adj @orig; print "'", join ("' '", @new), "'\n"; __END__ Prints --> '' 'a' 'b' 'c' '0' 'c' 'd' 'u' '0' '"0"' ''0''

I printed with single quotes to show where undef's are being printed. Note that 0, "0", and '0' are preserved. It's very generalizable. I predefined $p, but isn't that less work than having Perl do it through a built-in? I read through the entire thread again and it seems to fit the bill. Is this kind of what you're looking for?

Regardless, cheers!


Replies are listed 'Best First'.
Re^5: reduce like iterators
by LanX (Bishop) on Jan 19, 2011 at 00:09 UTC
    Your surely aware that replacing undef with a "magic" string is not a solution of the semi-predicate problem, because the magic string can also be an element of the processed list.

    Cheers Rolf

      In general and in theory, no.

      But lots of people have so done, and it works out reasonably well in practice. For a random example Dominus used char(20) for this purpose in the widely used Memoize. (Then documented the limitation.) This code is significantly faster than a robust escape mechanism would have been, and he provided a mechanism to fix the potential bug if you needed to.

        I know and agree that the probability of a bug is much smaller when using a magic string, and at the end "bug-freeness" of non-trivial code is only a product of probabilities.

        In other words IT isn't math!

        But I prefer solutions where I don't have to document (and keep in mind) rare side cases.

        Especially in this case, simulating reduce's approach to start with the first two values is clean and elegant.

        Cheers Rolf

      I don't know about "magic", but sure, I understand it's not a solution to the semi-predicate problem, but all the solutions are one kind of workaround or another, aren't they? Wouldn't a $^PRE built-in be undef at the start of your grep{} block and cause you the same problem? When it comes to the initial element of the list, wouldn't you still have the same problem no matter what kind of built-in variables you had available to you?

      reduce really doesn't make sense because that performs a function on the results of the previous run of the function. $a accumulates...something, but you end up with one value, not a new list. What you want is more like a grep -- deciding whether to allow a current value through based on a previous value.

      You can write a function that takes tuples and special cases $a, so it won't be skipped, but you didn't think that was elegant.

      You can write a function that initializes $p (or whatever you call it), and hide the details in the function, but you didn't like that either.

      In the end, you have to initialize $p, special-case the first element, or write much more complicated code just to avoid initializing $p. It all amounts to the same thing, so why not keep it simple? Obviously the semi-predicate problem is a very real concern, but it's also pretty trivial...

      My two cents...


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://883017]
and the rats come out to play...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (8)
As of 2018-06-20 13:34 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (116 votes). Check out past polls.