There are a variety of possible extensions to what is currently offered by 
spec wrt regex derivatives but that's up to Rich. 

On Friday, August 5, 2016 at 12:37:15 PM UTC-5, Russell Mull wrote:
>
> 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 clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to