Suppose you have a reactive process, something that receives a message,
processes it, updates its, state, and repeats. For example:
(go-loop [s :initial]
(case (<! input-chan)
:a (recur :processing)
:b (recur :stopping)
nil [:success]))
In this contrived example, there are some implied valid state transitions:
:initial -> :processsing
:processing ->: :processing
:processing -> :stopping
:stopping -> (done)
This is pretty easy to write as a regular expression, using clojure.spec:
(s/def ::state-seq
(s/cat :s1 #{:initial}
:s2 (s/+ #{:processing})
:s3 #{:stopping}))
But with the clojure.spec api, we'd have to store the whole sequence of
states and validate it once at the end. To be useful for specifying a
sequence of values that are spread out over time, I'd really like to be
able to partially evaluate the schema with a single value when it is at
hand. The API doesn't expose this, but the implementation appears to
support it. It would require the ability to track the intermediate states
of the regex derivative, and the ability to do an explicit complete
(nullable) check. It could look something like this:
(go-loop [st :initial, sch (s/get-spec ::state-seq)]
(let [[valid sch'] (s/partial-valid? sch st)]
(when-not (valid)
[:error "everything is terrible"]
(throw "everything is terrible"))
(case (<! input-chan)
:a (recur :processing sch')
:b (recur :stopping sch')
nil (if (s/complete? sch')
[:success]
[:error "input channel closed, but we weren't in a done state"
]))))
This could also be useful for specifying something about the order of
values expected on a channel:
(s/def ::channel-message-seq
(s/cat :s1 #{:a}
:s2 (s/+ #{:b})))
(go-loop [sch (s/get-spec ::channel-message-seq)]
(let [[sch' msg] (s/partial-conform sch (<! input-chan))
(case msg
:a (recur sch')
:b (recur sch')
::s/invalid [:error "got unexpected message"])))
There are of course many convenient ways this could be packaged.
Is it feasible or desirable to add this to clojure.spec?
- Russell Mull
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.