value-evt
1 Synopsis
2 API
value-evt
value-evt?
eventify
all-evt
8.12

value-evt🔗ℹ

David K. Storrs

 (require value-evt) package: value-evt

Wraps an arbitrary value into a synchronizable event.

1 Synopsis🔗ℹ

; value-evts are both evt? and value-evt?. They sync to their argument
> (define e (value-evt 9))
> e

#<value-evt>

> (evt? e)

#t

> (value-evt? e)

#t

> (sync e)

9

; 
; By default, syncing on a procedure syncs to the return value
> (define proc (lambda () (+ 2 2)))
> (sync (value-evt proc))

4

; You can instead get the procedure itself back
> (sync (value-evt proc #:eval-proc? #f))

#<procedure:proc>

; It's not a problem to specify #:eval-proc? on something that isn't a procedure
> (sync (value-evt "eval-proc? keyword is ignored for non-proc" #:eval-proc? #f))

"eval-proc? keyword is ignored for non-proc"

; 
; eventify always returns an evt
; Things that are evts are unchanged
> (define ch (make-channel))
> (evt? ch)

#t

> (eq? ch (eventify ch))

#t

; Things that are not evts become value-evts
> (evt? 'bob)

#f

> (evt? (eventify 'bob))

#t

; 
; by default, value-evts containing a list sync recursively
> (let ([result-ch (make-channel)]
        [arg-ch1   (make-channel)]
        [arg-ch2   (make-channel)])
    (void (thread (λ () (channel-put result-ch (sync (value-evt (list arg-ch1 arg-ch2)))))))
    (channel-put arg-ch1 'arg1-ch-ok)
    (channel-put arg-ch2 'arg2-ch-ok)
    (sync result-ch))

'(arg1-ch-ok arg2-ch-ok)

; 
; You can ask for it to return the original list
> (let ([arg-ch1   (make-channel)]
        [arg-ch2   (make-channel)])
  (sync (value-evt (list arg-ch1 arg-ch2) #:recurse-lists? #f)))

'(#<channel> #<channel>)

; 
; all-evt is the same as value-evt but takes a rest argument
; so you don't have to supply your own list
> (let ([result-ch (make-channel)]
        [arg-ch1   (make-channel)]
        [arg-ch2   (make-channel)])
    (define e (all-evt  arg-ch1 arg-ch2))
    (printf "all-evt returns: ~v" e)
    (void (thread (λ () (channel-put result-ch (sync e)))))
    (channel-put arg-ch1 'arg1-ch-ok)
    (channel-put arg-ch2 'arg2-ch-ok)
    (sync result-ch))

all-evt returns: #<value-evt>

'(arg1-ch-ok arg2-ch-ok)

2 API🔗ℹ

procedure

(value-evt v    
  [#:eval-proc? eval-proc?    
  #:recurse-lists? recurse-lists?])  value-evt?
  v : any/c
  eval-proc? : boolean? = #t
  recurse-lists? : boolean? = #t
Creates a synchronizable value-evt that by default will produce the original value when synced. There are two exceptions:

This provides a convenient way to run an arbitrary function and wait for it to complete without having to do polling, apply strictures to your interface (if the function is being passed in), or otherwise contort the code. If you want to actually return the lambda then you may use #:eval-proc? #f. Similarly, #:recurse-lists? makes it easy to handle the case where you want to wait for multiple events to complete before proceeding. A typical example would be waiting for a network connection to a server and simultaneously waiting for configuration files to be read and setup to be performed.

procedure

(value-evt? v)  boolean?

  v : any/c
Is the value a value-evt?

procedure

(eventify v    
  [#:eval-proc? eval-proc?    
  #:recurse-lists? recurse-lists?])  evt?
  v : any/c
  eval-proc? : boolean? = #t
  recurse-lists? : boolean? = #t
If v is a synchronizable event, return it unchanged. Otherwise, return (value-evt v #:eval-proc? eval-proc? #:recurse-lists? recurse-lists?). In most cases you’ll want to use this instead of using value-evt directly, since syncing on a (value-evt my-channel) will get you the channel itself instead of the first message on it.

procedure

(all-evt [#:eval-proc? eval-proc?    
  #:recurse-lists? recurse-lists?]    
  arg ...)  value-evt?
  eval-proc? : boolean? = #t
  recurse-lists? : boolean? = #t
  arg : any/c
Returns a value-evt the value of which is (map eventify args).