malli

https://github.com/metosin/malli :malli:
mike_ananev 2021-03-07T12:02:31.207200Z

@ikitommi what is the difference between :title and :description in spec? I want to describe my config file using malli and guessing what should I use to describe every field in the config map.

mike_ananev 2021-03-07T12:09:07.207600Z

(def http-server-host [:and {:title "http server host"} ne-string])
;; or
(def http-server-host [:and {:description "http server host"} ne-string])

ikitommi 2021-03-07T12:24:53.212Z

@mike1452 those are pulled from JSON Schema convention: > The `title` and `description` keywords must be strings. A “title” will preferably be short, whereas a “description” will provide a more lengthy explanation about the purpose of the data described by the schema. I would use :description there. In OpenAPI & Swagger, title is pulled as the Schema name, e.g.

[:map {:title "User", :description "Describes User of the System"} 
 [:name {:description "Name of the User"} :string] 
 [:age {:description "Age, must be >= 18} [:int {:min 18}]]]

mike_ananev 2021-03-07T12:28:37.213Z

Thank you.

ikitommi 2021-03-07T12:43:50.213800Z

pulling the return types too:

(-var-schema #'str)
;[:function
; [:=> :catn :string]
; [:=> [:catn [x :any]] :string]
; [:=> [:catn [x :any] [ys [:+ :any]]] :string]]

(-var-schema #'distinct?)
;[:function
; [:=> [:catn [x :any]] :boolean]
; [:=> [:catn [x :any] [y :any]] :boolean]
; [:=> [:catn [x :any] [y :any] [more [:+ :any]]] :boolean]]

borkdude 2021-03-07T12:53:11.214Z

Clever:

user=> (meta (second (:arglists (meta #'str))))
{:tag java.lang.String}

ikitommi 2021-03-07T13:01:25.215700Z

Noticed too that the hand-written arglists seem to have weird syntax.

joshkh 2021-03-07T16:06:08.218800Z

loving malli so far! what's the idiomatic way of "extending" a schema? for example let's say i have a Person map with the basic attributes first-name and last-name, and then a ProfessionalPerson that is a Person with an additional required profession attribute. would i create a ProfessionalPerson definition that contains only just [:map [:profession string]] and then mu/merge it on top of the Person map [:map [:first-name string?][:last-name-string?]]?

borkdude 2021-03-07T16:12:58.219200Z

@joshkh Or mu/assoc

joshkh 2021-03-07T16:17:53.220600Z

cool, thanks borkdude. on a side note it's too bad that mu/assoc doesn't allow for & kvs like clojure.core/assoc 😄

borkdude 2021-03-07T16:19:05.221100Z

;)

juhoteperi 2021-03-07T16:22:10.222800Z

Might be possible to implement. The options parameter makes it a bit inconvenient though, we could check that if odd number of params, last param is the options, and for even number of params, no options, just kv pairs. Not sure if worth the complexity.

juhoteperi 2021-03-07T16:23:25.223200Z

malli.util/dissoc also takes just one key.

borkdude 2021-03-07T16:23:55.223600Z

if you need more than one k/v, you can just use mu/merge :)

borkdude 2021-03-07T16:24:26.224400Z

or repeat mu/assoc

joshkh 2021-03-07T16:24:50.225200Z

yeah, merge is fine by me. i just thought it was funny that my first instinct was to treat it like the assoc i know.

juhoteperi 2021-03-07T16:26:42.227400Z

Yeah. Though I think it will be worth to mention the differences to clojure.core functions in the docstrings, now the util fns mention just "like clojure.core/x" but then many of them take a bit different parameters.

joshkh 2021-03-07T16:31:55.229700Z

perhaps. admittedly i just tried it out while completely ignoring the very clear docstring params in my editor. you can lead a horse to water but you can't make it drink 😉

borkdude 2021-03-07T16:33:05.230200Z

It's awesome that you can do this with malli btw.

👍 1
joshkh 2021-03-07T16:37:58.230600Z

absolutely. and the deep merging is really handy, too

ikitommi 2021-03-07T17:34:54.234600Z

there are at least two options to resolve the malli.util varargs issue: 1. make all utilities only work with Schema instances, e.g. no auto-coercion from schema AST => only place to pass the options would be the m/schema -> simpler, more boilerplate, 2. make a custom type/record/protocol for the options, could be the first argument in all functions, “the schema context” - easy to distinguish it from other args

schmee 2021-03-07T19:47:09.235300Z

do I need to have sci for a spec like this?

[:map {:gen/fmap 'map->Point}
       [:lat [:double {:min -180.0 :max 180}]] 
       [:long [:double {:min -180.0 :max 180}]]]]

schmee 2021-03-07T19:53:17.235500Z

seems like it according to the tests: https://github.com/metosin/malli/blob/master/test/malli/generator_test.cljc#L94-L105

schmee 2021-03-07T19:53:45.236200Z

can you configure malli to use the clojure compiler for eval instead of sci?

schmee 2021-03-07T20:06:32.237200Z

I can’t get this to work with or without sci, can you not use namespace-qualified functions as arguments to :gen/fmap? :thinking_face:

ikitommi 2021-03-07T20:07:00.237700Z

yes, just don't quote and it works

ikitommi 2021-03-07T20:07:31.238700Z

(but, can't be deserialized if it's a fn value)

ikitommi 2021-03-07T20:08:42.240800Z

If you wan't eval, PR welcome. Could be option :malli.core/evaluator a, there could be a -eval-evaualuator in malli.core

ikitommi 2021-03-07T20:09:02.240900Z

relevant code: https://github.com/metosin/malli/blob/master/src/malli/core.cljc#L1739-L1741

👍 1
schmee 2021-03-07T20:12:57.242200Z

ahh, I was fooled by the output of my REPL, it printed the record as a plain map (and skipped the record type)!

schmee 2021-03-07T20:13:03.242500Z

then all is well, thanks for the help 🙂