Name: Anonymous 2013-03-02 2:18
In this thread, you may post code that makes use of continuations, and I will attempt to produce code that does the same and looks reasonably similar, without using continuations.
(define yield-to-event-loop (lambda () (error "not set")))
(define (main-loop)
(dispatch (get-next-event))
(main-loop))
(define (dispatch event)
(cond
; Other internal and external events
; ...
((io-event? event)
(let ((cont (get-io-continuation (get-io-ticket event))))
(cont (get-io-data event))))
((resumable? event)
((get-resumable-continuation event)))
(else (unhandled-event event))))
(define (resource-manager init n)
; Limited number of resources, for instance file descriptors
(define resources (make-list-of-n-resources init n))
(define wait-queue '())
; Return a free resource, and wait until there is one to get
(define (get-resource)
(call-with-current-continuation
(lambda (k)
(if (null? resources)
(begin
; No free resource, resume caller later
(set! waiters (cons k wait-queue))
(yield-to-event-loop))
(let ((resource (car resources)))
(set! resources (cdr resources))
resource)))))
; Free a single resource and possibly let a waiting event handler run
(define (free-resource resource)
(call-with-current-continuation
(lambda (k)
(if (null? wait-queue)
(set! resources (cons resource resources))
(let (waiter (car wait-queue))
(set! waiters (cdr wait-queue))
; Suspend the caller for a while
(push-resumable-event k)
; Resume a waiting event handler
(waiter resource)))))
#t)
; Return dispatcher
(lambda (message)
(case message
((get-resource) get-resource)
((free-resource) free-resource)
(else (error "unknown message")))))
(define (read-from-io-device device)
(call-with-current-continuation
(lambda (k)
(let (io-ticket (schedule-read device))
(push-event-queue-io-continuation io-ticket k)
(start-io-event io-ticket)
(yield-to-event-loop)))))
(define io-manager (resource-manager make-io-port 4))
; Register some event handlers
(for-each
(lambda (event)
(register-event-handler event
(lambda ()
; Here, without continuations, you end up with node.js
; get-resource, free-resource and read-from-io-device all
; yield to the event loop if necessary
(let ((device ((io-manager 'get-resource))))
(display (read-from-io-device device)
((io-manager 'free-resource) device))))))
'(event-1 event-2 event-3))
; Start main loop
(begin
(call-with-current-continuation (lambda (k) (set! yield-to-event-loop k)))
(main-loop))