This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-11-15
Channels
- # aleph (5)
- # announcements (1)
- # architecture (35)
- # babashka (9)
- # beginners (87)
- # chlorine-clover (13)
- # cider (3)
- # cljdoc (12)
- # clojure (16)
- # clojure-australia (2)
- # clojure-dev (4)
- # clojure-europe (5)
- # clojuredesign-podcast (21)
- # clojurescript (19)
- # conjure (1)
- # core-async (1)
- # data-science (1)
- # emacs (44)
- # events (2)
- # helix (1)
- # leiningen (2)
- # malli (31)
- # pathom (3)
- # pedestal (31)
- # portal (3)
- # reagent (20)
- # reitit (5)
- # reveal (2)
- # rewrite-clj (18)
- # tools-deps (6)
- # xtdb (5)
wrote an issue for discussing about auto-updating with container schemas: https://github.com/metosin/malli/issues/304. Comments most welcome.
function schemas, comments welcome: https://github.com/metosin/malli/issues/125#issuecomment-727555388
I think you are ignoring the fact that different arities can have different return types/schemas
I think clojure.spec is also making this too difficult. In clj-kondo I chose to define the spec per arity
I guess there are lot of examples in the core where the different arities return different things?
confirmed: > - The output schema always goes on the fn name, not the arg vector. This means that all arities must share the same output schema.
well, clojure.core/map, filter, etc, is an example that have different return types for different arities. I kinda wish that the transducer arity was just a different version like clojure.core/mapping
but that ship has sailed. I often make mistakes with this
look at the spec that will result from this: https://github.com/borkdude/speculative/blob/master/src/speculative/core.cljc#L297-L302
I think this is not ergonomic at all. spec has to do backtracking etc, to match the right arity.
good point. what would be a good malli definition for this:
(defn fun
([x] x)
([x y] [x (* x x)]))
something like:
(m/=> fun {:arities {1 {:output int?
:input [:tuple int?]}
2 {:output [:tuple int? pos-int?]
:input [:tuple int? int?]}}})
Not sure if that's the best, but I optimized for matching speed, so clj-kondo can find the right arg types fast
as for defn syntax, maybe:
(defn fun
([x :- int?] :- int?
x)
([x :- int? y :- string?] :- [:tuple string? int?]
[y (* x x)]))
the extracted schemas could be in the compact/short :=>
format, which is always 1-arity:
(defn fun1 [x] (* x x))
;; short
(m/=> fun1 [:=> int? [:tuple pos-int?]])
(defn fun
([x] (fun x x))
([x y] [x (* x x)]))
;; short
(m/=> fun [:or
[:=> int? [:tuple int?]]
[:=> [:tuple int? pos-int?] [:tuple int?]]])
the long versions:
(defn fun1 [x] (* x x))
;; long
(m/=> fun1 {:arities {1 {:input int?
:output [:tuple pos-int?]}}})
(defn fun
([x] (fun x x))
([x y] [x (* x x)]))
;; long
(m/=> fun {:arities {1 {:output int?
:input [:tuple int?]}
2 {:output [:tuple int? pos-int?]
:input [:tuple int? int?]}}})
yes, those are needed for varags. we just had an internal tech-talk on friday, did a plan how to get the sequence schemas & schema parsing out. takes few days to make that good.
first demo of the function schemas will be with non-vargargs. enough to get feedback & start with the clj-kondo integration.
(require '[malli.schema :as ms])
(ms/defn ^:always-validate fun :- [:tuple int? pos-int?]
"returns a tuple of a number and it's value squared"
([x :- int?] :- any? ;; arity-level override
(fun x x))
([x :- int?, y :- int?] ;; uses the default return
[x (* x x)]))
(clojure.repl/doc fun)
; -------------------------
; demo/fun
; ([x] [x y])
;
; [:-> [:tuple int?] any?]
; [:-> [:tuple int? int?] [:tuple int? pos-int?]]
;
; returns a tuple of a number and it's value squared
full meta:
(ms/defn square :- pos-int?
[x :- int?]
(* x x))
(meta #'square)
;{:schema [:or [:-> [:tuple int?] pos-int?]],
; :ns #object[clojure.lang.Namespace 0x3c5f3ba8 "demo"],
; :name square,
; :file "/Users/tommi/projects/metosin/malli/src/malli/schema.cljc",
; :column 1,
; :raw-arglists ([x :- int?]),
; :line 64,
; :arglists ([x]),
; :doc "\n[:or\n [:-> [:tuple int?] pos-int?]]"}