Deutsch   English   Français   Italiano  
<vdceue$1sli1$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Dmitri Volkov <dmitri.s.volkov@gmail.com>
Newsgroups: comp.lang.scheme
Subject: Toy asynchronous implementation
Date: Sun, 29 Sep 2024 16:56:46 -0400
Organization: A noiseless patient Spider
Lines: 101
Message-ID: <vdceue$1sli1$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sun, 29 Sep 2024 22:56:47 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="256c60e8b983c7252dba75bd9ff5a2ac";
	logging-data="1988161"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1+fbmc0MEB37n/Wr8b1WaUV"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:iNhUpo3Rhk7tDp0j93k7gSJQp3s=
Content-Language: en-US
Bytes: 3301

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)))))