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
| [reply] |
|
| [reply] |
|
| [reply] |
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
| [reply] |
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.
| [reply] [d/l] |
Re: Ternary vs. Sort vs. Max
by shmem (Chancellor) on Aug 10, 2015 at 10:31 UTC
|
$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'
| [reply] [d/l] [select] |
|
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.
| [reply] [d/l] [select] |
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,
| [reply] [d/l] [select] |
|
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
| [reply] [d/l] [select] |
|
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,
| [reply] [d/l] [select] |
|
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.
| [reply] [d/l] |
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. |