[racket] returning self as sync result with struct prop:evt and wrap-evt

From: Neil Van Dyke (neil at neilvandyke.org)
Date: Wed Jun 27 17:34:27 EDT 2012

If I have a struct that wraps an input-port, and I want the struct to be 
usable as an event that returns the struct as the sync result... is 
there an better way than the code below?

In the code below, I am using "letrec" to get around the fact that 
AFAIK, I need my "wrap-evt" proc arg to reference the struct itself, I 
don't have a reference to the struct while the struct is being 
contructed, and "prop:evt" won't let me reference a mutable field.

#lang racket/base

(struct my-struct
   (my-wrapped-evt
    my-wrapping-evt)
   #:property prop:evt (struct-field-index my-wrapping-evt))

(define (my-struct* my-wrapped-evt)
   (letrec ((my-wrapping-evt (wrap-evt my-wrapped-evt
                                       (lambda (ignored-wrapped-evt)
                                         s)))
            (s (my-struct my-wrapped-evt
                          my-wrapping-evt)))
     s))

(define (my-struct-read s)
   (read-byte (my-struct-my-wrapped-evt s)))

;; Test:

(define s (my-struct* (current-input-port)))

(printf "s = ~S\n" s)

(let loop ()
   (write-string "Syncing...\n")
   (let ((my-evt-result (sync s)))
     (printf "Reading from ~S...\n" my-evt-result)
     (let ((v (my-struct-read s)))
       (printf "Read ~S\n" v)
       (loop))))


(The reason I am wrapping an input port this way is because the struct 
ADT in my real program does bigger stuff whenever at least 1 byte is 
available on the port, not just return the single byte.)

Neil V.


Posted on the users mailing list.