In Japanese, there are several different ways of expressing conditionality. For example, "[past tense verb ending in -ta] + ra" is one: "sore wo tabetara, byouki ni naru" = "If you eat that, you'll get sick." Another is "[plain form of verb] + to," as in: "sore wo taberu-to, byouki ni naru." The latter form always made sense to me because "-to" is also the Japanese word for "and." But at the same time, I was aware that this connection doesn't really make sense and I wasn't sure why it seemed to help me remember the conditional form.
I think today I realized why the connection exists in my head. It's related to a programming technique common in perl and bash shell scripting. Both of those programming languages implement short-circuit evaluation of conditional statements. That means that, supposing you have a perl statement such as:
if ( ($x == 1) && ($y > 2) ) print "omgwtfbbq!!!11";
The if statement will only evaluate as true if both conditions are true — the variable named $x is equal to 1, and the variable named $y is greater than 2. Thus, if the interpreter determines that $x is not equal to 1, it doesn't need to waste any time evaluating the other side of the && to determine the value of $y, because the statement as a whole is already known to be false. In this case, comparing $y to 2 is a minor calculation, but if each condition of the if were instead a computationally intensive function call, the advantage of not needing to execute the second function call at all could be significant.
Perl programmers often take advantage of short-circuit evaluation somewhat counterintuitively, to write more succinct code (Perl has a reputation for producing nearly unreadable code, but that's not perl's fault; it's the fault of perl programmers). Rather than writing a nice, legible statement such as:
if ($x < 0) $message = "Invalid value.";
You'll often find the same logic expressed like this:
$x < 0 && $message = "Invalid value.";
They are functionally identical — if $x is not less than 0, the interpreter will not evaluate the other side of the &&, and the text will not be assigned to the $message variable. And it did save two or three bytes of code, which wins you an equivalent number of geek scene points. But it's little tricks like this that contribute to the illegibility of typical perl code.
However, it is awesome to be able to say:
speak() or die;
Anyway, note how the succinct form of the example above looks a lot like the Japanese use of "and" as a way of expressing the concept that "if the one on the left is true, then I'm declaring that the one on the right is true as well." Although that sounds more like mathematical implication than intersection.
God. Japanese, perl, and binary arithmetic. I have friends who are interested in each of those three things, but I suspect that the Venn diagram of the three circles intersects at a single point, named Dan. :)
Posted by Bryan 14 hours, 2 minutes later
Actually, both php and javascript support this short-hand format as well; Although, the format is a bit different. More like:
$test true : false;
or the more useful:
print($test 'yes' : 'no');
Posted by Bryan 1 day, 14 hours later
But I suppose that's irrelavent to the 'and' factor of your post. Stupid me.
Posted by Dan 23 minutes later
Hehe, I actually wouldn't be surprised if the ternary operator (
(condition ? true_statement : false_statement)) could be used in this way as well, but that'd just be going too far :) I'm actually guilty of using the ternary operator a bit too much myself, and when I go back and read through my code I realize it is pretty confusing.But you're right, that doesn't really apply to the linguistics half of my entry :) Although really, in
perl, I tend to seeorused much more often thanand. It's mostly inbashshell scripting that I see the&&used as a conditional, such as:[ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshdI.E., if the file
/etc/sysconfig/sshdexists, then include and execute it.Posted by Bryan 2 hours, 11 minutes later
Aye, the all too famous (or infamous :) line from init scripts. I think that the frequency of its use in perl is based on the fact that most people who are writing shell scripts are already moderate to advanced programmers. Put that against PHP which is gaining huge recognition and a lot of new web programmers are using it; only doing things the way they leaned them the first time.
I believe that programming is closely related to mathematics. I’ve adopted a philosophy that I learned from a math video as a kid (‘Where There's A Will There's An A+’): If you can’t read and/or understand what you’ve done, your chance for error is higher.
I use the ternary operator sometimes but I try and stay away from it merely because I like nice and neat code. Another influence is from a book I’ve read, ‘Mastering Algorithms with Perl’, where the author goes into great detail about how different methods of evaluation use more or less resources (or merely memory vs. cpu). He also explains how ‘properly’ written statements evaluate *much* faster.
Example:
Print(‘Hello World’ . “\n”);
Evaluates 20% faster (cpu time) than:
Print “Hello World\n”;
I’m not sure what the performance difference is with an ‘if’ vs. ternary. I’ll have to test that out :) But in most cases, the server that I’m working with is powerful enough to handle the performance hit it may take for my cleanliness. You do have to be careful with thinking this way, though, because it could possibly destroy the scalability of your application.
Basically, it boils down to this: If I’m doing very complex calculations with mixed for loops, etc, I always write it neatly and document every step. If it’s a one liner: translate true/false (or the return of a function) to yes/no, then I’ll use the ternary operator.
Posted by Bryan 17 minutes later
After some benchmarking, it appears that the two statements evaluate at nearly the exact same speeed. So, it's left to asthetics. I'm glad you brought this up because I've been meaning to run this test for the past few weeks :)
FYI
perl test_ternary
Time taken was 3 wallclock secs ( 3.15 usr 0.15 sys + 0.00 cusr 0.00 csys = 3.30 CPU) seconds
Time taken was 4 wallclock secs ( 3.19 usr 0.20 sys + 0.00 cusr 0.00 csys = 3.39 CPU) seconds
Time taken was 3 wallclock secs ( 3.19 usr 0.13 sys + 0.00 cusr 0.00 csys = 3.32 CPU) seconds
perl test_if
Time taken was 3 wallclock secs ( 3.13 usr 0.15 sys + 0.00 cusr 0.00 csys = 3.28 CPU) seconds
Time taken was 3 wallclock secs ( 3.17 usr 0.11 sys + 0.00 cusr 0.00 csys = 3.28 CPU) seconds
Time taken was 3 wallclock secs ( 3.07 usr 0.19 sys + 0.00 cusr 0.00 csys = 3.26 CPU) seconds