Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • couldn't you write…

    my @reversed = induce { @$_ ? pop @$_ : end_of_fold } [ 1 .. 10 ];

    …and have end_of_fold undef $_?

    If you used a different localised variable, you might also be able to unfold undef values. But I don't really know if that is wanted.

    --phaylon

    --
    Ordinary morality is for ordinary people. -- Aleister Crowley
    • That makes it seem like the end_of_fold function is somehow special. I’d prefer people who use this to understand exactly how it works, and avoiding low-gain abstractions helps.

  • Why not return []'s which get flattened into the output until undef is returned?

        my @rev = induce {@$_ ? pop @$_ : undef} [1..10];

    But maybe I'm missing something as to why the prototype is &$ instead of &@, or am just wanting a better example? I would think that unfold might be more like:

        my @flat = map({map({$_} @$_)} [1..10],[12..20]);

    or thereabouts - and the 'reverse' example does not clarify that for me.

    • Why not return []’s which get flattened into the output until undef is returned?

      Because then there has to be an escape mechanism for the block to be able to return an actual [] that should be preserved in the output, and the block has to make sure to use it when appropriate.

      But maybe I’m missing something as to why the prototype is &$ instead of &@

      Because unfold (“induce”) takes a single value and inflates it to a list, as opposed to fold (reduce) which takes a list and def

      • Why not return []’s which get flattened into the output until undef is returned?

        Because then there has to be an escape mechanism for the block to be able to return an actual [] that should be preserved in the output, and the block has to make sure to use it when appropriate.

        No, you would not reach inside the returned ref - only flatten it at the first level. It is either [] or undef, so [[]] would be a list of one reference.


            my @power = induce {
                my $r = $_ % 12
                $_ /= 12;
                return $r ? [$r] : undef;
            } 4711;


            my @chunk = induce {
              (length) ? [substr $_, 0, 3, ''] : undef
            } "foobarbaz";

        The return $condition ? [@stuff] : unde

  • I played a bit with the concept, and found an issue I can't resolve, possibly you can help me here. The problem concerns whether $_ is an alias or a copy to the parameter passed. If it is a copy then you can't modify it unless it is a reference. If it is an alias you can't modify it if it is read-only. You may ask why should it be modified at all, and here comes the classic unfoldr:

    unfoldr { $_ ? ($_, $_ - 1) : () } 10;

    10,9,8,7,6,5,4,3,2,1

    which allows to pass arbitrary values to the callback .

    • Read my post; I addressed that concern. To reiterate: because the empty list is a valid return value. I want to be able to make compute state transitions on the input value without them having to contribute to the resulting list.

      It’s not hard to convert a read-only value to modifiable copy.

      if I want to send values other than the original parameter to myself (e.g. callback), then I can’t.

      You can. You just have to capture them with a closure. Admittedly that’s cumbersome.

      So yeah, it’s

      • Oh well, I could say the same, read my post; I addressed that concern too :) unfoldr actually allows to return empty lists. Here's a hacked quote from haskell description:

        The unfoldr function is a `dual' to foldr: while foldr reduces a list to a summary value, unfoldr builds a list from a seed value. The function takes the element and returns empty list if it is done producing the list or returns (@a,$b), in which case, @a is a appended to the list and $b is used as the next element in a recursive call.

        • But then you need to drag it along through all of your return values. That is cumbersome.

          Using $_ for the purpose is more idiomatic. The problem is in reusing $_ to signal the last iteration – that prevents you from unfolding undef, should you want to, and it bloats the code by your having to be careful not to return that undef when you meant to stop iterating.

          However I can’t think of any good way to signal termination out of band.

    • Btw, no, your point about alias vs copy is mistaken. The induce function above takes a copy of the value and then aliases $_ to that copy, so you are guaranteed to be able to modify the value, although if you want to preserve its last value past the unfolding, you want to arrange for that yourself.