Fork me on GitHub
#clojure-spec
<
2021-03-11
>
mokr14:03:08

Quick question before I resort to rewrite my code: Is there something inherently wrong with trying to keep code DRY by extracting values directly from a spec like this?

(ns my.specs  ;; cljc-file
  (:require [clojure.spec.alpha :as s]))

(s/def :select/legal-values #{1 2 3 4})


(ns my.ui    ;; cljs-file
  (:require [clojure.spec.alpha :as s]
            [my.specs]))

(def dropdown-config [{:id      :select-legal-values
                        :tooltip "Select your value"
                        :values  (s/form :select/legal-values)},,,])
This only illustrates the part where I retrieve values from this spec. Data verification is elsewhere. What makes me ask is that I’ve had this working in my Luminus+Shadow-cljs+re-frame app, but as soon as I upgrade shadow-cljs, my project won’t load in the browser. From e.g. “ReferenceError: spec is not defined” I get the impression that the spec might not be ready yet. I don’t think it is shadow-cljs that is to blame as I encountered the same issue when upgrading yesterday as well, but after cleaning and trying a few times it suddenly started working. Maybe I got lucky with a race condition or something… Anyone?

Alex Miller (Clojure team)14:03:45

Yeah, this won’t work in spec

Alex Miller (Clojure team)14:03:18

Oh wait, I’m misreading

Alex Miller (Clojure team)14:03:49

Might be a bug in spec emitting the wrong namespace on the spec form? We have fixed a few things like that

Alex Miller (Clojure team)14:03:11

I’m keying off of “spec” there - not sure if that’s a hard coded word or a ns from data

mokr15:03:26

Based on the error I don’t get the impression that there is a wrong namespace issue, but it’s not that informative really. It’s often a bit hard to reduce the actual code down to a suitable snippet that captures to issue. In this case I would say the gist is: Can a spec from a required namespace be used in a normal def that calls s/form to extract the “value” from that spec. Is the spec ready for value extraction at the time of def evaluation? Even though I had this working I’ll just rewrite it as it seems a bit brittle. For instance IIRC I had to put the set directly inside the s/def, as s/form did not work if the spec used a var containing the set like this: (def my-set #{1 2 3} (s/def :foo/bar my-set) (def boom (s/form :foo/bar) I guess I might be abusing spec a bit, or relying on functionality that is not suitable for that purpose.

mokr15:03:30

A quick rewrite where both the spec and my config refers to the same vars/defs resolved the issue. Still DRY, a few more lines of code, less “clever”, but maybe easier to understand and less brittle. 🙂

Alex Miller (Clojure team)15:03:29

some of the fiddliness of this is improved in spec 2

mokr17:03:42

Sounds great. I was holding back on spec for a long time waiting for spec 2 😉 But, I understand and appreciate the attention to detail that goes into the process.

vlaaad19:03:27

Anyone knows if there is a library to convert json schema to spec definitions?

robertfw20:03:51

@vlaaad I've looked for this previously (and for the reverse transformation) but came up empty. luposlip/json-schema is the library I used for validation, and it seems to have sprouted schema inference since I last looked through its docs, that may not be useful in its exact form but could have some useful code within

🙏 3