Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

What's bad about Python?

Name: Anonymous 2005-12-21 8:09

Because I'm learning it, almost done through the tutorial, and it looks great.

Name: Anonymous 2011-07-27 0:10

>>200
Implementing call/cc requires writing a full-blown codewalker.

Name: Anonymous 2011-07-27 0:12

>>200
actually you can implement it quite easily with macros over lambda.

Name: Anonymous 2011-07-27 0:12

>>199
You can't in CL; you need Scheme and its realized continuations for that. Here's how you might do it:

(define (make-generator fun)
  (let ((current #f))
    (lambda ()
      (call-with-current-continuation
       (lambda (outer)
     (if current
         (begin (current))
         (begin (fun (lambda (value)
               (call-with-current-continuation
                (lambda (inner)
                  (set! current inner)
                  (outer value)))))
            (call-with-current-continuation
             (lambda (end)
               (set! current end)))
            (throw 'no-more))))))))

Name: Anonymous 2011-07-27 0:17

>>203
You can, but it wont be CL anymore.

Name: Anonymous 2011-07-27 0:29

>>204
So in other words, you can't in CL.

Name: Anonymous 2011-07-27 0:40

>>205
Consider (mapcar #'F Xs).
If F uses call/cc (it's common to use AMB during map), mapcar would crash, because it doesn't support continuations.
So one have to rewrite every high-order CL function and macros, like LET and PROGN.

Name: Anonymous 2011-07-27 1:26

>>206
There's nothing intrinsic about mapcar, let or progn that make them "not support continuations". If anything, you speak of some specific implementation of CL, which is a different thing altogether.

CL (the standard) doesn't support continuations at all, however.

Name: Anonymous 2011-07-27 1:33

>>207
I have (defun F (K ...) ...)
How can I force MAPCAR to pass F it's continuation as the first argument?

Name: Anonymous 2011-07-27 1:34

>>207
CL (the standard) doesn't support continuations at all, however.
It supports. Internally. It's called "return address", which is pushed onto stack.

Name: Anonymous 2011-07-27 1:38

Basically, one can't implement TCO, SIGNAL, BLOCK and RETURN-FROM without access to continuations. It must already be there.

Name: Anonymous 2011-07-27 2:34

>>203
I know how to do it using regular call/cc.  I was asking for how to do it using delimited continuations, more specifically, using shift/reset.  Since delimited continuations may be used to implement call/cc, it comes as no surprise that (make-generator f) may be implemented using delimited continuations.  However, I would like to know the most natural way of doing it, preferably without wrapping the code in a reset (which would amount to emulating call/cc, which involves an unfortunate copying of the entire stack).

Name: >>112 2011-07-27 3:13

>>199,211
I find it cleaner to define a yield procedure, instead of passing it as an argument, but that's doable too.

(define (yield . xs)
  (shift k (cons k xs)))

(define ((generator f) . xs)
  (reset (apply f xs) #f))

(define ((generator/yield-arg f) . xs)
  (reset (f yield) #f))

(define ((fioc-generator-of gen) f)
  (let ((g (gen f)))
    (lambda ()
      (let ((next (g)))
        (set! g (car next))
        (apply values (cdr next))))))

(define fioc-generator (fioc-generator-of generator))
(define fioc-generator/yield-arg (fioc-generator-of generator/yield-arg))

(define g
  (fioc-generator
   (lambda ()
     (for-each yield '(1 2 3 4)))))

(g) ; 1
(g) ; 2
(g) ; 3

(define g2
  (generator/yield-arg
   (lambda (yield)
     (for-each yield '(1 2 3 4)))))

(g2) ; (cont . (1))
((car (g2))) ; (cont . (2))
((car ((car (g2))))) ; (cont . (3))
((car (g2))) ; (cont . (2))

(define g3
  (fioc-generator/yield-arg
   (lambda (yield)
     (for-each yield '(1 2 3 4)))))

(g3) ; 1
(g3) ; 2
(g3) ; 3

Name: Anonymous 2011-07-27 3:16

>>209
It supports one-shot third class escape continuations with return-from too.

Name: Anonymous 2011-07-27 10:46

>>212
I find it cleaner to define a yield procedure, instead of passing it as an argument, but that's doable too.
I can explain.  The idea is that you can use the (f yield) directly, without wrapping it using (make-generator f), in order to call (yield x) on every generated element of f.  Whether this is actually useful is arguable.

Name: Anonymous 2011-07-27 11:54

>>214
If the yield escapes its generator procedures' dynamic extent, bad things can happen:
- It may capture and abort the current continuation up to the nearest reset, returning '(cont . args).
- In a multi-prompt implementation, it may interrupt whatever generator it is invoked within, or raise an error when you're not inside the dynamic extent of a generator.
- In a multi-prompt implementation, with every generator having a distinct prompt tag, it probably just raises an exception, but it does the right thing while still inside the original generator's extent.

Name: Anonymous 2011-08-15 0:59

>>115-117
Just wanted to correct myself, for future reference and archival purpose:

Let # be an unique continuation prompt delimiting the bottom of the metacontinuation
Let (C p k E) be a control operator that either captures a continuation up to the nearest active prompt tag p, or to the tag #, reinstantiating it, reified and bound to x

Call/cc is:

(define (call/cc f)
  (C # k (prompt p (f (lambda xs (C p _ (apply k xs)))))))


This should work.

Name: Anonymous 2011-12-22 14:14

python is shit

Name: Anonymous 2011-12-22 14:49

madoka a shit

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List