[Python-ideas] Where-statement (Proposal for function expressions)

Carl Johnson cmjohnson.mailinglist at gmail.com
Sat Jul 18 05:19:18 CEST 2009


Steven D'Aprano wrote:


> It seems to me that the "where" construct makes writing code easier than
> reading code. It is a top-down construct: first you come up with some
> abstract expression:
>
> element = w + x.y - f(z) where:
>
> and then you need to think about how to implement the construct:
>
>    w = 2
>    x = thingy()
>    z = 4
>
> That roughly models the process of writing code in the first place, so I
> can see the attraction. But it doesn't model the process of *reading*
> code:
>
> "Hmmm, element is equal to w + x.y - f(z), okay, but I haven't seen any
> of those names before, are they globals? Ah, there's a 'where'
> statement, better pop that expression into short-term memory while I
> read the block and find out what they are..."
>
> In a real sense, the proposed 'where' block breaks the flow of reading
> code. Normally, reading a function proceeds in an orderly fashion from
> the start of the function to the end in (mostly) sequential order, a
> bottom-up process:

This objection seems to be a very convincing one. At the very least, I
think we should give up on the idea of having the "where" block use a
different scope, since that seems to cause more problems than it
solves.

For me, the original reason why where clauses looked appealing is that
I think there are some very limited cases in which the code reads
better out of order. My canonical example for this is "new_list =
sorted(old_list, key=...)" It just seems like sometimes you don't want
to hear about the key func until after you know that you're going to
sort a list. A simple "where" (or even "do … where" which might read a
little better) statement would solve this problem by basically just
letting you one line out of order.

do new_list = sorted(old_list, key=key) where:
    def key(item):
        do_data_normalizing_stuff…

I also think that most decorator definitions would look better with
the return at the top rather than the bottom:

def my_debug_decorator(f):
    do return inner where:
        def inner(*args, **kwargs):
            print(args, kwargs)
            return f(*args, **kwargs)

Yes, this nests a level deeper than usual (flat is better than
nested), but I think it's a lot less confusing than the usual form of
decorators with the return at the end where your eye doesn't know
where to rest.

On the other hand, it's not that hard to make a decorator decorator to
get rid of the weird return clause, and having any where statement at
all invites the abuse of nested wheres:

do x += y where:
    do y = z where:
        do z = x where:
            x = 2
print(x) # 4

Is the temptation for abuse here so strong that it will out weigh the
potential for readability gains? Does this construct violate TOOWTDI?

My answer is a definite… maybe.

So for now, I think "where" is not ready for prime time.

My 2 cents,

-- Carl Johnson



More information about the Python-ideas mailing list