Skip to content

Instantly share code, notes, and snippets.

@shriphani
Created January 30, 2012 09:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shriphani/1703524 to your computer and use it in GitHub Desktop.
Save shriphani/1703524 to your computer and use it in GitHub Desktop.
Scheme code to teach myself co-routines
#lang racket
;; loops using continuations
(define infinite-loop
(lambda (proc)
(letrec ((loop (lambda ()
(proc)
(loop))))
(loop))))
;; we will need to exit the loop @ some point.
;; so context is stored and when you meet an exit condition
;; you use the escaper to go for it.
;; I don't know what that means
(define countdown
(lambda (n)
(let ((receiver (lambda (exit-proc)
(let ((count 0))
(infinite-loop
(lambda ()
(if (= count n)
(exit-proc count)
(begin
(display "The count is: ")
(display count)
(display "\n")
(set! count (+ count 1))))))))))
(call/cc receiver))))
;; using the following piece of code
(display
(call/cc (lambda (cc)
(begin
((display "I got here.\n")
(cc "This string was passed as continuation's arg.\n")
(display "but not here\n"))))))
;; the continuation example from Ferguson et al
(+ 3 (* 4 (call/cc (lambda (continuation) (continuation 6)))))
;;(let ((start #f))
;; (when (not start)
;; (call/cc (lambda (continuation) (set! start continuation))))
;; (display "Going to invoke (start)\n")
;; (start))
;;(let ((start #f))
;; (call/cc (lambda (cc)
;; (begin
;; (display "Firdaus")
;; (set! start cc))))
;; (display "Invoking cc\n")
;; (start))
;; printing 1 -> n
;; printing values to n
(define count-n
(lambda (n)
(let ((count 0) (continuation #f))
(call/cc (lambda (cc) (set! continuation cc))) ;; continuation should contain increment+print
(when (not (= count n))
(begin
((set! count (+ 1 count))
(display count)
(newline)
(continuation)))))))
;; idiom for continuation programming
;; this guy just returns the continuation
;; in which it has been evaluated (i.e context + escaper)
(define (current-continuation)
(call/cc (lambda (cc) (cc cc))))
;; detect if continuation comes from elsewhere
(let ((cc (current-continuation)))
(cond
((procedure? cc) ...);;body
((future-value? cc) ...) ;; this is our own predicate
(else (error "fuck up"))))
;; generators
;; idea is to toggle between
;; 2 continuations
;; one contin in loop
;; another in the gen.
;; if new val needed, switch to gen
;; then pass val + cont for generator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment