2015-10-22 15:35:30 +00:00
|
|
|
## Syntax
|
|
|
|
|
2015-11-17 18:15:39 +00:00
|
|
|
Just a sketch, at the moment.
|
2015-10-22 15:35:30 +00:00
|
|
|
|
2015-12-15 02:01:13 +00:00
|
|
|
Instantaneous actions, I := (actor I ...)
|
2016-04-07 07:42:54 +00:00
|
|
|
(dataspace I ...)
|
2015-12-15 02:01:13 +00:00
|
|
|
(state [B O ...] [E I ...] ...)
|
|
|
|
(background I ...)
|
|
|
|
(assert! P)
|
|
|
|
(retract! P)
|
|
|
|
(send! P)
|
|
|
|
(flush!) ;; ???
|
|
|
|
expr
|
2015-11-17 18:15:39 +00:00
|
|
|
Optional Bindings, B := ;; nothing, or
|
2015-12-15 02:01:13 +00:00
|
|
|
#:collect [(id I) ...]
|
|
|
|
Ongoing actions, O := (on E I ...)
|
2016-02-29 15:24:25 +00:00
|
|
|
(during P O ...)
|
2015-12-15 02:01:13 +00:00
|
|
|
(once E I ...) ;; ???
|
|
|
|
(assert P)
|
|
|
|
(assert #:when Pred P)
|
|
|
|
(track [x Agg] I ...)
|
|
|
|
(begin O ...) ;; ??? begin isn't quite right
|
|
|
|
Predicates, Pred := (not Pred) ;; -- NOT YET IMPLEMENTED
|
|
|
|
(exists P Pred) ;; -- NOT YET IMPLEMENTED
|
|
|
|
(forall P Pred) ;; -- NOT YET IMPLEMENTED
|
|
|
|
expr
|
|
|
|
Events, E := (asserted P)
|
|
|
|
(retracted P)
|
|
|
|
(message P)
|
|
|
|
(rising-edge Pred)
|
|
|
|
(falling-edge Pred)
|
2015-10-22 15:35:30 +00:00
|
|
|
Aggregates, Agg := (count expr P)
|
2015-12-15 02:01:13 +00:00
|
|
|
(set expr P)
|
|
|
|
(hash k_expr v_expr P)
|
|
|
|
(project P)
|
|
|
|
(single-value expr P)
|
|
|
|
(single-value expr P #:default def_expr)
|
|
|
|
Pred
|
2015-10-22 15:35:30 +00:00
|
|
|
Patterns, P := ... ;; uses $var as binder
|
|
|
|
|
2015-12-15 02:01:13 +00:00
|
|
|
(define-syntax-rule (until B E O ...)
|
|
|
|
(state [B O ...] [E (values)]))
|
2015-11-17 18:15:39 +00:00
|
|
|
|
|
|
|
(define-syntax-rule (forever B O ...)
|
2015-12-15 02:01:13 +00:00
|
|
|
(state [B O ...]))
|
2015-11-17 18:15:39 +00:00
|
|
|
|
|
|
|
Note also that `falling-edge` is encodable using `rising-edge` and
|
|
|
|
`not`, and that `forall` is encodable using `exists` and `not`.
|
|
|
|
|
|
|
|
`state` has the `B` bindings visible in the `I`s, and returns the
|
2015-12-11 17:20:50 +00:00
|
|
|
value(s) of the final `I` from the `E` exit branch that was chosen
|
|
|
|
*prepended* to the values of the calling actor's variables at the time
|
|
|
|
of `state` termination.
|
2015-11-17 18:15:39 +00:00
|
|
|
|
2016-04-07 07:42:54 +00:00
|
|
|
There are four kinds of actor-spawning `I`s: `actor`, `dataspace`,
|
|
|
|
`state` and `background`. Neither `actor`, `dataspace` nor `background`
|
2015-11-17 18:15:39 +00:00
|
|
|
yield a value; only `state` does so. However, both `state` and
|
|
|
|
`background` link to their invoking contexts, because `state` may
|
2015-12-11 17:20:50 +00:00
|
|
|
return values or crash, and `background` may crash. Actors using
|
2015-11-17 18:15:39 +00:00
|
|
|
`state` and `background` must therefore have a special continuation
|
|
|
|
table in their private state to link them to their `state` and
|
|
|
|
`background` logical-children-but-physical-siblings. The link
|
|
|
|
communicates values (on success) and crashes (on failure).
|
|
|
|
|
|
|
|
Q: Should exception values be transmitted on `state` failure? I think
|
|
|
|
no, but I am not sure there's a good reason why not.
|
|
|
|
|
|
|
|
Of the events, `asserted`, `retracted` and `message` require no
|
2016-04-07 07:42:54 +00:00
|
|
|
private-state, since the dataspace does the book-keeping for us.
|
2015-11-17 18:15:39 +00:00
|
|
|
`rising-edge`, however, needs to track the state of its predicate. If
|
|
|
|
the predicate happens to involve an `exists`, then an assertion set
|
|
|
|
must be maintained, like for a `track`.
|
|
|
|
|
|
|
|
This is leading me to believe that the order of operations is:
|
|
|
|
|
|
|
|
- Given a patch,
|
|
|
|
- update `track`s and assertion-sets related to `rising-edge`.
|
2015-12-09 01:12:27 +00:00
|
|
|
- handle `on` for `asserted`, `retracted` and `rising-edge`, in order of appearance
|
2015-12-03 21:45:27 +00:00
|
|
|
- check termination conditions
|
2015-12-09 01:12:27 +00:00
|
|
|
- maintain `assert`s and subscriptions for `on`s
|
2015-11-17 18:15:39 +00:00
|
|
|
- Given a message,
|
2015-12-09 01:12:27 +00:00
|
|
|
- handle `on` for `message` and `rising-edge`, in order of appearance
|
2015-12-03 21:45:27 +00:00
|
|
|
- check termination conditions
|
2015-12-09 01:12:27 +00:00
|
|
|
- maintain `assert`s and subscriptions for `on`s
|
2015-10-22 15:35:30 +00:00
|
|
|
|
2015-11-17 18:15:39 +00:00
|
|
|
Actually, I'm not sure `falling-edge` is encodable using
|
|
|
|
`rising-edge`, since the initial state might be different. Do we
|
|
|
|
assume that the level is high when the level is unknown for a
|
|
|
|
falling-edge? I think it likely, given I think it likely that we
|
|
|
|
assume the level is low when the level is unknown for a rising-edge.
|
2015-11-03 02:40:12 +00:00
|
|
|
|
2015-11-17 19:00:45 +00:00
|
|
|
`when` is a bit tricky, because it should clearly apply to `on` and
|
|
|
|
`assert`, but it is not clear that it should apply to `track`.
|
|
|
|
Furthermore, what should happen if, mid-way through some interaction
|
|
|
|
involving assertions, the `when` predicate goes false? Should the
|
|
|
|
subscription be retracted? On balance, I'm starting to think that
|
|
|
|
`when` is a bad idea. In my sketches so far, there's only one place
|
|
|
|
it's used, to conditionally `assert` a set, so I've added `#:when` to
|
|
|
|
`assert` instead.
|
|
|
|
|
2015-12-09 23:59:49 +00:00
|
|
|
Note that `exists` (and so `forall`) are tricky because of the nested
|
|
|
|
`Pred`. For now, I'm not implementing them -- we'll see how painful it
|
|
|
|
is to use `track` and plain-old `expr` `Pred`s instead.
|
|
|
|
|
2016-02-29 15:24:25 +00:00
|
|
|
`during` is a quasi-macro, with defining equation
|
|
|
|
|
|
|
|
(during P O ...) === (on (asserted P)
|
|
|
|
(until (retracted P')
|
|
|
|
O ...))
|
|
|
|
|
|
|
|
where `P'` is like `P` but with all the binders in `P` instantiated
|
|
|
|
with their values at the time the `until` is started.
|
|
|
|
|
2015-11-03 02:40:12 +00:00
|
|
|
## Examples
|
|
|
|
|
|
|
|
```racket
|
2016-04-01 23:53:46 +00:00
|
|
|
#lang syndicate/actor
|
2015-11-03 02:40:12 +00:00
|
|
|
;; Simple mutable box and count-to-infinity box client.
|
|
|
|
|
|
|
|
(struct set-box (new-value) #:transparent)
|
|
|
|
(struct box-state (value) #:transparent)
|
|
|
|
|
|
|
|
(actor (forever #:collect [(value 0)]
|
|
|
|
(assert (box-state value))
|
|
|
|
(on (message (set-box $new-value))
|
|
|
|
new-value)))
|
|
|
|
|
|
|
|
(actor (forever
|
|
|
|
(on (asserted (box-state $value))
|
|
|
|
(send! (set-box (+ value 1))))))
|
|
|
|
```
|