Jump to content

Talk:Ternary conditional operator

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by 70.55.240.92 (talk) at 22:34, 11 May 2009 (order of subsections - should Stylistic examples be moved closer to top of document?). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Order of subsections for clarity?

Just noticed that in the PHP section an example of a multi-line switch-like statement is given, to illustrate a PHP associativity bug. This occurs before the "style" section at the end of the page that actually introduces this idomatic shortcut. Just wondering whether that style section, which is IMO more general than the langauge-specific sections, should be moved closer to the head of the article? 70.55.240.92 (talk) 22:34, 11 May 2009 (UTC)[reply]


argc argv example

What is the given argc argv example program good for? I don't understand what the

ostream& sout = name ? fout : cout;

statement does. --Abdull 06:15, 28 March 2007 (UTC)[reply]

It checks name to see if it is a null pointer. If it is, then it sets sout to a reference to cout (standard output), otherwise, it sets sout to a reference to the output stream fout. --Btx40 (talk) 19:53, 18 April 2008 (UTC)[reply]

Strongly Disagree

I don't know how to do so, but this page should be flagged as being a very biased viewpoint. The text runs counter to my experience of 20+ years as a professional software programmer. The only people who prefer the ternary conditional operator to the more readable if-then-else format (when both are allowed by the language syntax) are those people who have never had to maintain other people's code bases for any significant period of time. This opinion is found in industry standard texts, such as "Code Complete" by Steve McConnell. I would love to see a valid citation supporting the viewpoint presented here, i.e. that the ternary operator is NOT considered to be antiquated, harder to debug, and harder to maintain.

You should have datetimesign this comment cause it's a little bit hard to find out if your remarque have been took in count. I don't really read the "very biased viewpoint" you were talking about. This may have corrected and I'm aggry with that: Wikipedia is not here to gave personnal point of views. ...But personnaly... I got a 10 years experimentation of web developping with the speciality of technology crossing and I prefer the ternary operator for conditional values. And I have a lot of arguments to justify the fact that I find it more readable than a huge structural block. And I'm sorry for your unability to read it as easy as it is. Lacrymocéphale 195.154.218.123 13:11, 13 November 2007 (UTC)[reply]
Maybe "This is much more readable and is more immediately recognized than the if statement equivalent." at the tail of the article is one of that "biased viewpoint" things. It's make me laugh cause for me it's similar to 'switch' statement which is not similar to 'if' statement... But, true, that kind of sentences have nothing to do here. But it's also informational to say, at the begining of this "?: in style guidelines" paragraph, that this operator is concidered as bad practice by some guidlines authors. And the writing dates of those guidelines should be added, could be revelant. Ok. This matter should only be a paragraph about the fact that there's a kind of holy war about readability of this operator without joinning the war. Lacrymocéphale 195.154.218.123 13:40, 13 November 2007 (UTC)[reply]
I agree completely that this article shows a clear bias towards using the ternary operator. A perfect example is the quote you mentioned above ("This is more readable and immediately recognized than an equivalent if/else or switch construction"), which I find to be patently untrue. I had to look at that code for a moment to figure out what it was doing, whereas an if/else or switch construction is immediately recognizable. I would wager that most novice programmers would react similarly. So in short, this article is proscribing a "correct" way to do programming, without providing any real support for why it is correct. If the author(s) can find authoritative citations about ?: being more maintainable or more readable, that is one thing, but it just looks like soap-boxing right now. (I would like to note that I am not personally opposed to the use of the ternary operator when it is appropriate and readable, but Wikipedia articles should be purely informational with a NPOV, and I do not think this article satisfies those requirements.) --Carychan (talk) 16:41, 7 March 2008 (UTC)[reply]
The article has been improved, however some trimming could be done. Statements such as "is most frequently used" and "most common usage" are claimed as facts without any references, nor are there likely to be any. If a statistical analysis of a large sample of code from diverse origins has been published and can be cited then that would be one thing, but otherwise the article should stick to explaining what the operator is, its history and a few examples and that's pretty much it.
In terms of whether it is preferable or not, well that is just opinion. After machine code, one of my first languages as a teenager was BCPL (on a BBC Micro co-processor), which is where this operator originates, and I've always felt that it has its place if used sensibly. As Carychan above illustrates, one downside of using more esoteric language features is that not everyone will recognise them immediately, although that should not be a problem if a development team has developers who are fully familiar and proficient with a language, and is not a reasonable argument in itself for avoidance.
One source of bugs is typographical errors and omitting to edit some code during maintenance, and use of the ternary may reduce the probability of such bugs by having a single assignment. An if/else construct with 10 assignments that should be to the same variable is 10 opportunities to use the wrong variable by mistake, and if the variable needs to be renamed during maintenance, 10 chances to miss a rename. As each code path is executed only a proportion of the time, unless coverage analysis is used to ensure that each code path is executed during testing, such a bug may remain undiscovered indefinitely. Using the ternary would be one assignment that would be affected by all code paths, and so easier to test and less likely to get wrong. In terms of readability, code using ternary for multiple assignments is more compact and has less extraneous text than alternative constructs, reducing eye movement and the need to scroll, and being easier and quicker to grasp the overall picture in one go. Bugs from faulty conditions may also be more immediately obvious, again from seeing the complete expression in most likely a single view. But this is an hypothesis only, and it might be an interesting cognitive psychology experiment to actually test the theory and see how quickly and accurately bugs in code are spotted when equivalent code is expressed using ternary, if/else and switch constructs.
Where I would draw the line is when some extra processing is required for some or all code paths, and the developer tries to be clever by introducing the comma operator to the expression. At that point readability may plunge and the chance of bugs increase significantly. This is one argument against using ?: in favour of if/else as should extra code be required for any of the conditions (which is unlikely though), given if/else usage it can be added easily but should force a rewrite if ternary was used. This is also an argument for always using braces for code blocks even where the statement is a single line, as being lazy and omitting braces can impair readability, reduces maintainability and increases the chance of bugs when extra code needs to be added in the future and the maintainer fails to correctly add braces at that point.
Moggie2002 (talk) 08:58, 18 April 2008 (UTC)[reply]

C# example

I think this would be an acceptable C# equivalent of the C++ example

using System.IO;

static void Main(string[] args)
{
    string name;
    StreamWriter stw;

    if (args.Length >= 1)
    {
        name = args[0];
        stw = new StreamWriter(name, true);
    }
    
    StreamWriter output = (name.IsNullOrEmpty() ? System.Console.Out: stw );
}

--Btx40 (talk) 20:10, 17 April 2008 (UTC)[reply]

This may be an equivalent literal translation, but would not behave the same as the C++ example in the case of a zero length string argument. With the C++ example and argc > 1, argv[1] will always yield a pointer, and the output stream would be the ofstream instance fout even for an empty string argv[1]. With the C# example, the output stream would be the console output in such a case. Had the C++ ternary been written as "ostream& sout = (argc > 1) ? fout : cout;", which more closely and correctly models the possibly intended behaviour of "try to open and use a file if an argument is supplied", then a precise translation would be more likely. The C# example might then set and test a boolean flag such as "filenameWasSupplied" if an exact copy of the C++ behaviour were required. This said, testing argc instead of name would preclude the possibility for the filename to come from another source in some cases (e.g. an environment variable), and a test for "was a filename supplied" is quite reasonable and more extensible.
Moggie2002 (talk) 10:11, 18 April 2008 (UTC)[reply]
In that case, both examples have one thing in common. The attempt to open the output stream would fail. The C# code would throw a System.ArgumentException, ending the program immediately (since there is no handler) while the C++ example would use setstate to set fout's fail bit.
As a result of an unhandled exception, the C# example would not assign a value to output because the last line would not run. --Btx40 (talk) 18:07, 18 April 2008 (UTC)[reply]
Here is a revised example that prevents a System.ArgumentException from being thrown.
using System.IO;

static void Main(string[] args)
{
    string name;
    StreamWriter stw;

    if (args.Length >= 1 && !args[0].IsNullOrEmpty())
    {
        name = args[0];
        stw = new StreamWriter(name, true);
    }
    
    StreamWriter output = (name.IsNullOrEmpty() ? System.Console.Out: stw );
}
--Btx40 (talk) 17:14, 22 April 2008 (UTC)[reply]


Python

I saw a trick a while back to do the ternary operator in python. It went something like this:

[false-condition, true-condition][condition]

Since booleans are 1 or 0 in python, the condition can be an index of a list, and the list can be the true/false conditions. Maybe this ought to be mentioned. --Belugaperson (Talk|Contribs) 00:30, 6 June 2008 (UTC)[reply]

Maybe we can add a paragraph about common workarounds for languages that don't have the ternary operator ?: built in. For example in PowerShell this would work:
# (false-condition, true-condition)[condition]
(3.1415, 42)[$true -eq $false]
3.1415
Ghettoblaster (talk) 09:41, 6 June 2008 (UTC)[reply]
This isn't an exact equivalent because it would eagerly evaluate both the false condition and the true condition regardless of which one you want. The ternary operator does lazy evaluation. 194.60.38.198 (talk) 08:50, 22 October 2008 (UTC)[reply]

Above

The page, no longer makes sense. It says, "in PHP uses the incorrect associativity when compared to other languages, and given a value of T for arg, the PHP equivalent of the above example " under PHP, even though the C example is below. Either the PHP text needs to be corrected, or the C needs to be moved up. Superm401 - Talk 19:08, 10 December 2008 (UTC)[reply]

You are quite correct. When I first added the inconsistency section it was at the end, immediately following the usage in style guidelines section where the example was indeed given, above. Restructuring and edits to the article since then have broken the previous flow.
Moggie2002 (talk) 01:14, 11 December 2008 (UTC)[reply]

MAX(a,b)

I just have to get this off my chest: the MAX(a,b) code here,

#define MAX(a,b) (((a)>(b))? (a): (b))

causes three evaluations instead of two, so it is inefficient and should not be used. Melchoir 10:19, 25 February 2006 (UTC)[reply]

More importantly it shouldn't be used because it may produce unexpected results, e.g. int z = MAX(++x, ++y); —Preceding unsigned comment added by 27 super goats (talkcontribs) 14:56, 9 May 2008 (UTC)[reply]

Even more importantly, operations that change state such as pre/post increment should not be used as parameters to capitalised functions as, according to common convention, it should be assumed that they will be cpp macros where parameters may be evaluated zero or more times and not exactly once.
Moggie2002 (talk) 13:48, 11 May 2008 (UTC)[reply]
Yet more importantly, new topics should be placed at the bottom of the page with their own header. Heh. Salvar (talk) 18:50, 23 March 2009 (UTC)[reply]