This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-11-22
Channels
- # announcements (2)
- # babashka (64)
- # beginners (41)
- # calva (4)
- # cider (1)
- # clj-kondo (78)
- # cljdoc (31)
- # cljsrn (4)
- # clojars (2)
- # clojure (109)
- # clojure-germany (1)
- # clojure-italy (8)
- # clojure-nl (2)
- # clojure-spec (8)
- # clojure-uk (28)
- # clojurescript (61)
- # code-reviews (2)
- # cryogen (2)
- # cursive (23)
- # datomic (21)
- # duct (15)
- # fulcro (37)
- # graalvm (17)
- # graphql (3)
- # jackdaw (3)
- # joker (11)
- # lein-figwheel (4)
- # malli (42)
- # off-topic (97)
- # pathom (4)
- # pedestal (1)
- # portkey (3)
- # re-frame (7)
- # reagent (13)
- # reitit (2)
- # shadow-cljs (54)
- # spacemacs (1)
Not having a global registry has a downside though. Let’s say some library introduces a new Schema
protocol implementation. Then someone uses that in schemas in namespace X. With Spec
when you load the namespace you automatically gain all specs in there with all the required bits and pieces to make it all work. But with the way Malli is set up, if something is using a custom :datetime
schema, then all the users of that thing must invoke all the Malli functions with an opts map where :registry
is set to the default one with all the extensions added. If the calls to m/validate
and such are burried inside a third party library, then that library must provide a way for you to pass the registry to be used otherwise, you cannot use any new schema types except the ones defined in malli.core
Also I’d like to ask, what is the policy regarding non-serializable content in schemas. I see that some examples include opts map where you have keys like {:decode/string some-fn}
which isn’t really serializable
This is meant vis-a-vis developing own schema implementations… should I disallow non-serializable options?
@roklenarcic you can always define the library schemas as Vars, the first value in the Schema vector syntax can be an instance of IntoSchema
.
(def date-time (reify IntoSchema ...))
(m/validate date-time (java.time.DateTime.))
; => true
so I can also do `[datetime “format”]?
policy on non-serializable: up to the user. There is an issue about making an utility that checks if a schemas can be fully persisted or not. One can put that into project tests.
thanks that is very helpful
I mean any schema that specifies decode/encode implementation cannot be persisted?
(defprotocol IntoSchema
(-into-schema [this properties children opts] "creates a new schema instance"))
(require '[malli.core :as m])
(require '[malli.edn :as edn])
(-> [:and
[:map
[:x int?]
[:y int?]]
[:fn '(fn [{:keys [x y]}] (> x y))]]
(edn/write-string)
(doto prn) ; => "[:and [:map [:x int?] [:y int?]] [:fn (fn [{:keys [x y]}] (> x y))]]"
(edn/read-string)
(doto (-> (m/validate {:x 0, :y 1}) prn)) ; => false
(doto (-> (m/validate {:x 2, :y 1}) prn))) ; => true
;[:and
; [:map
; [:x int?]
; [:y int?]]
; [:fn (fn [{:keys [x y]}] (> x y))]]
ah.. but then the code processing the value has to call eval or something on it?
it uses sci
, a small interpreter. So it works on JVM, ClojureScript & GraalVM, no eval needed
sorry, I should be clearer. If my custom datetime schema has an option :formatter
which someone puts the value of DateTimeFormatter/ISO_INSTANT
if I quote this, I get a symbol
the latest version of sci supports Java reflection, if you bring this class in with the :classes
option.
but that won't work in CLJS of course
sure, but you cannot specify instant formatter by giving a string
specifying something like “yyyy-MM-dd” then telling it to format an Instant
object will fail
My current idea is to support everything
so if someone puts a formatter instance there, then I will use it
but then they lose serializability, but that’s on them
ok… this was very helpful
one thing there could be is to have a startup-time altering of a registry. via JVM options for example. It would be explicit, but still global.
plan is to pull schema defn
and fn
syntax helpers, can’t pass easily any custom options/registry there.
to support something like [:json-schema {:type "string"}]
schema would require some way to change the one registry. could just be the var reference (`[json/json-schema {:type "string"}]`), but could be a JVM property to bootstrap some extra schemas into the registry… not sure if thi is a good idea