Language mavens: Is there a programming with "if then else ENDIF" syntax?

Steve Howell showell30 at yahoo.com
Wed Nov 18 19:44:09 EST 2009


On Nov 18, 3:02 pm, Steven D'Aprano
<ste... at REMOVE.THIS.cybersource.com.au> wrote:
>
> That depends on the code. In particular, it depends on how coupled the
> code is. Ideally, you should have loosely coupled code, not highly
> coupled. If the code is loosely coupled, then there's no problem with
> understanding it in isolation. If the code is highly coupled, then it is
> hard to refactor it into a separate function, but that's a side-effect of
> the original problem, namely the high degree of coupling.
>

Different blocks of an if/elif/elif/elif/elif/end are never directly
coupled to each other, since you know that only one of the blocks is
gonna execute.  The blocks inherently do not effect each other.

What you really achieve by extracting the code from an inside an elif
block into a method is decoupling the elif block from the code ABOVE
the if.  This in and of itself is a good thing, of course, because you
get a nice clean namespace in the extracted method, and you make the
coupling between the code ABOVE the if and the extracted method
explicit by specifying which parameters get passed.  And in the case
of my original code, all seven methods that were extracted only
depended on a single parameter, the variable I was calling "ast," so
it was easy to dispatch them all using the same mechanism.  (In my
case I didn't achieve much in terms of cleaning the local namespace,
since the only variable defined above the if/elif/elif/elif/end was
"kind," but I did make my code less brittle to future changes.)

I am not going to defend "if/elif/elif/elif/elif/end" too vigorously
here.  There are obvious advantages to extracting methods, even
methods that only ever get called from one parent.  I do not miss
switch statements one bit in Python.  I am little more ambivalent
about anonymous methods.  It pains me just a tiny bit whenever I have
write code like this:

    dispatches = {
            'dict': handle_dict,
            'list': handle_list,
            'attr': handle_attr,
            'key':  handle_key,
            'as':   handle_as,
            'call': handle_call,
            }
    if kind in dispatches:
        return dispatches[kind](ast)
    else:
        raise Exception('unknown kind!')

I have used the idiom that Simon suggested in an earlier post, shown
below, but it is still brittle to name changes in a way that anonymous
methods are not, because you can't break an inline anonymous method
with a name change (the benefits on anonymity!!):

        try:
            method = getattr(self, 'do_' + kind)
        except AttributeError:
            raise Exception('unknown kind!')

        self.ast = ast

        return method()




More information about the Python-list mailing list