There is no logical equivalent to conditional statements!

For a long time, I have seen chunks of code in languages such as Lua and Python that claim that they can reproduce the C conditional operator just by using two logical operators, “and” and “or”.

The conditional statement in C uses the following format:

v = c ? t : f;

This is equivalent to saying “if the condition c (a boolean expression) is met assign t to v, otherwise assign f to v”. It’s a shorthand way of writing

if (c)
  v = t;
else
  v = f;

Some example outputs:

v = 1 ? "foo" : "bar"; /* v = "foo" */
v = 0 ? "foo" : "bar"; /* v = "bar" */
v = 1 ? 0 : 2;         /* v = 0 */

In the first example, the condition is true (C has no boolean type, anything that isn’t zero equates to true) so “t” is assigned. In the second example, the condition is false (zero) so “f” is assigned. The important thing to note here is that in the third example, the condition is true so “t” is still assigned.

As proof of this final value, the following was taken from a cgwin shell using the gcc compiler

~$ gcc --version
gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
~$ cat cond.c
#include <stdio.h>
 
int main(void)
{
  printf("The result is %d!\n", 1 ? 0 : 2);
 
  return 0;
}
~$ gcc -Wall -o cond cond.c
~$ ./cond
The result is 0!
~$

The following is an implementation in Python that always gives the same behaviour as the conditional operator in C.

def cond_if(c, t, f):
  if c: return t
  else: return f

We can show the same examples again:

>>> cond_if(True, "foo", "bar")
'foo'
>>> cond_if(False, "foo", "bar")
'bar'
>>> cond_if(True, 0, 2)
0

However, many people claim that the same code can be written more concisely and, more importantly, inline by using logical operators to mimic the behaviour. The following is such a function:

def cond_logic(c, t, f):
  return c and t or f

When we try to actually run this, with the same examples again, we see where it all falls down.

>>> cond_logic(True, "foo", "bar")
'foo'
>>> cond_logic(False, "foo", "bar")
'bar'
>>> cond_logic(True, 0, 2)
2

While it works for the first two examples as it should, any pair of values which can be equated to a boolean expression will corrupt the logic used. In this example, simply passing zero as the “t” makes the result of “c and t” false (because false and _ = false), which reduces it to “false or f”, which returns “f” (because false or _ = _). No combination of parenthesis or variables will correct this problem.

Here’s the final example again but this time in Lua:

> function cond_logic(c, t, f)
>>   return c and t or f;
>> end
 
> = cond_logic(1, false, 2);
2

So, the next time someone tells you that your code can be improved in this way or that logical operators can be used to mimic the conditional operator, tell them that they are wrong and give them an example to prove it, then stick to using if statements if the language does not provide a conditional operator.

Tags: , , ,

Leave a Reply