More code block / closure ideas

Dave Benjamin ramen at lackingtalent.com
Tue Oct 14 04:30:23 EDT 2003


Here are some more ideas for how to implement a statement-friendly code
block syntax in Python. Hopefully more "Pythonic" (that is, of or pertaining
to those features noticably reminiscent of styles relating to things
Python-like; see: Pythonic) this time.

Warning to uninitiated: This is not real Python. I am playing make-believe.
If you are a Python beginner, kindly ignore this post unless you want to get
confused or you like made-up languages resembling Python.

1. Hey, let's just call a spade a spade.
 
def make_adder(num):
    return closure with other:
        return num + other

>>> make_adder(2)(3)
5

Here, "closure with" is the keyword. This would steal a keyword and probably
break some code. But nobody can ever tell you Python doesn't have closures
again; you can snap back with, "yes it does! there's even a keyword for it!".
End of argument. =)

2. The old proposal, but with square brackets.

scrollbar.on_press = [ event, window:
    print 'Got on press event: ' + event
    print 'x=%d, y=%d' % (window.x, window.y)
]

[: print 'no-argument closure']()

For reference, Smalltalk style is:

[:x | x printNl ]

But don't be deceived - the ':' is part of ':x', which is a symbol (kind of
like an interned string, if I understand correctly). I think the above
syntax is pretty close to ST, and has the less noisy square brackets,
not at all like Perl and therefore good. <jk>

3. Down'n'dirty lambda shorthand style (no statements):

return \x, y. x + y .\

They look like \. .\ but with variables before the first .
Maybe too hackish, but it certainly is minimal, just like lambda: is.
By the way, I still like 'lambda:'. Neener, neener. =)

4. A scoping twist:

x = 42
self.onEnterFrame = def(self, closed, over, variables):
                        del self.onEnterFrame
                        print 'on the next frame!'
                        print variables
                        print x # error! not explicitly specified!

The point behind this is that the "def" can later be lifted and turned into
a standalone function since it documents all of the variables it needs from
the enclosing scope. This would aid in refactoring later (extract function),
but still allow you to code "in place" for rapid prototyping.

Notice the indentation is relative to the actual def. This would be
enforced. As a result, you can use an editor with block-select to easily
de-nest the anonymous function and give it a name later.

5. Anonymous inner classes:

(removed as per Communications Decency Act)

6. Turn ; into an operator:

We barely use it. Why not make ; behave like C's , operator, like it does in
OCaml? It would just return the last evaluated value. You could write
something like:

>>> aList = []
>>> print [aList.append(x); x + 2 for x in range(4)]
[2, 3, 4, 5]
>>> aList
[0, 1, 2, 3]

Now, we still haven't escaped expression land, which is why we of course
must just bite the bullet and make print a function! Hey, it can't be that
hard, can it? ;)

7. With #6: put the "fun" in functional:

return (fun x, y -> print x; print y; x + y)

8. Hijack the ellipsis:

xml = make_parser()
xml.load(filename, ...)
xml.close()

def ...(dom):
   for element in dom.firstNode.childNodes:
       print element.attributes['name']

This lets you do the def *after* the actual function call. It's not nested
anymore, but because its definition is delayed until after the call, it
doesn't break the continuity. Unfortunately, there's only one ellipsis, but
I think the semantics are nice; it says "coming soon" to me. Kinda like the
web.

9. Macro!@!!!$**)))
+++ATH0
NO CARRIER




More information about the Python-list mailing list