- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Count(comments) = 0 ? "Frist" : "Discourse is the real WTF"
Admin
An ingenium example of the frist reason to use ternaries.
Admin
Admin
Stop trying to make discourse happen.
Admin
Personally, in all my years of reading the daily WTF, I have had zero use for Discourse.
Admin
dis·course, Latin - from the verb discurrere, from dis- 'away' + currere 'to run'.
So it originally meant 'run away'? See, even the Ancient Romans were trying to warn us against using it!
Admin
Discourse in an ancient African word meaning "I'll spam your browser history with thousands of meaningless links".
Admin
I suggest that the string "Frist!" be prepended to @PaulaBean's posts.
Admin
Well, ok. This code sample clearly shows how bit flags shouldn't be read.
However, the introduction text is something I vehemently disagree with. The ternary operator is a great tool to make code more readable by dropping unnecessary syntactic verbosity. Not to forget, it gives you a LISP-style if in C-Style languages without any parenthesis hell!
Admin
Btw, that line of code doesn't seem to be doing anything. It's just an expression that returns a string.
Are they missing an assigment?
Admin
I knew someone who wrote a functional program in C with just one function —
main()
— and just one statement —return
. It was some of the most flagrant abuse of ternaries and comma operators that I've ever seen, and that was before you got into the realms of all the undefined behaviour with which it was strewn.It edited DOS boot sectors (as far as I can remember; it was a long time ago).
Admin
The ternary abuse is one thing ... but I cannot figure out the bit operators.
At some point you don't have a bitfield anymore, you functionally have an integer. This seems like a really bad way to write "switch (FailSafe & 0x0F)"
Admin
PS Note that it isn't C.
Admin
...0?'Bad configuration':'FILE_NOT_FOUND'
There. Much better!
Admin
You could increase readability tremendously just by properly formatting and rewriting the conditions (I'm assuming this is a language with sane precedence and associativity — ie, not PHP — and getting rid of the extraneous parens too):
Compare to the same conditions but with
if
statements instead:Admin
These remarks translate into the following logic:
"I have not used feature X." "I have seen an example of feature X abused." "Ergo feature X must be bad".
Which might be a wtf in its own right.
Admin
Admin
TRWTF is not the ternary operators instead of if-else (although ternary operators for complex if statements, especially nested ones, are certainly a wtf). It's that there's four different things representing known problems, any combination of which could be non-zero, and it tests for each possible combination - a total of 16 conditions, not counting all zero and anything other than those four being non-zero, even though it always does the same thing for, e.g. FailSafe&2 != 0 regardless of how many others there are.
Edit: slight improvement
Admin
I meant associativity. PHP's ternary operator is unintuitively left-associative. I amended my post.
Admin
Some lazy sod couldn't be bothered to add the braces when converting the inner if() from a simple assignment.
My main argument for avoiding the ternary is that it is so subject to abuse that allowing it outside of some strictly regulated circumstances is a really bad idea, sort of like how overt goto should be handled. Examples of reasonable ternaries are where you want to pass this or that parameter (depending on some condition) to a function without having to duplicate the rest of the function call. Unreasonable ones include constructions like in this WTF, but also things like this:
That is, call the appropriate one of these functions with the same argument list.
My main objection is not so much that ternaries hide conditions / if()s / switch-cases as that when reading the code I have to stop and decode them to work out what they are trying to do - the syntax is excessively quiet and the rules of precedence are a bit flaky across languages.
Admin
If this was a sane language that used C style precedence rules, you could write this very clearly as :
Brackets are superfluous as are !=0 conditions
Admin
Admin
Loving complexity of the operator here.
Admin
I read it as the author meant to type "I have had zero use for ternary operators".
Which makes infinitely more sense.
Admin
Not really.
Admin
My exercise was to use only delete :smile:
Admin
Depending on the use case, you might care about the performance of string concatenation in frequently-occurring conditions.
Admin
Not saying there IS zero use for...
Just saying the phrase
have had zero use of
is less likely meant than
have had zero use for
Admin
+1
@mark_bowytz should consider an example such as:
Personally, I prefer the ternary operator version of that:
Ultimately, it means the same thing, but it's easier to see what's going on since you just read the one line.
As for the stopping to decode them, that probably has more to do with how often you encounter them than anything. I use them all the time in my code, and I have no problem decoding (properly) used ternary operators. Ones like the monstrosity in the article take a while though.
As for the rules of precedence being flaky across languages, that's why I generally avoid using ternary operators in situations that would require multiple levels. If you have a simple, single level use case, the rules of precedence tend to be pretty clear.
Ah, the Blub paradox. I think you might be right that @mark_bowytz may be dealing with such a scenario.
Admin
I understood you. I'm saying that going from "had zero use of" to "had zero use for" isn't much of an improvement.
Admin
And if you are setting a hitherto undeclared variable using the ternary form is even more elegant:
Admin
Admin
Comparing boolean-valued things to true is a form of insanity. It isn't (normally) a problem in languages like C# or Java, but in C it is particularly dangerous - lots of values are (by the normal definitions of the language) true, but only one of them is equal to TRUE. All the other non-FALSE values are simultaneously true (not equal to FALSE) and false (not equal to TRUE). In C++ it is dangerous for a slightly different reason. I might write
if ( k == true )
but if k is not abool
, I will have problems because C++ will silently coercetrue
to 1 before comparing it to k, rather than the other way around.No, in general, you should compare against
false
as inif ( k != false )
or even just not do the comparison,if ( k )
.For real fun, though, consider the sinners who write an "operator bool()" member function in a C++ class, where that class might reasonably be used as a key in an STL container such as map or set. The map becomes effectively a map<bool, OtherThing> and therefore holds only two values. Member operator bool() is a favorite of people who are creating smart pointer objects. They should convert to a non-useful pointer instead: operator class ZogShallRule *() where ZogShallRule is defined nowhere, or even declare ZogShallRule as a private inner class:
You can still use DodgySmartPointer variables nakedly in if() and while() conditions (
if( dsp )
) but this method doesn't cause havoc in collections.Admin
C and C++ are dangerous. We've had type-safe alternatives for years.
Admin
Yeah, and then you spend two hours debugging your program before you notice that
if (P1IN & 0x80 == TRUE)
doesn't really do what you'd want it to. Twice. Been here, done that.And ternaries are insanely useful. Let's say you have
f(string x, int y)
, and you want to pass a "YES"/"NO" and 1/0 value depending on some conditions. Would you rather write:or
? To me, it's pretty much a no-brainer.
When doing low-level stuff, it's sometimes useful to just hack away without the regard for type safety. As long as you know what you're doing, that is.
Admin
In a way, it's even more dangerous with type-safe languages like Java and C#, where accidentally using a single equals sign in an if statement would normally cause a compile error, unless you happen to be comparing a boolean variable to a boolean literal.
Admin
Which you shouldn't be doing in the first place.
Admin
My point precisely.
Admin
Here's another example of useful ternaries. They're nested, even! Before Perl 5.12 (I believe), Perl didn't have switch or case. If you wanted to switch, you would have to do:
This should not be hard to read. It is a very informative structure.
Admin
Your last line seems to be a binary operator.
Admin
I always keep reading ternaries as questions. Something like "Case1? Yes? Ok, then result1." etc. It's pretty intuitive, in a way.
I also like C#'s
x ?? somevalue
- basically, a stripped-downx == null ? somevalue : x
. Another one of the more useful statements.Admin
Sure the code is messed up. However, another WTF is someone submitting code who may have been stuck in their ways enough to utter this opinion: "The only practical application of ternary operator is to either intentionally obfuscate your code or use it as a soapbox to brag about how "l33t" you are.".
At least here it's a pain to read through, but everything is clear past the formatting. If this had been something along the lines of a ridiculous lambda expressions using implied data types, then I might have agreed (some people shouldn't be allowed to have ReSharper... :-P ).
Admin
Oops, fixed. :)
Admin
Or JS's
||
Admin
Exactly. And under that reading,
:
is "exclusive or". Haskell's pattern guards look like:They've got almost the same amount of noise (very little to none)
That looks like a prism combinator. Does C# have a generalized framework for constructing prisms?
Admin
I would bet that in the code it actually is done like you posted, all spaced out and legible. Then either the submitter or Mark removed the whitespace and newlines to make it extra WTFy. Or a codeshrink utility (if it's an interpretted language) removed all the whitespace and newlines.
By the way, nice article, that massive ternary mess stands alone (even if it had been whitespaced properly, it's still nasty) and doesn't need a 20 page backstory. Well done.
Admin
And this is where your wrong assumption undermines your argument. He's saying that he hasn't had a situation where it's useful, not that he hasn't used it.
Admin
Meah.
Admin
Admin
Filed under: Optimization!