Defending the ternary operator

Andrew Dalke adalke at mindspring.com
Mon Feb 10 07:54:37 CET 2003


Paul Rubin on my analysis of some C++ code's use of "?:" :
> > EXAMPLE 1: (used 6 times)
> >
> >   return arr[i] & mask ? true : false;

> > If C++ does have a boolean type, then this isn't needed.  Even
> > when it didn't exist, it would have been easy to define, just like
> > the values 'true' and 'false' were defined.
>
> It's still needed, if you want the function to return true or
> false, instead of considering 0x1 and 0x04000 to be equivalent.

If C++ has a bool type and builtin true/false then the C++ code
quoted above can be replaced with

   return bool(arr[i] & mask)

If it doesn't have a bool type, then the project's standard
library, which includes a 'true' and a 'false' should include a
function like (excuse my rusty C++ experience)

template<T>
int bool(const T& cond) {
  if (cond) {
    return true;
  } else {
    return false;
  }
}

In either case, the "?:" should not be needed for this example.

> > EXAMPLE 2:

> I don't understand this one so I'll skip it.

It's very C++ specific and its requirement doesn't easily translate
to Python.  Briefly, C++ classes can have constant instance attributes.
Because they are constant, they can never be changed over the
lifespan of the instance.  But they must be initialized somehow.
C++ has a syntax to initialize these attributes before the constructor
is actually called, but it requires that only an expression be evaluated.
Hence the use if ?:.

> > EXAMPLE 3: (used twice, 3x each)
> >
> >   sprintf(outputStr, msgFmt, is_clean ? "CLEAN": "DIRTY",
> >             "spam=", spamStr,
> >             output_format == FORMAT1 ? "STR1" : "STR2",
> >             output_format == FORMAT1 ? "" : output_filename


> > For C++ this is useful.  Doesn't mean it's needed for Python.
>
> Doing it the same way in Python looks ok to me.

It's true.  However, I thought the original C++ code was going to
print the format name and the destination, and so would use
  output_format == ...
  output_destination == ...

Instead, the format name and destination are both encoded in
the same variable.  I had to look very closely to see that
this example wasn't a typo.  Whereas in my alternate expression
as

   if output_format == FORMAT1:
     extra_args = ("STR1", "")
  else:
    extra_args = ("STR2", output_filename)
 print outputStr %  (  (args, ...) + extra_args)

it's easy to see that both args are meant to be set by the
same option.

> > EXAMPLE 5:
> >
> >   // flg can be 0 ("no"), 1 ("same as last time"), or 2 ("yes")
> >   if (flg != 1 && cursor && (cursor.dirty() ? !flg : flg) {
> >      delete cursor;
> >      cursor = NULL;
> >   }
> >   if (!cursor) ...
> >
> >
> > I have a hard time following the logic.  I think it's more
> > understandable as
> >
> >   if ((flg == 0 and cursor and cursor.dirty()) or
> >       (flg == 2 and cursor and not cursor.dirty()):
> >
> > assuming I didn't get something swapped.
>
> Yes, it's clearer as originally written, no problem with getting
> something swapped.

I don't understand this.  You say the original expression is
clearer than my rewrite?  Or should that "as" be a "than"?

> And so on for other examples...

And so on?  So the original C++ uses were better than the
alternative versions I suggested were Python available?

                    Andrew
                    dalke at dalkescientific.com






More information about the Python-list mailing list