Already asked in #cider but it looks unrelated, at least for one of my projects where it started to fail with lein repl (maybe a dependency update but I believed it worked fine and don't remember any changes in dependencies).
Caused by: Syntax error macroexpanding clojure.core/defn at (clojure/spec/alpha.clj:85:1).
at clojure.lang.Compiler.checkSpecs(Compiler.java:6972)
at clojure.lang.Compiler.macroexpand1(Compiler.java:6988)
at clojure.lang.Compiler.macroexpand(Compiler.java:7075)
...
at clojure.main$loading__6721__auto____8974.invoke(main.clj:11)
at clojure.main__init.load(Unknown Source)
at clojure.main__init.<clinit>(Unknown Source)
... 55 more
Caused by: java.lang.Exception: #object[clojure.spec.alpha$and_spec_impl$reify__1057 0x459f703f "clojure.spec.alpha$and_spec_impl$reify__1057@459f703f"] is not a fn, expected predicate fn
What could be a reason for this ?
We use these if it matters:
[expound "0.8.9"]
[orchestra "2021.01.01-1"]Sorry, not sure what that is
Can you make something reproducible to share?
I'll try to check if it isn't something specific to the dependencies / toolchain (which is likely)
Hello 👋 I'm defining a spec using https://clojure.org/guides/spec#_collections, and i quote:
Tuple - (s/tuple double? double? double?)
Designed for fixed size with known positional "fields"
Conforms to a vector of the values
What if, i have a fixed size collection but with unknown positional "fields", and the collection is NOT homogenous ?cat might work, if I understood correctly?
user=> (require '[clojure.spec.alpha :as spec])
nil
user=> (spec/def ::elements (spec/cat :int int? :string string?))
:user/elements
user=> (spec/valid? ::elements [1 "a" :b])
false
user=> (spec/valid? ::elements [1])
false
user=> (spec/valid? ::elements [1 "a"])
truewhat about ["a" 1] ?
That's what i meant with unknown positional fields
Oh, I see.
Yeah, this is basically what Alex said, but:
user=> (spec/def ::element
(spec/or :int int? :string string? :keyword keyword?))
:user/element
user=> (spec/def ::elements (spec/coll-of ::element :count 3))
:user/elements
user=> (spec/valid? ::elements [1 "a" :b])
true
user=> (spec/valid? ::elements [1])
false
user=> (spec/valid? ::elements [1 "a"])
falsewhat are you expecting to validate about this collection?
just it's size?
(s/coll-of any? :count 2)Not just the size, an example of the collection:
[{:identity "username"
:value "john"}
{:identity "age"
:value "30"}]
One might think this can be described with s/coll because it appears to be an homogenous collection, however, depending on the context of the application, i have different values on this collection...
The way i'm defining the two entries of the collection is as follows:
;; username
(s/def :username/identity
#{"username"})
(s/def :username/value
"PREDICATE_HERE")
(s/def :entry/username
(s/keys :req-un [:username/identity
:username/value]))
;; age
(s/def :age/identity
#{"age"})
(s/def :age/value
"PREDICATE_HERE")
(s/def :entry/age
(s/keys :req-un [:age/identity
:age/value]))
;; now i'm trying to define the collection using :entry/username and :entry/age
i've over simplified the keywords names because i'm obfuscating the real names
but the structure is this
(s/coll-of (s/or :user :entry/username :age :entry/age) :count 2)there are more options for the content, like wrapping that in s/nonconforming to avoid the s/or tag, or use s/multi-spec instead for open extension there, etc
This approach leads me with a collection having two entries of for example :entry/username as being valid I'm starting to think something using multi-spec, might work!
Will look into s/nonconforming docs also
the last is un-doc'ed but it basically conforms, then returns the original value