Python equivalent of call/cc?

The Pythonista none at this.time
Wed Jul 9 17:04:42 CEST 2008


Yesterday, I was hacking around a bit, trying to figure out how to 
implement the semantics of call/cc in Python.  Specifically, I wanted to 
translate this Scheme code to equivalent Python:

####

(define theContinuation #f)
 
 (define (test)
   (let ((i 0))
     (call/cc (lambda (k) (set! theContinuation k)))
     (set! i (+ i 1))
     i))

  (test)
  (theContinuation)
  (theContinuation)

####

Incidentally, those last three lines evaluate to 1, 2, and 3, 
respectively.

The best Python translation I could come up with was something like this 
(targeted at Python 2.5):

####
import inspect

theContinuation = None

def call_cc (f):
    f (inspect.currentframe().f_back)

def invoke (c):
    exec c.f_code in c.f_globals, c.f_locals
    
def test():
    i = 0
    call_cc (lambda k: globals().update({'theContinuation' : k }))
    i = i + 1
    print i

test()
invoke (theContinuation)
invoke (theContinuation)

####

Now, this code is wrong on a number of levels [I am indeed aware of 
exactly how ugly that lambda is...], but, in particular, my 
continuations / stack frames don't seem to be resuming at the right 
point.  I'd expect invoke (theContinuation) to restart on the line 
immediately following call_cc, but it does not.  Not surprisingly, the 
output is also wrong.  (I get 1, 1, and 1 rather than 1, 2, and 3.)

Can anyone help me by, perhaps pointing out some silly error I made?  
Failing that, can someone show me a working implementation of call/cc 
(preferably based on some form of stack inspection)?

Thanks!
-- 
code.py: A blog about life, the universe, and Python

http://pythonista.wordpress.com
** Posted from http://www.teranews.com **



More information about the Python-list mailing list