What is the reason spec chose a custom deftype LazyVar
over the built-in delay
in its implementation?
for which?
I'm trying to come up with something that would work in Clojure for this case:
(def input (LazyVar. (fn [] (line-seq (java.io.BufferedReader. (java.io.StringReader. "1\n2\n3\n")))) nil))
such that you don't have to write @input
but just input
so the first time it's derefed by Clojure it starts its realization. Just a naked line-seq
doesn't work, since that starts reading once it's def-ed.@alexmiller in the gen namespace
I think in Clojure I would have to write a subclass of clojure.lang.Var
to make that work.
sorry, I don't actually see what you're talking about
And maybe I should just go with @input
and not do any magic... This lead to the question: why is gen/LazyVar not just a delay but a custom data structure.
Ah right.. sorry, the LazyVar
is something in CLJS, not CLJ. 🤦
I'll ask over there in #clojurescript
ah
I am confused about the syntax for (or)
and (and)
in s/keys
. My understanding of it was that anything that is passed to or
could be correct, and anything that passed into and
has to be present. Did I misunderstand? My intuition does not work for the following example:
(s/def :foo/foo #{:foo})
(s/def :bar/foo #{:bar})
(s/def ::an-int int?)
(s/def ::baz (s/keys :req-un [(or :foo/foo
(and :bar/foo
::an-int))]))
(s/valid? ::baz {:foo :foo})
;; => false
(s/valid? ::baz {:foo :bar})
;; => true
ok it looks like when you have the same naked keyword (not sure of the right terminology, keyword without the NS) then it will always take the last one defined. That's a huge bummer, since I wanted to be able to spec something like "In this case, do this, in this other case, do this + another piece of data", and the way that was being specced before was by storing everything as a tuple
@socksy can't you use s/or
for either case?
more verbose
yes I think it might be possible. I'll go hit my head on it
i am thinking my own predicate will probably be the most readable but let's see
maybe spec2 has a better answer to this... although I'm not sure if s/select
can solve this case
Another option would be a multi-spec I think?
(s/def ::baz (s/or :foo-case (s/keys :req-un [:foo/foo])
:bar-case (s/keys :req-un [:bar/foo ::an-int])))
is not too bad actuallyNow I wonder how you would use this in spec2. I think you would define ::baz
as the thing with all possible keys and then use s/select
for either case?
(s/def ::baz (s/schema [:foo/foo :bar/foo ::an-int]))
(s/def ::foo-case (s/select [:foo/foo]))
(s/def ::boo-case (s/select [:bar/foo ::an-int]))
Something like this?