This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-01-19
Channels
- # adventofcode (7)
- # aws (6)
- # babashka (7)
- # beginners (200)
- # calva (49)
- # chlorine-clover (3)
- # cider (24)
- # clj-kondo (115)
- # cljs-dev (5)
- # cljsrn (16)
- # clojure (44)
- # clojure-australia (9)
- # clojure-czech (1)
- # clojure-dev (1)
- # clojure-europe (63)
- # clojure-france (6)
- # clojure-losangeles (1)
- # clojure-nl (2)
- # clojure-spec (27)
- # clojure-uk (77)
- # clojurescript (45)
- # clojurewerkz (3)
- # conjure (5)
- # cryogen (1)
- # cursive (2)
- # datahike (6)
- # datascript (3)
- # datomic (18)
- # fulcro (5)
- # graalvm (55)
- # jobs (3)
- # luminus (4)
- # malli (1)
- # pathom (1)
- # reagent (16)
- # shadow-cljs (67)
- # spacemacs (18)
- # sql (57)
- # testing (6)
- # tools-deps (9)
I was thinking, is there (should there be) a way to describe something in spec as “this has to be produced from a call to that function”?
Sort of a bit like (s/fdef some-fn :args ... :ret ::the-thing)
without specifying ::the-thing
anywhere else, but, like, inverted: (s/def ::the-thing (s/ret-of some-fn))
. I don’t think there is a good way to fit this into conform
machinery, but I’m just thinking about the ability to express the API contract in spec (so far expressing it in the docstring is fine 🙂 )
@vlaaad you can do this without spec maybe, just by letting the "factory" function put in some unique property which indicates it was made by that function
you can also do this via .impl naming, e.g. create a defrecord in an impl namespace and have one public API function for creating those records
I also can use blanket (https://github.com/vlaaad/blanket) to cover the implementation details 😄 To be clear — I’m not looking for solutions outside of spec, I just thought the problem I’m solving is about describing the API, and spec seems like a fitting tool for this use case. I also heard @richhickey is redesigning spec particularly around fn specs, hence decided to share a use case to consider 🙂
I don’t understand the use case
Saying “this has to be produced from a call to that function” seems weird
Data is data
I want to express the intention — if next version returns something else (or more realistically — if the next version has more functions that produce something valid in a other context), it will remain valid in that other context
then spec the truth - what does the data look like?
don't couple the spec to code
this is the whole schema/select idea
select tells you what fields are selected from the schema at different points
then don't spec those parts
@vlaaad Wouldn't just speccing the return values in the namespace that effectively declares that structure be enough?
Would be speccing it with any?
(and a docstring when we get it) a better idea in this case?
why bother?
if it truly is "implementation details", then you are just erecting scaffolding and barriers in the way of future change
there needs to be some balance between the agility of Clojure data and the constraints of specs - don't spec everything to death
Sounds like a disapproving opinion. I want to express a single thing: the shape of this object is implementation detail, and despite this fact, it can be used in that context. This is not a barrier in the way of future change, and definitely not specing everything to death, this is a contract that helps user to see the relationship between parts of API.