From 28f6b8acf81a53755ebd81118592bfb16d863528 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Thu, 27 Jul 2017 10:40:08 -0400 Subject: [PATCH] Finally committing the f-to-c examples of Sep 23, 2016 --- racket/syndicate/actor.rkt | 1 + racket/syndicate/examples/actor/f-to-c.rkt | 56 +++++++++++++++++++++ racket/syndicate/examples/actor/f-to-c2.rkt | 29 +++++++++++ 3 files changed, 86 insertions(+) create mode 100644 racket/syndicate/examples/actor/f-to-c.rkt create mode 100644 racket/syndicate/examples/actor/f-to-c2.rkt diff --git a/racket/syndicate/actor.rkt b/racket/syndicate/actor.rkt index 368c8df..b790ab2 100644 --- a/racket/syndicate/actor.rkt +++ b/racket/syndicate/actor.rkt @@ -1139,6 +1139,7 @@ (module+ implementation-details (provide actor-behavior boot-actor + make-field (struct-out field-descriptor) (struct-out field-handle) (struct-out actor-state) diff --git a/racket/syndicate/examples/actor/f-to-c.rkt b/racket/syndicate/examples/actor/f-to-c.rkt new file mode 100644 index 0000000..aba854e --- /dev/null +++ b/racket/syndicate/examples/actor/f-to-c.rkt @@ -0,0 +1,56 @@ +#lang syndicate/actor +;; After the Fahrenheit-to-Celsius converter example in "Fabrik - A +;; Visual Programming Environment", Ingalls, Wallace, Chow, Ludolph +;; and Doyle, OOPSLA 1988. + +;;--------------------------------------------------------------------------- + +(struct versioned-value (value version write-id) #:prefab) + +(define (random-id) + (local-require racket/random sha) + (bytes->hex-string (crypto-random-bytes 16))) + +(define versioned-field-sentinel (cons #f #f)) + +(define (make-versioned-field name initial-value) + (local-require (only-in (submod syndicate/actor implementation-details) make-field)) + (define f (make-field name (versioned-value initial-value 0 ""))) + (match-lambda* + [(list) (versioned-value-value (f))] + [(list (== versioned-field-sentinel eq?) 'get-field) f] + [(list new-value) + (f (versioned-value new-value (current-inexact-milliseconds) (random-id)))] + [(list new-value cause) + (define cause-f (versioned-field->field cause)) + (match-define (versioned-value _ my-version my-write-id) (f)) + (match-define (versioned-value _ cause-version cause-write-id) (cause-f)) + (when (or (> cause-version my-version) + (and (= cause-version my-version) (string>? cause-write-id my-write-id))) + (f (versioned-value new-value cause-version cause-write-id)))])) + +(define (versioned-field->field vf) (vf versioned-field-sentinel 'get-field)) + +(define-syntax-rule (versioned-field [id init] ...) + (begin (define id (make-versioned-field 'id init)) ...)) + +;;--------------------------------------------------------------------------- + +(struct temperature (unit value) #:prefab) +(struct set-temperature (unit value) #:prefab) + +(spawn (versioned-field [C 0] [F 32]) + (begin/dataflow + (F (exact->inexact (+ (* (C) 9/5) 32)) C) + (C (exact->inexact (* (- (F) 32) 5/9)) F)) + (assert (temperature 'C (C))) + (assert (temperature 'F (F))) + (on (message (set-temperature 'C $v)) (C v)) + (on (message (set-temperature 'F $v)) (F v))) + +(spawn (on (asserted (temperature $unit $value)) + (printf "Temperature in ~a is ~a\n" unit value))) + +(spawn (on (asserted (observe (set-temperature _ _))) + (send! (set-temperature 'C 20)) + (send! (set-temperature 'F 90)))) diff --git a/racket/syndicate/examples/actor/f-to-c2.rkt b/racket/syndicate/examples/actor/f-to-c2.rkt new file mode 100644 index 0000000..fb0441d --- /dev/null +++ b/racket/syndicate/examples/actor/f-to-c2.rkt @@ -0,0 +1,29 @@ +#lang syndicate/actor +;; After the Fahrenheit-to-Celsius converter example in "Fabrik - A +;; Visual Programming Environment", Ingalls, Wallace, Chow, Ludolph +;; and Doyle, OOPSLA 1988. + +(struct temperature (unit value) #:prefab) +(struct set-temperature (unit value) #:prefab) + +(spawn (field [temp 0]) + (assert (temperature 'C (temp))) + (on (message (set-temperature 'C $new-temp)) + (temp new-temp)) + (on (asserted (temperature 'F $other-temp)) + (temp (exact->inexact (* (- other-temp 32) 5/9))))) + +(spawn (field [temp 32]) + (assert (temperature 'F (temp))) + (on (message (set-temperature 'F $new-temp)) + (temp new-temp)) + (on (asserted (temperature 'C $other-temp)) + (temp (exact->inexact (+ (* other-temp 9/5) 32))))) + +(spawn (on (asserted (temperature $unit $value)) + (printf "Temperature in ~a is ~a\n" unit value))) + +(spawn (on (asserted (observe (set-temperature _ _))) + ;; (send! (set-temperature 'C 20)) + (send! (set-temperature 'F 90)) + ))