http://qs321.pair.com?node_id=1137981

A line in BrowserUK's post reminded me of one of my cobwebs that I'm always chasing, namely, whether the Conditional Operator, ?:, is preferable over sort. In the end I should import a max function when possible, but I don't always do so.

Conditional operator:

my $n = $x > $y ? $x : $y;

I find this awkward to read, and it also duplicates the variable names.

Sort:

my $n = (sort {$a <=> $b} $x, $y)[-1];

But because sort needs a numeric sort function, that's a bit long winded.

And the max function:

use List::Util qw(max); my $n = max($x, $y);

Which seems to be the laziest and preferred way.

-QM
--
Quantum Mechanics: The dreams stuff is made of

Replies are listed 'Best First'.
Re: Ternary vs. Sort vs. Max
by GrandFather (Saint) on Aug 10, 2015 at 09:30 UTC

    The max version has the huge advantage that it actually says what the intent of the code is. The other variants require at least some pattern recognition or, worse, some thought to interpret.

    Premature optimization is the root of all job security
      worse, some thought

      Dog forbid that programmers should expend some thought.

        The wetware also only has a certain capacity, why waste it on something that can easily be made cheaper to process?

        Jenda
        Enoch was right!
        Enjoy the last years of Rome.

Re: Ternary vs. Sort vs. Max
by Tux (Canon) on Aug 10, 2015 at 09:44 UTC

    I personally prefer the ternary as it involves no overhead of extra scopes, loading modules and/or function calls: it is fast, obvious and clear (at least if you are acquainted with ternary syntax).

    Your worry about duplicating the value is only important if the implementation of ternary is such that it actually invokes the FETCH on the variable twice (in any language), which can be problematic is the value is overloaded and does magic on fetch.

    Calling sort could suffer the same, depending on the implementation.


    Enjoy, Have FUN! H.Merijn
Re: Ternary vs. Sort vs. Max
by BrowserUk (Patriarch) on Aug 10, 2015 at 10:38 UTC

    That sort construction is (IMO) far more obscure and obfuscate than the ternary.

    As for List::Util::max(); if I need to find the max() of a bunch (more than two) things, I use it, but -- just as my wife doesn't break out her food processor to slice a tomato for a sandwich -- for two items, the ternary construct is simple, efficient (and to me; clear). Perfect for the task at hand.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
    I'm with torvalds on this Agile (and TDD) debunked I told'em LLVM was the way to go. But did they listen!
Re: Ternary vs. Sort vs. Max
by shmem (Chancellor) on Aug 10, 2015 at 10:31 UTC

    Just for the sake of TIMTOWTDI:

    $max = ($x,$y)[$x<$y]; $min = ($x,$y)[$x>$y];

    which is a golfed version of your 2nd variant: (sort-of) a one-step sort which eliminates building a code block frame and the call of sort. Ternary is cheaper, since it doesn't involve bulding a list.

    update:
    I've been working at a place where restrictive coding standards prohibited ternary and forced me to write

    if ($x < $y ) { $max = $y; } else { $max = $x; }

    - which is as cheap as ternary (I guess) but looks convoluted to me - among other hilarities. Good riddance.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      if ($x < $y ) { $max = $y; } else { $max = $x; }

      When faced with the need to write a similar construct (e.g., the condition is too long to make an easily scannable ternary or the like), I find it easier to Just Pick One and then write one conditional, like

      $max = $x; if($x < $y) { $max = $y; }

      Aside from shorter, I find it actually more descriptive, especially if the other side is an else rather than elseif; "x except when y" as a description reads just like the code.

Re: Ternary vs. Sort vs. Max
by Athanasius (Archbishop) on Aug 10, 2015 at 14:08 UTC

    Hello QM,

    Another — possibly heretical? — option is to make max an inline function using a module such as macro:

    #! perl use strict; use warnings; use macro max => sub { $_[0] > $_[1] ? $_[0] : $_[1]; }; my $x = $ARGV[0]; my $y = $ARGV[1]; my $m = max($x, $y); print "max is $m\n";

    Output:

    0:05 >perl 1334_Med.pl 17 12 max is 17 0:05 >perl -MO=Deparse 1334_Med.pl Compiling 1334_Med.pl by macro::compiler/0.06 ... sub Digest::base::new; sub Digest::base::clone; sub Digest::base::add; sub Digest::base::digest; use macro ('max', sub { use warnings; use strict; $_[0] > $_[1] ? $_[0] : $_[1]; } ); use warnings; use strict; my $x = $ARGV[0]; my $y = $ARGV[1]; my $m = $x > $y ? $x : $y; print "max is $m\n"; 1334_Med.pl syntax OK 0:05 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Hi Athanasius,

      The macro is indeed interesting, as I've not delved in there before.

      However, that may suffer from techical debt. If I define a max macro that only handles 2 values, I (or my replacement) may call it later and give it 3 values, and only get the max of the first 2. Still, some careful coding (probably duplicating List::Util's max) could ensue.

      Edited to add:

      Also, it seems the macro syntax uses significant whitespace, which bugs me.

      Edited to add (2):

      The macro doc page has this:

      use macro add => sub{ $_[0] + $_[1] }; say => sub{ print @_, "\n"}; say(add(1, 3)); # it's replaced into 'print do{ (1) + (3) }, "\n";'
      which I'm assuming uses significant whitespace to figure out that say is a macro. (Or there's a typo semicolon on the first line.)

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        It’s just a typo:

        19:13 >perl pod.pl Useless use of a constant ("say") in void context at pod.pl line 6. Useless use of single ref constructor in void context at pod.pl line 6 +. Undefined subroutine &main::say called at pod.pl line 7. 19:39 >

        Whereas with a comma instead of the semicolon:

        19:39 >perl pod.pl 4 19:41 >perl -MO=Deparse pod.pl Compiling pod.pl by macro::compiler/0.06 ... sub Digest::base::clone; sub Digest::base::new; sub Digest::base::digest; sub Digest::base::add; use macro ('add', sub { use warnings; use strict; $_[0] + $_[1]; } , 'say', sub { use warnings; use strict; print @_, "\n"; } ); use warnings; use strict; print 4, "\n"; pod.pl syntax OK 19:41 >

        Hope that helps,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Ternary vs. Sort vs. Max
by eyepopslikeamosquito (Archbishop) on Aug 11, 2015 at 03:26 UTC

    For completeness, the preferred "artistic" solution:

    my $n = [ $y => $x ] -> [ $x >= $y ];
    BTW, this coding style question is discussed in the "Cleverness" section at the bottom of The Boy Scout Rule.

A reply falls below the community's threshold of quality. You may see it by logging in.
A reply falls below the community's threshold of quality. You may see it by logging in.