This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-10-21
Channels
- # 100-days-of-code (5)
- # announcements (6)
- # beginners (92)
- # cider (39)
- # cljdoc (35)
- # cljsrn (1)
- # clojure (187)
- # clojure-sanfrancisco (2)
- # clojure-spec (26)
- # clojure-sweden (2)
- # clojure-uk (1)
- # clojurescript (27)
- # cursive (19)
- # datascript (3)
- # datomic (19)
- # defnpodcast (1)
- # emacs (11)
- # fulcro (71)
- # incanter (1)
- # lein-figwheel (4)
- # lumo (10)
- # off-topic (19)
- # planck (5)
- # reagent (49)
- # reitit (2)
- # shadow-cljs (25)
- # spacemacs (1)
- # sql (1)
- # unrepl (4)
- # yada (4)
@gfredericks yikes, in RC1 as well. maybe a bug? EDIT: it was valid in 1.8.0 as well
I hadn't considered that; I'm not sure
That’s the compiler hook under fn
Certainly not the preferred entry point
We’re writing some specs for clojure.core functions. I notice things can get a bit slower on big codebases with instrumenting all core functions. Is there a way to let spec know to not check when a function is called from clojure itself? so only external calls. I hoped direct linking would solve this, but I don’t think it is now
I would not expect calls between core functions to get checked
I would be very surprised, if you are compiling Clojure with the default option of direct linking enabled, that calls between Clojure functions within Clojure are being checked, if you are using instrument. If you believe you are seeing otherwise, I would love to see an example of that.
instrument works by re-def'ing Vars. direct linking means that the current value of the Var is ignored, instead being embedded in the calling function at compile time.
FYI, there is one function in clojure.data/diff's call tree that calls a function in clojure.set (I think clojure.set/difference) with non-set arguments. I have tried writing a spec for clojure.set/difference that causes errors if you call it with anything other than a set, and the only way I could make the error be caught is to disable direct linking when compiling Clojure.
Some details here: https://dev.clojure.org/jira/browse/CLJ-2287
And if you want to try compiling Clojure with direct linking disabled, and thus likely see instrumented runs get even slower, there are some instructions near the bottom of this page, with the heading "Building Clojure without direct linking": https://dev.clojure.org/display/community/Developing+Patches
Thanks. Then my understanding of direct linking is correct and I need to do more research to see how to speed up things.
is there a shortcut for a Spec s/or
which only contain spec keywords and want to tag them with the same keyword? i.e. (s/or ::foo ::foo ::bar ::bar ...)
Not in spec, no
Thanks @alexmiller. Other question: I read that specs are discouraged to be used as runtime because they can be slow. With that in mind, would it still make sense to use specs at runtime to branch on code based on the shape of data. i.e. check if data conforms to some spec to know if it’s of some “kind”, branch on that, etc
Only you can answer whether it’s fast enough for you
It’s definitely fast enough for me; I’m just wondering if it goes against some deeper philosophy that I’m missing and could come bite me in the back down the line (beyond performance)
I’ve another question on Clojure spec for whomever is around: how do you avoid circular namespace dependencies? It seems preferable to put every spec in a namespace mapping to the namespace part of the spec keyword to be able to then require and alias that namespace wherever the spec is used. i.e.
(ns my-app.schema
(:require [my-app.schema.person :as person]))
(s/def ::person (s/keys :req [::person/first-name]))
(ns my-app.schema.person)
(s/def ::first-name string?)
The simplest example of the issue I’m running into is, then, what if I want to add a friends
attribute on a person. i.e.
(ns my-app.schema.person
(:require [my-app.schema :as schema])) ; oops, circular dependency!
(s/def ::first-name string?)
(s/def ::friends (s/coll-of ::schema/person))
The only solution I can think of it to still create the my-app.schema.person
namespace but to move the attribute specs for person
in the my-app.schema
namespace, like this:
(ns my-app.schema)
(s/def :my-app.schema.person (s/keys :req [:my-app.schema.person/first-name :my-app.schema.person/friends]))
(s/def :my-app.schema.person/first-name string?)
(s/def :my-app.schema.person/friends (s/coll-of :my-app.schema/person))
actually I could still use the namespace alias here, but I would have to define the attribute specs in my-app.schema
namespace and essentially just create an almost blank file for the my-app.schema.person
namespace