Why not spec 2? Though not finished, I guess it bears completion (just the last 10% that use 90% of the time :rolling_on_the_floor_laughing:)...
I’ve got a spec(ish) design question that I’ve been thinking about for a while. I finally decided to throw it in a gist: https://gist.github.com/telekid/0f276bfa3b3f0d395a7a71158adbb35d I’m curious to know how other people approach this problem?
@jake142 If EDIT: Gist has been updated. Disregard! :)::animals/penguins
is defined as a count (perhaps s/def ::penguins nat-int?
) then I do not see a problem with reusing it.
Oh, I just realized that I made a typo
🤦
one moment
L20 how has ::animals/lions
I see. Thanks for the clarification.
Sorry for the confusion!
In a given (ns models.geography.continent)
, I tend to solve this with:
(spec/def :models.geography.continent.penguins/animals ...)
(spec/def :models.geography.continent.lions/animals ...)
i.e. I don't use ::
syntax for these cases, and I don't create additional Clojure namespaces (files).
I call it the "synthetic ns pattern"
It's a bit verbose, and losing the 1:1 mapping between cljs namespaces and spec namespaces isn't ideal either.
But it's fairly occasional so I've been happy to use these for a couple yearsbtw, not sure if this solution is already described in your gist. sometimes I'm impatient 🙃
yeah, I like that
I’ve experimented with that a bit in a few places (but I forgot about it when I was writing the gist - thanks for bringing it up)
✌️! I realised, a more accurate nickname would be "synthetic sub-ns pattern". so, while it's not a 1:1 mapping, one is still reasonably close to that ideal
funnily enough, I’ve been using the same name: https://ask.clojure.org/index.php/2817/lighter-weight-aliasing-for-keywords?show=8918#a8918
Why were multi-specs implemented using multi-methods? I have never found the dynamism of multimethods useful in defining multi-specs. In fact, I think I'd prefer all of the multi-spec types to be declared statically.
@kenny so that they're open to extension
in fact I can't think of anything in clojure that's closed
Right. At least interally, I've never found that useful. All type->keys are declared upfront. Multimethods make it hard to determine the input data.
> All type->keys are declared upfront. ?
Dispatch functions
I'm sorry I still don't understand
For a particular entity, I know it has types A, B, C. It can never and should never be extended except directly in the definition.
All the variants of an entity are known upfront.
ok that's your use case
You might not be the one defining the multispecs, the users of your library may be.
^^
https://github.com/clojure/tools.deps.alpha/blob/master/src/main/clojure/clojure/tools/deps/alpha/extensions.clj look at t.d.a.extensions ^
and all the extensions in the extensions folder
Oh right, I see the use for libs. This internal use case is much different. Perhaps some sort of new macro is what we need:
(multi-spec2 {:type1 (s/keys :opt [])
:type2 (s/keys :opt [])})
wouldn't it be amazing if you can write that macro today?
😄
For those interested...
(defmacro closed-multi-spec
[name dispatch-key dispatch->spec]
(let [defmethods (map (fn [[dispatch spec-form]]
`(defmethod ~name ~dispatch
[~'_]
~spec-form))
dispatch->spec)]
`(do
(defmulti ~name ~dispatch-key)
~@defmethods
(s/multi-spec ~name ~dispatch-key))))
Don't know if this is where it'll land but it's a start.