Fork me on GitHub
#clojure-spec
<
2018-10-04
>
misha08:10:32

@scot-brown 1) https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html#clojure.spec.alpha/fdef

Note that :fn specs require the presence of :args and :ret specs to
conform values, and so :fn specs will be ignored if :args or :ret
are missing.
2) https://clojure.github.io/spec.alpha/clojure.spec.test.alpha-api.html#clojure.spec.test.alpha/instrument does not validate against :ret and :fn fdef's spec-components, see: https://groups.google.com/d/msg/clojure/JU6EmjtbRiQ/uND70kAFBgAJ The official way to test against :ret and :fn of s/fdef - is test.check. Folks who accept performance price also use https://github.com/jeaye/orchestra instead of vanilla stest/instrument

noisesmith16:10:05

@misha thanks for the clarification

👍 4
noisesmith16:10:59

so instrument only validates the arglist and not the return value

alexmiller16:10:21

Yes- it instruments functions to ensure you are invoking them correctly

triss16:10:43

If I have a lot of functions all with the same spec how can I share it between them? I’m guessing I can use an fspec with fdef somehow? I really want these specs to show up in the doc strings

alexmiller16:10:55

Sure, name the common spec and use the name

alexmiller16:10:27

fdef is really a wrapper around fspec then def

👍 4
triss16:10:22

oh nice. Thanks @alexmiller

alexmiller16:10:34

So you can (s/def foo ::a) where ::a is an s/fspec

alexmiller16:10:59

There were some bugs around this but I think those are all fixed now

fabrao17:10:48

what is the right use? [clojure.spec.alpha :as s] or [clojure.spec :as s]. I tried [clojure.spec :as s] but it seems no lib in this path

seancorfield17:10:35

Spec is still alpha right now.

seancorfield17:10:45

[clojure.spec.alpha :as s]

favila17:10:01

always the namespace with "alpha". Clojure 1.9-alpha had a brief period where spec was in clojure core (not a separate lib). That is why you may see non-alpha namespaces sometimes.

seancorfield17:10:05

All of the Spec namespaces end in .alpha -- until it stops being alpha.

seancorfield17:10:34

@favila Ah, yeah, that must have been a fairly brief period 🙂

fabrao17:10:23

That´s because I was confuse

the2bears17:10:09

The great thing about REPL development is you can try these things very quickly and see which one works.

seancorfield17:10:24

There's a comment on that video, dated a year ago, that says "Good introduction! But something changed in the meantime: starting from 1.9.0-alpha16 you have to include clojure.spec.alpha" @fabrao

the2bears17:10:42

Though Lein setup with the project.clj file can slow that down a bit.

seancorfield17:10:11

@the2bears Aye, I always have a REPL open and I try stuff in it all the time.

4
favila17:10:35

https://clojure.org/community/devchangelog clojure 1.9.0-alpha16 is when it split. So from May 24 2016 to april 26, 2017 "clojure.spec" was the correct namespace

fabrao17:10:47

I left using lein for boot because of @seancorfield

seancorfield17:10:03

Longer than I realized -- thanks @favila for that detective work!

seancorfield17:10:29

Boot REPL is nice because you can easily add new dependencies without restarting the REPL!

fabrao17:10:53

that´s the main part I changed

fabrao17:10:29

C-c C-e in set-env! and that´s it

the2bears17:10:46

@seancorfield my problem is I lose track of my REPL's state from time to time 🙂 . But I have 2 or 3 open at any one time, usually, main project then libraries used in it.

fabrao17:10:43

I´ll do cider-connect and start it from command line

fabrao17:10:53

I tried to use Proto-REPL with Atom but I can´t leave Emacs anymore

fabrao19:10:42

In this case, I got Assert failed. Is there any way to custom error message?

(defn stringer-bell
  "Prints a string and rings bell."
  [s]
  {:pre [(s/valid? (s/nilable string?) s)]}
  (println s "\007"))

taylor19:10:32

maybe relevant thread here about custom pre/post messages https://groups.google.com/forum/#!msg/clojure/xHrFyDcPS9A/gXiNY6pmAwAJ

taylor19:10:51

one suggestion is to use clojure.test/is in the assertion

taylor19:10:09

(or something similar of your own)

fabrao19:10:35

thanks again taylor, as you see I little lost about using it

fabrao19:10:33

I tried

(if (not (s/valid? ::campos campo))
(throw (Exception. (str "Tipo do campo incorreto. Válidos = #{" (reduce #(str %1 %2 " ") "" campos) "}"))))

fabrao19:10:42

but is too much code, don´t you think?

taylor19:10:39

I think that reduce could be replaced with clojure.string/join maybe

taylor19:10:48

also, if you think you need this type of check a lot, you could easily define a function that takes a spec, an input, and maybe an error message or explain-data-to-string function; and then wherever you call it should be pretty terse?

fabrao19:10:30

I´m thinking use https://github.com/bhb/expound to be more explicity

taylor19:10:33

also check out https://github.com/bhb/expound if you haven't already, and I think there's a similar lib that's more geared towards user-facing error messages

fabrao20:10:32

thanks

👍 4
misha20:10:25

and (reduce #(str %1 %2 " ") "" campos) looks like (clojure.string/join " " campos)

👍 4
misha20:10:05

suddenly, not too much code opieop

ag23:10:26

if you are writing a s/fdef foo but want to place it in a separate ns (not the same where foo is), should you require the ns where the function is in ns where the spec is? But what if you need to use specs say for validation (in the ns where s/fdef is implemented) how do you avoid circular dependency?

ag23:10:20

or should you move higher order specs to a separate ns, but keep s/fdef foo where foo is implemented?

noisesmith23:10:57

isn't some of this simplified by the fact that the spec is looked up by a keyword? you can use a namespaced keyword before the namespace it nominally refers to exists

noisesmith23:10:23

by the time the spec is actually checked, you need the ns that defined the spec for that keyword to be loaded, of course