Fork me on GitHub
#clojure-spec
<
2017-04-14
>
fossifoo14:04:39

@gfredericks thanks for the example, instrument {:gen (f [] somegen)} works indeed

borkdude14:04:46

Before I post this to JIRA, could someone take a look if this is bug? https://gist.github.com/borkdude/95301951e81e3022674279d463783586

moxaj15:04:44

@borkdude reloaded.repl is not a valid symbol

borkdude15:04:51

@moxaj Why not - and why is this the only symbol in my dependencies causing problems?

borkdude15:04:29

(symbol? ’reloaded.repl) ;;=> true

moxaj15:04:33

yeah, I was wrong about that 😮 seems like a bug to me

moxaj15:04:00

if you move the quote inside the set it works

borkdude15:04:39

This also works:

user=> (def deps ’#{[org.clojure/core.async “0.3.442”]
    [prismatic/schema “1.1.4"]
    [com.stuartsierra/component “0.3.2”]
    [reloaded.repl “0.2.3"]})
#’user/deps
user=> (s/def ::dependency deps)

borkdude15:04:45

or the equivalent in a let, but not inside ->>. Probably because def and let are compiler level things and ->> is a macro

borkdude15:04:50

I can live with the let solution, but if it’s a bug, I’m happy to post it to JIRA

Alex Miller (Clojure team)17:04:12

the quoted form is expanded to (quote #{ ... })

Alex Miller (Clojure team)17:04:25

s/def is a macro - it doesn’t expect to find a (quote ...) form

moxaj17:04:52

@alexmiller why is it trying to resolve the symbol though?

Alex Miller (Clojure team)17:04:40

oh, it’s seeing a bare symbol with a “.” in it, which is interpreted as a class instance

Alex Miller (Clojure team)17:04:47

so it’s trying to load the class

Alex Miller (Clojure team)17:04:17

reloaded.repl is being interpreted like java.lang.String

Alex Miller (Clojure team)17:04:16

“it” here being the compiler, I don’t think it’s ever even getting to spec

moxaj17:04:53

@alexmiller to me it seems like the resolve call at the line I linked is responsible for the exception

moxaj17:04:00

or what do you mean by "not getting to spec"?

borkdude17:04:18

Then what’s the difference between calling

(-> '#{[org.clojure/core.async "0.3.442"]
    [prismatic/schema "1.1.4"]
    [com.stuartsierra/component "0.3.2"]
    [reloaded.repl "0.2.3"]})
which works and
(s/def ::dependencies '#{[org.clojure/core.async "0.3.442"]
    [prismatic/schema "1.1.4"]
    [com.stuartsierra/component "0.3.2"]
    [reloaded.repl "0.2.3"]})
which doesn’t ?

borkdude17:04:45

both are macros

Alex Miller (Clojure team)17:04:03

well the macros do do different things :)

Alex Miller (Clojure team)17:04:50

@moxaj you could be right - it’s basically the point at which the form passed to s/def is evaluated inside s/def

Alex Miller (Clojure team)17:04:14

s/def uses the form in both an evaluated and unevaluated context

borkdude17:04:54

but I quoted the form which should remain the same when evaluated?

moxaj17:04:54

replaced resolve with my-resolve to confirm

Alex Miller (Clojure team)17:04:35

during macro-expansion a quoted form is literally (quote ...) - it has not yet been evaluated

souenzzo17:04:55

+1 on clojure.spec use data > functions > macros.... I also have some problems related to this macros...

Alex Miller (Clojure team)17:04:58

the quote expansion happens during reading

Alex Miller (Clojure team)17:04:19

@souenzzo several parts of spec don’t work without macros

Alex Miller (Clojure team)17:04:20

also, keep in mind that spec forms are data and can be conformed into a map-y form with spec specs (and unformed back)

Alex Miller (Clojure team)17:04:56

they can also be transformed in the middle of that or even constructed straight from the mappy form via unform

mpenet17:04:19

Not yet right?

borkdude17:04:26

ok, so in the case of passing a set, it’s best to evaluate it before passing, instead of quoting it

Alex Miller (Clojure team)17:04:59

hard to say “best” - just that there is an interplay here between reading, macroexpansion, and the macro that is subtle

moxaj17:04:13

@borkdude in your case, the safest I believe would be to def it, and use the var

Alex Miller (Clojure team)17:04:25

@mpenet patch is on CLJ-2112. it’s not done yet but idea is there.

borkdude17:04:32

@moxaj yes, let also works (wrote that earlier already)

Alex Miller (Clojure team)17:04:38

(defn make-or [keys preds]
  (let [or-data {:s 'clojure.spec/or
                 :args (map #(hash-map :tag %1 :pred [:pred %2]) keys preds)}]
    (s/unform ::ss/or-form or-data)))
(make-or [:a :b] [`int? `keyword?])
;;=> (clojure.spec/or :a clojure.core/int? :b clojure.core/keyword?)

Alex Miller (Clojure team)17:04:58

was just playing with it this morning actually - there’s a function that makes a spec from data

mpenet17:04:13

So "are" -> "will be"

Alex Miller (Clojure team)17:04:48

well I’d say specs “are” data now, just that you need the specs for that data too

Alex Miller (Clojure team)17:04:55

the ::ss/or-form in the example above is the only missing piece

stand23:04:30

Is there some way of specing a situation where a map has mutually exclusive optional keys? That is neither ::a or ::b is required but if ::a appears, ::b may not and vice versa.

Alex Miller (Clojure team)23:04:14

You can and a predicate

Alex Miller (Clojure team)23:04:40

Or possibly multi-spec is a better match

stand23:04:09

Can you explain what you mean by "and a predicate?"