in reply to Re: Re: A set of new operators. In keeping with the design of Perl?
in thread A set of new operators. In keeping with the design of Perl?

use List::Util qw(min); $hash{$set}{min} = min @{$hash{$set}{data}};
I love that module. Thank goodness it's in the core since 5.8. Of course that doesn't address your beef, but in this case I think you're looking for aliasing, not a condensed form of the ternary. Some of that is available with Perl5 already, had you phrased your loop differently:
for (@{$hash{$set}{data}}) { $hash{$set}{min} = $hash{$set}{min} < $_ ? $hash{$set}{min} : $_; }
And in Perl6 (I'm probably getting the syntax wrong) it'd be something like:
my $min := $hash{$set}{min}; for(@{%hash{$set}{data}}) { $min = $min < $_ ? $min : $_ }

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re^3: A set of new operators. In keeping with the design of Perl? (aliasing)
by BrowserUk (Patriarch) on May 21, 2003 at 16:10 UTC

    List::Utils is great and was one the reasons I got around to upgrading. It replaced about half the routines in my personal utils module. The problem is that I need the min and max of each dataset, and iterating each dataset twice isn't ideal with huge datasets.

    I agree with your reduction when the array is of a reasonable size, but each dataset is 786,432 elements, there are several datasets and the operation isn't a one-off, so building a list in the for loop is kind of expensive I think? Hence the choice to use the lazy evaluation of the range op in a for loop to index the elements. That problem goes away once we get lazy-evaluating in P6.

    It still irks me that I have to type the operands, to what is essentially a binary operation, twice each, but it seems I'm the only one who sees that as a problem, and I don't relish causing, let alone being involved in, a 3 year p5p flame fest which I was told above is what it took to get ||= implemented:(.

    It's the same "I know that everything is available in the cpu for the processing required" type ire that I feel about the need to do

    my $n; my ($div, $rem) = ( int($n/10), $n % 10 );

    as I pontificated on at A better mod (%) operator?. It's not a "performance thing",

     my ($div, %rem) = $n %% 10;

    just seems cleaner. That I know that both values are available in the registers after either / or % means that even hiding the double division within a sub or overloading % or whatever still doesn't satisfy my sense of "once and once only:)


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      As for the single-pass problem, you can do that too:
      use List::Util qw(reduce); @hash{$set}{qw(min max)} = @{ reduce { return [ $a, $b ] if 'ARRAY' ne ref $a; return $a->[0] < $b ? [ $b, $a->[1] ] : $a->[1] > $b ? [ $a->[0], $b ] : $a; } @{$hash{$set}{data}} };
      Admittedly more hoop jumping here. Of course that doesn't address the memory problem, but in that case I'd still opt for a counter in a while loop instead. (In keeping with the corresponding use of while and each to traverse a hash.)
      for my $min ($hash{$set}{min}) { my $data = $hash{$set}{data}; my $i = -1; while(++$i < @$data) { $min = $min < $data->{$i} ? $min : $data->{$i}; } }

      Makeshifts last the longest.