Create `speced/promise` `speced/promise-of`
vemv opened this issue · 2 comments
Context
'Promise' return values are non-trivial to spec: derefing them on :post
would make that defn blocking, defeating the purpose of promises
Task
Implement speced/promise
(a promise
replacement), plus speced/promise-of
(a spec predicate)
Example:
(defn promise [spec]
(let [p (clojure.core/promise)]
(fn [deliverable]
(assert (check! spec deliverable))
(deliver p deliverable))))
(spec/valid? (speced/promise-of ::foo) (speced/promise ::foo)) ;; true
Acceptance criteria
- Works analogously to clojure.core/promise
- The resulting spec checking is meaningful / strong
Additional resources
Would promise-of
block/defer the promise to check the result of the promise; or check whether the value is a speced/promise
is passed and the spec matches.
If the latter; how would we determine the match?
(spec/def ::foo string?)
(spec/def ::bar (spec/and ::foo (complement (clojure.string/blank?)))
(spec/valid? (speced/promise-of ::foo) (speced/promise ::bar))
this should be valid, but on spec1 i'm not sure we can determine this
or check whether the value is a speced/promise is passed and the spec matches.
the latter - the point of distinguishing between promise and promise-of is being able to check specs without blocking. Else we'd just have a unified promise
API
i'm not sure we can determine this
Specs are a protocol: