• Toy asynchronous implementation

    From Dmitri Volkov@dmitri.s.volkov@gmail.com to comp.lang.scheme on Sun Sep 29 16:56:46 2024
    From Newsgroup: comp.lang.scheme

    Wrote a toy implementation of asynchronous programming using
    continuations. Posting here in case anyone might find it interesting:

    (define pop-effect!
    (lambda (es)
    (match (unbox es)
    [`() `(exit (void))]
    [`(,a . ,d)
    (begin
    (set-box! es d)
    a)])))

    (define queue-effect!
    (lambda (e es)
    (set-box!
    es
    (append (unbox es) (list e)))))

    (define handle-effects
    (lambda (es)
    (let ([eh (let/cc k k)])
    (match (pop-effect! es)
    [`(exit ,any) any]
    [`(wait-until ,time ,k)
    (cond
    [(> (current-milliseconds) time)
    (begin
    (k `(effect-info ,eh ,es))
    (eh eh))]
    [else
    (begin
    (queue-effect! `(wait-until ,time ,k) es)
    (eh eh))])]
    [`(output ,s ,k)
    (begin
    (println s)
    (k `(effect-info ,eh ,es))
    (eh eh))]
    [`(continue ,k)
    (begin
    (k `(effect-info ,eh ,es))
    (eh eh))]))))

    (define exit
    (lambda (any ei)
    (match-let ([`(effect-info ,eh ,es) ei])
    (begin
    (queue-effect! `(exit ,any) es)
    (eh eh)))))

    (define wait
    (lambda (ms ei)
    (match-let ([`(effect-info ,eh ,es) ei])
    (let/cc k
    (begin
    (queue-effect! `(wait-until ,(+ (current-milliseconds) ms)
    ,k) es)
    (eh eh))))))

    (define output
    (lambda (s ei)
    (match-let ([`(effect-info ,eh ,es) ei])
    (let/cc k
    (begin
    (queue-effect! `(output ,s ,k) es)
    (eh eh))))))

    (define continue
    (lambda (ei)
    (match-let ([`(effect-info ,eh ,es) ei])
    (let/cc k
    (begin
    (queue-effect! `(continue ,k) es)
    (eh eh))))))

    (define run
    (lambda (l)
    (let
    ([initial-effects
    (map
    (lambda (f)
    `(continue ,f))
    l)])
    (handle-effects (box initial-effects)))))

    ; example of use

    (run
    (list
    (lambda (ei)
    (begin
    (wait 5000 ei)
    (output "a" ei)))
    (lambda (ei)
    (begin
    (wait 3000 ei)
    (output "c" ei)))
    (lambda (ei)
    (begin
    (wait 500 ei)
    (output "b" ei)))))
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence D'Oliveiro@ldo@nz.invalid to comp.lang.scheme on Sun Sep 29 23:34:07 2024
    From Newsgroup: comp.lang.scheme

    On Sun, 29 Sep 2024 16:56:46 -0400, Dmitri Volkov wrote:

    Wrote a toy implementation of asynchronous programming using
    continuations.

    Continuations can be used to implement

    * coroutines
    * loop constructs
    * exceptions

    but not

    * arbitrary gotos.

    They truly are the universal control construct!

    I implemented them in GXScript <https://bitbucket.org/ldo17/gxscript/>,
    which is my attempt to create a more modern PostScript derivative (sans
    the graphics API), with proper lexical binding and some conveniences to
    try to make stack-based programming a little less error-prone.
    --- Synchronet 3.22a-Linux NewsLink 1.2