PEP 308: A PEP Writer's Experience - PRO

Andrew Dalke adalke at mindspring.com
Mon Feb 10 02:54:08 EST 2003


Brian McErlean:
> if x > y:
>     result = x
> else:
>     result = y

Roy Smith:
> I'm probably going to hate myself in the morning, but I'm forced to
> admit that, in some ways, the long-winded way (which I've been
> advocating) is inferior.
>
> I'm a fan of refactoring (but not a zealot, in the XP-ish "refactor
> mercilessly" sense).  It's temping to want to factor the "result =" out
> of the above and end up with "result = ternary involving x>y, x, and y".
> There's both a cognitive advantage (you only have to read and understand
> it once) and a coding advantage (if you only type it once, there's no
> chance of introducing inconsistancy).

Consider also its potential misuses

One of the other branches of this thread looked for uses of ?:
in the C implementation of Python.  One such example was

> Modules/_sre.c:
> #define SRE_LOC_IS_DIGIT(ch) ((ch) < 256 ? isdigit((ch)) : 0)

This is used twice in that file, one as
     return SRE_UNI_IS_DIGIT(ch);
and the other as
    return !SRE_UNI_IS_DIGIT(ch);

Python does not have a macro, so were this written in
current Python it would be done as either an if/else statement

    if ch < 256:
      return isdigit(ch)
    return 0

or by making a function.  As a pro-refactoring person, I am
pretty certain you would rather make a function, because it
is used twice.

On the other hand, with an if/else expression the temptation is
strong to write this as

  return isdigit(ch) if ch < 256 else 0

After all, it's only two lines which are affected, rather than the
3 or 4 needed for a function, *AND* it saves the function call
overhead.

But as a refactoring fan, I'm also reasonably convinced you
would want this as a function definition because it's common
code.

If not, what's the cutoff?  3 repeats?  5 repeats? 20?  100?

so yes,
   result = x if f(x, y) else y
is shorter, more concise, and less prone to errors because the
'result' name isn't duplicated, etc.

But on the other hand, if this test is done a few times, it's
less likely you'll refactor the common case.

                    Andrew
                    dalke at dalkescientific.com
P.S.
Some people argue that having a small function increases cognitive
load because of the need to remember the name instead of simply
looking at the function.  This is a counter example to that argument
because there are several related functions, as in

#define SRE_IS_DIGIT(ch)\
    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0)
#define SRE_IS_SPACE(ch)\
    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0)
#define SRE_IS_LINEBREAK(ch)\
    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0)
#define SRE_IS_ALNUM(ch)\
    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0)
#define SRE_IS_WORD(ch)\
    ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0)

(Hmmm, looks like the code quote I did at the start of my post
was from a different version of sre.)

As you can see, these are all members of the same family, and
the meaning is obvious from the macro name, and learning what
one does helps understand what all do.






More information about the Python-list mailing list