Brian Sabbey wrote:
used, but rarely is because doing so would be awkward. Probably the simplest real-world example is opening and closing a file. Rarely will you see code like this:

def with_file(callback, filename):
    f = open(filename)
    callback(f)
    f.close()

def print_file(file):
    print file.read()

with_file(print_file, 'file.txt')

For obvious reasons, it usually appears like this:

f = open('file.txt')
print f.read()
f.close()

Normally, though, one wants to do a lot more than just print the file. There may be many lines between 'open' and 'close'. In this case, it is easy to introduce a bug, such as returning before calling 'close', or re-binding 'f' to a different file (the former bug is avoidable by using 'try'/'finally', but the latter is not). It would be nice to be able to avoid these types of bugs by abstracting open/close. Thunks allow you to make this abstraction in a way that is more concise and more readable than the callback example given above:

do f in with_file('file.txt'):
    print f.read()

Thunks are also more useful than callbacks in many cases since they allow variables to be rebound:

t = "no file read yet"
do f in with_file('file.txt'):
    t = f.read()

Using a callback to do the above example is, in my opinion, more difficult:

def with_file(callback, filename):
    f = open(filename)
    t = callback(f)
    f.close()
    return t

def my_read(f):
    return f.read()

t = with_file(my_read, 'file.txt')


Definitely put this example into the PEP. I didn't really understand what you were suggesting until I saw this example. All the other ones you gave just confused me more.


When I see 'do', it reminds me of 'do loops'. That is 'Do' involves
some sort of flow control.  I gather you mean it as do items in a
list, but with the capability to substitute the named function.  Is
this correct?

I used 'do' because that's what ruby uses for something similar. It can be used in a flow control-like way, or as an item-in-a-list way.

Please spend some time in the PEP explaining why you chose the keywords you chose. They gave me all the wrong intuitions about what was supposed to be going on, and really confused me. I also got mixed up in when you were talking about parameters to the thunk, and when you were talking about parameters to the function that is called with the thunk as a parameter.


I'd also like to see you start with the full example syntax, e.g.:

    do <unpack_list> in <returnval> = <callable>(<params>):
        <code>

And then explain what each piece does more carefully.  Something like:

"""
When a do-statement is executed, first <callable> is called with the parameters <params>, augmented by the thunk object, e.g.


    do func(4, b=2):
        ...

would call

    func(thunk_obj, 4, b=2)

Next, the body of the function is executed. If the thunk object is called, then <code> will be executed with the names in <unpack_list> bound to the objects with which the thunk was called, e.g.

    def func(thunk):
        thunk(1, y=2)
    do x, y, z=4 in func():
        print x, y, z

would call:

    func(thunk_obj)
        thunk(1, y=2)

and thus x, y and z would be bound to 1, 2 and 4 and the body of the thunk would be executed, printing "1 2 4".

The code in <callable> is then resumed, and the process is repeated until <callable> returns. Note that this means that each additional call to the thunk object will cause another execution of <code>, with potentially different bindings for the names in <unpack_list>.

When the function finally returns, the return value will be bound to <returnval>, e.g.:

    def func(thunk):
        thunk()
        thunk()
        return True
    do r = func():
        print "thunk called"
    print r

would print "thunk called" twice as the body of the thunk is executed for each call to thunk() in func, and then would print "True" in the code following the do-statement.
"""


Not sure if I actually understood everything right, but you definitely need a much more throrough walkthrough of what happens with a thunk -- it's not clear at all from the current pre-PEP.

STeVe
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to