This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-13
Channels
- # announcements (2)
- # aws (4)
- # babashka (14)
- # beginners (186)
- # cljdoc (2)
- # cljsrn (7)
- # clojure (56)
- # clojure-austin (1)
- # clojure-australia (2)
- # clojure-europe (46)
- # clojure-france (5)
- # clojure-nl (16)
- # clojure-norway (7)
- # clojure-spec (76)
- # clojure-sweden (15)
- # clojure-uk (13)
- # clojurescript (60)
- # code-reviews (2)
- # conjure (8)
- # datascript (1)
- # datomic (4)
- # depstar (10)
- # emacs (9)
- # events (4)
- # exercism (1)
- # fulcro (36)
- # graalvm (8)
- # introduce-yourself (3)
- # jobs-discuss (2)
- # kaocha (14)
- # lsp (1)
- # minecraft (8)
- # new-channels (1)
- # off-topic (3)
- # pathom (6)
- # polylith (9)
- # re-frame (48)
- # shadow-cljs (5)
- # specter (26)
- # tools-deps (19)
- # vim (2)
- # vscode (1)
Question regarding conventions and style. For some map spec ::foo
having a few variants, how would you name the specs?
Should keys be named :foo/key
?
For the variants I thought of just using or
(s/def ::foo (s/or ,,,))
To name the variants I can think of ::foo.a
::foo-a
:foo.type/a
Recommendations and ideas very welcome
There’s not enough detail here for me to really answer that - how does a variant vary?
Generally though, I would urge you first to focus on the attributes not on the maps. Name the attributes well and fully describe the set of values that attribute can cover. If you then need multiple sets of attributes, kind of depends how they relate
Right, then to be specific, consider https://clojure.github.io/tools.analyzer.jvm/spec/quickref.html#binding, which I want to spec out unambiguously
if you don't mind my asking, are you building something off t.ana? Would be curious about it (as someone who maintains two derived tools namely Eastwood and refactor-nrepl)
I am exploring the possibilities. Background, clj-fast, one of my first projects, is just a bunch of heuristic inlinings and optimizations of core clojure. I can keep on working at it for every conceivable use case, but I became interested in solving the general problem. I want to implement some intermediate compiler passes - constant inlining, beta reductions, copy and constant propagation. If I get this, I can write a compiler from clojure to clojure that cuts down on the biggest performance hits in the language, iteration and dynamism
This ia clearly not for for development time, but for final artifacts it could be huge
this is probably a good use case for s/multi-spec
switching on :op
A very rough spec would be:
(s/def ::binding
(s/keys
:req-un
[:binding/op :binding/form :binding/name :binding/local :binding/arg-id
:binding/variadic? :binding/init :binding/atom :binding/children]))
you could do a second level of s/multi-spec on :local
it's designed for open extension, and it doesn't tag the conformed value
okay, and how would you name the specs you select between? would you even name them?
I think I would name them, and I would name them something related to the ast node type
in general, I find relying on s/merge and s/multi-spec to "build up" evolves better than trying to s/or
I have no sense of style or habits with spec so I thought it would be better to ask instead of produce something horrendous 🙂
how would you name the specs you dispatch to? ::arg-binding
, ::binding.arg
, :binding.type/arg
?
.'s should generally be used only in qualifiers, so I'd rule out the middle one
since these are ast nodes I would probably be trying to include either "ast" and/or "node" in the name of each one
whether you put that in the qualifier or in the name is a matter of taste
In that case, I can even start from naming it something like :node/binding
then the multi case could be :node/binding.arg
? :node/arg.binding
?
Like I said previously, I still have no sense of taste when it comes to specs, so I prefer to ask someone with experience
"node" is not sufficiently unique - you should treat this as a global naming space
:clojure.tools.analyzer.node/binding
this is admittedly a bit painful to use without an alias, and aliases to namespaces that don't exist don't work, so you either need to do the create-ns
/ alias
dodge or use a real namespace
(this is going to get better in 1.11 with lightweight alias support)
yes, that would work
although .'s in names are bad
the problem is they have meaning understood in the compiler, which is: class name for symbols
the https://clojure.org/reference/reader#_literals spec actually says keywords "cannot contain '.' in the name part, or name classes"
so I'd either use node-binding
or bite the bullet on moving it into the qualifier
well, you'd hardly be alone :)
and like I said, better solution for this is coming
that is important here if it's part of analyzer.jvm
It would be a tall order for it to be integrated into analyzer.jvm but having it as a companion library would be nice
While we're here, I'll also use this opportunity to ask regarding namespace and artifact naming convention (and copyright)
A "correct" name for the spec's ns would probably be clojure.tools.analyzer.jvm.spec
, but can I distribute a library whose root namespace is clojure
? Even if the license allows it, which I'm not sure it does, it feels rude
I assumed you were spec'ing this to include with tools.analyzer.jvm, where it would be fine
seems like it would be the greatest utility to the most people as either part of that library or as a separate contrib lib
currently tools.analyzer still supports pretty old clojure versions, older than spec
I think so
I'd have to ask Rich but I don't think he would object to that
we've taken the approach of appending ".specs" for stuff like this, so it would presumably be tools.analyzer.jvm.specs
If I'm doing it with the intent of it becoming a contrib library I should probably start with a tools.analyzer.specs then merge the jvm stuff on top of it
I mean, there isn't really anything but .jvm, so I think it would be fine to include it all in one
What is the recommend route for evaluating the result of a clojure.spec.gen.alpha/check result summary set with the test framework (runners, assertions, and family) of clojure.test? The test.check library appears to have defspec, but it's unclear if it's a good fit to glue to spec/fdef generative, as examples seem to favor it's own clojure.test.check.generators in the guide examples.
I would recommend not doing that and separating your generative tests from your unit tests
could you elaborate on this?
unit tests are generally fast and you run them a lot. generative tests are usually slow and you run them less often, they also often require most setup (for things like instrumentation, mocking etc).
i have something like the following:
(deftest specd-functions-pass-check
(stest/instrument)
(macros/filtered-check `a-namespace/a-function (num-tests 1))
(macros/filtered-check `b-namespace/a-function (num-tests 3))
(defmacro filtered-check [sym opts]
`(let [fltr# (or (.get (js/URLSearchParams. js/window.location.search) "filter") "")
check# (fn [res#]
(cljs.test/is (= true (-> res# :clojure.spec.test.check/ret :result))
(goog.string/format "spec check failure:\r\n%s"
(with-out-str (cljs.pprint/pprint res#)))))]
(when (or (= fltr# "all")
(clojure.string/includes? (clojure.string/join "/" [(namespace ~sym) (name ~sym)]) fltr#))
(let [check-res# (clojure.spec.test.alpha/check ~sym ~opts)]
(clojure.spec.test.alpha/summarize-results check-res#)
(if (nil? check-res#)
(cljs.test/is false "stest/check result was nil. did you pass it any valid symbols?")
(doall (map check# check-res#)))))))
some people have written code to wrap spec check tests into clojure.test, but I don't have that at hand