in reply to Mr. Ternary is greater than Mrs. If Else

Ternaries have readability problems: that's enough to shoot them down right there. The small amount of brevity you gain with them just isn't worth it.

Further, I'd claim that "if/else" constructs are eaisier to maintain, because if you need to check for another case later it's easy to stick in "elsif" clauses, but with ternaries you end up with "cascading ternaries", which strike me as even harder to read.

Notably though, Conway in his "Best Practices" doesn't recommend against ternaries, instead he just recommends formatting cascading ternaries in columns to improve readability.

  • Comment on Re: Mr. Ternary is greater than Mrs. If Else

Replies are listed 'Best First'.
Re^2: Mr. Ternary is greater than Mrs. If Else
by PerlPhi (Sexton) on May 19, 2007 at 17:39 UTC
    yes, readability at first is a problem with Mr. Ternary... i can't get wrong with that... but as often you use the ternary operator becomes handy. but wait my delima was this "\&". what was that execption for in the strict pragma?
      yes, readability at first is a problem with Mr. Ternary... i can't get wrong with that... but as often you use the ternary operator becomes handy. but wait my delima was this "\&". what was that execption for in the strict pragma?

      I think it is your dilemma, and yes: I had never seen it. Indeed, had you asked me, I would have guessed it was no valid syntax at all. And while I'm far from being a guru myself, I've seen quite a lot of code over the years, from gurus too. However reasoning on it a little, it's easy to see it simply amounts to taking a real reference after taking a symbolic dereference. The exception perldoc strict talks about is that that particular symbolic dereference, in that situation, doesn't issue an error, while it would in all the other situations:

      C:\temp>perl -wMstrict -e "\&{'foo'}" Useless use of reference constructor in void context at -e line 1. C:\temp>perl -wMstrict -e "&{'foo'}" Can't use string ("foo") as a subroutine ref while "strict refs" in us +e at -e line 1.

      Why you think you can use that instead of eval is completely out of my comprehension. The semantics is completely different.

        Consider
        perl -le 'use strict; my $foo = 1; $foo ? \&{print "foo"} : \&{ print +"bar"};' foo

        Inside a ternary ?: the expressions are evaluated - and \& { } constructs a code ref block which gets evaluated at runtime, to get at the name of the symbol table entry CODE slot from which a reference is taken.

        perl -MO=Concise,-exec -le '$foo = 1; $foo ? \&{print "foo"} : \&{ pri +nt "bar"};' 1 <0> enter 2 <;> nextstate(main 1 -e:1) v 3 <$> const[IV 1] s 4 <#> gvsv[*foo] s 5 <2> sassign vKS/2 6 <;> nextstate(main 3 -e:1) v 7 <#> gvsv[*foo] s 8 <|> cond_expr(other->9) vK/1 9 <0> pushmark sRM a <0> pushmark s b <$> const[PV "foo"] s c <@> print sK d <1> rv2cv[t3] lKRM/AMPER,33 <---- here e <1> refgen vK/1 goto f g <0> pushmark sRM h <0> pushmark s i <$> const[PV "bar"] s j <@> print sK k <1> rv2cv[t4] lKRM/AMPER,33 <---- and here l <1> refgen vK/1 f <@> leave[1 ref] vKP/REFC -e syntax OK

        <update>

        For the bare \& { } try e.g.

        perl -le 'use strict; my $foo = \&{ print "bar"}; $foo'

        </update>

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

        well first of all im not that good in understanding english terms that are so deep for me. but then let me rephrase your question... well correct me if im wrong... maybe you were asking me that, why did i use "\&" instead of eval, and because they have different functions right?

        my answer would be as follows:

        a couple of hours ago i was trying (tweaking) to make Mr. Ternary operator work on multi-statements. i tried a sub function definition inside the ternary but it didn't succeed, and so on and so forth. until i came up with that compilation error "Can't use string ("1") as a subroutine ref while "strict refs" ....". so i checked the documentation right away and found that exception in strict pragma "\&". but i didn't make use of it immediately instead i tried to use the eval block. since the eval block is just a single statement that can be used as a container of my multi-statements to function in Mr. Ternary. then, it succeeded. next is i tried to use the "\&", replace the word "eval" with that, and it worked well.

        so to wrap up my observations between "eval" and "\&":

        "\&" - is used while bullet proofing a program because it permits runtime error to exit my program so sudden. so the programmer could easily notice the error.

        "eval" - is used when you have finished bullet proofing a program. well it just trap runtime errors that was not caught by the programmer.

Re^2: Mr. Ternary is greater than Mrs. If Else
by PerlPhi (Sexton) on May 20, 2007 at 06:12 UTC

    well, overall its all about readability problems with Mr. Ternary...

    to easily remember the structure of Mr. Ternary a multi-decision structuring as follows:

    <expression> ? eval { <statement>; <statement>; <statement>; <expression> ? eval { <statement>; <statement>; <statement>; } : eval { <statement>; <statement>; <statement>; }; } : eval { <statement>; <statement>; <statement>; <expression> ? eval { <statement>; <statement>; <statement>; } : eval { <statement>; <statement>; <statement>; }; };

    NOTE: (eval or \& or do) well also work

    literally, Mr. Ternary is more on simple symbols that gives you a more concentration on expressions and statements without being bothered with words like if, elsif, and else.

    i don't think so that other languages could make Mr. Ternary more functional (making Mr. Ternary hold multiple-statements) than Perl could do. what do you think?

      This looks quite orderly, since the only words you are using here are 'eval', 'statement' and 'expression'. If you fill that with 'real code', the picture will get different, and the tiny ':' will get hard to spot at a glance.

      In contrast, 'if-elsif-else' statements stand out and are thus better readable on larger constructs.

      As for \& {}, that's an abuse of the coderef constructor and it will clutter up your symbol table.
      <expression> ? eval { <statement>; <statement>; <statement>; <expression> ? eval { <statement>; <statement>; <statement>; } : eval { <statement>; <statement>; <statement>; }; } : eval { <statement>; <statement>; <statement>; <expression> ? eval { <statement>; <statement>; <statement>; } : eval { <statement>; <statement>; <statement>; }; };
      if (<expression>) { <statement>; <statement>; <statement>; if (<expression>) { <statement>; <statement>; <statement>; } else { <statement>; <statement>; <statement>; } } else { <statement>; <statement>; <statement>; if (<expression>) { <statement>; <statement>; <statement>; } else { <statement>; <statement>; <statement>; } }

      What do you do with your large ?: construct if you have by chance to insert a third condition (a.k.a elsif) statement? Which of both columns is better readable? Can you tell at a glance if there's a semicolon missing (or one that causes a syntax error) on a line in the left column?

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

        okey... you got the power. well, i got no things in mind yet to mind storm with Mr. Ternary over Mrs. If Else. anyway my delimma was already solved. thanks guys. it was appreciated... i will come back to this topic very soon, if ever i find a good try over Mrs. If Else in Perl.

        now, the good news is Mr. Tarnary operator can be used in multi-statements unlike to what i usually hear about it (that it can only be used in single statement only).

      literally, Mr. Ternary is more on simple symbols that gives you a more concentration on expressions and statements without being bothered with words like if, elsif, and else.

      Indeed: if, else, elsif are flow control constructs. ?: is an operator. Now, it happens, thanks to short circuiting and the availability of constructs that take a block and execute it, that the latter can be used in a semantically equivalent manner to the former. Yet, as has been repeatedly explained to you in this thread, they serve different purposes: there are superimpositions and there may be some situation in which the choice is not obvious. But this is generally not the case.

      i don't think so that other languages could make Mr. Ternary more functional (making Mr. Ternary hold multiple-statements) than Perl could do. what do you think?

      I don't understand your question, but I'll make some guess and try to answer anyway: in some functional languages, the regular branching control structures behave much like (C and) Perl's ?: in that they return a value - exactly because they're functional. But seriously, your insisting on this issue makes me think that you're simply fond of the extreme conciseness you get out of it. OTOH several different monks already explained to you the reason why we generally do not strive for extreme conciseness: Perl has already a wrongly deserved bad name for being mostly line-noise, in some circles and speaking of other languages if I were to write programs that look like brainfuck I would... program in brainfuck! But then joy the world: Perl 6 will have a grammar modifiable at runtime, so you will be free to happily brainfuck it!