Defending the ternary operator
Andrew Dalke
adalke at mindspring.com
Mon Feb 10 01:54:37 EST 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