Python equivalent of call/cc?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • The Pythonista

    Python equivalent of call/cc?

    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)
    (theContinuatio n)
    (theContinuatio n)

    ####

    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.curren tframe().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().updat e({'theContinua tion' : k }))
    i = i + 1
    print i

    test()
    invoke (theContinuatio n)
    invoke (theContinuatio n)

    ####

    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 (theContinuatio n) 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

    A blog about life, the universe, and Python.

    ** Posted from http://www.teranews.com **
  • Larry Bates

    #2
    Re: Python equivalent of call/cc?

    The Pythonista wrote:
    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)
    (theContinuatio n)
    (theContinuatio n)
    >
    ####
    >
    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.curren tframe().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().updat e({'theContinua tion' : k }))
    i = i + 1
    print i
    >
    test()
    invoke (theContinuatio n)
    invoke (theContinuatio n)
    >
    ####
    >
    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 (theContinuatio n) 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!
    While I know absolutely no scheme what you show here is a generator in Python.

    def theContinuation ():
    n = 0
    while 1:
    n += 1
    yield n


    invoke = theContinuation ()

    print
    print invoke.next()
    print invoke.next()
    print invoke.next()

    Maybe that is what you are looking for?

    -Larry

    Comment

    • Aahz

      #3
      Re: Python equivalent of call/cc?

      In article <be112$4874d38a $18817@news.ter anews.com>,
      The Pythonista <none@this.time wrote:
      >
      >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)
      (theContinuatio n)
      (theContinuatio n)
      >
      Python relies on mutables to do this:

      class holder: pass

      def call():
      x = holder()
      x.counter = 0
      def cc():
      x.counter += 1
      return x.counter
      return cc

      foo = call()

      print foo()
      print foo()
      print foo()
      --
      Aahz (aahz@pythoncra ft.com) <* http://www.pythoncraft.com/

      "as long as we like the same operating system, things are cool." --piranha

      Comment

      Working...