5 ms·
I'm confused what a function spec would look like using fdef (etc). Can someone write an example? If in Haskell we have a type signature f :: Type1 -> Type2
by georgewsinger 10y ago
I'm confused what a function spec would look like using fdef (etc). Can someone write an example?
If in Haskell we have a type signature
f :: Type1 -> Type2
...what will a clojure function spec roughly look like?
- puredanger 10y ago(spec/fdef clojure.core/range :args (spec/alt :infinite (spec/cat) :range-0 (spec/cat :end number?) :range (spec/cat :start number? :end number?) :step (spec/cat :start number? :end number? :step number?)) :ret #(instance? clojure.lang.Seqable %))```
- georgewsinger 10y agoInteresting. I don't know what to think. It's a lot to read. But in some ways adds more information than types (you can make reference to values). Maybe you could make it more concise with more definitions? For example: (def UnboundedInterval (spec/cat)) (def PositiveUnboundedInterval (spec/cat :end number?)) (def ClosedInterval (spec/cat :start number? :end number?)) (def StepClosedInterval (spec/cat :start number? :end number? :step number?)) (def SeqableInstance #(instance? clojure.lang.Seqable %)) And then: (spec/fdef clojure.core/range :args (spec/alt :infinite UnboundedInterval :range-0 PositiveUnboundedInterval :range ClosedInterval :step StepClosedInterval :ret SeqableInstance) Perhaps this would be non-idiomatic, and perhaps I'm trying to make this into something that looks like a static type annotation when it isn't.
- hcarvalhoalves 10y agoLooks sane, specially because you can (s/and ...) the specs so you should have reusable specs in some common namespace.
- catnaroek 10y ago> (you can make reference to values) Dependent types let you do just that as well. While theoretical computer scientists for the most part focus on dependently typed systems capable of expressing and proving any mathematical proposition (which obviously results in increased complexity), there exist more pragmatic variants of dependent types aimed at solving the everyday needs of programmers, with a minimum of annotation burden, see: http://hackage.haskell.org/package/liquidhaskell http://hackage.haskell.org/package/liquidhaskell
- puredanger 10y agoHere's another example showing how you can use the :fn spec to relate the :args and :ret values in arbitrary ways. (defn title-case "Capitalizes the first letter of each word" [s] (str/replace s #"(\w+)" (comp str/capitalize second))) (title-case "moving pictures") ;; => "Moving Pictures" (spec/fdef title-case :args (spec/cat :s string?) :ret string? :fn #(= (-> % :args :s str/capitalize) (-> % :ret str/capitalize)))