This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-01-03
Channels
- # aleph (2)
- # announcements (6)
- # babashka (6)
- # beginners (106)
- # biff (8)
- # clara (24)
- # clj-kondo (10)
- # clj-otel (4)
- # cljdoc (2)
- # clojure (54)
- # clojure-conj (3)
- # clojure-europe (85)
- # clojure-norway (54)
- # clojure-uk (3)
- # clojurescript (27)
- # community-development (2)
- # data-science (1)
- # datahike (2)
- # datomic (11)
- # deps-new (67)
- # emacs (4)
- # graalvm (15)
- # hyperfiddle (11)
- # introduce-yourself (1)
- # lsp (6)
- # malli (30)
- # midje (4)
- # nrepl (13)
- # off-topic (86)
- # polylith (7)
- # releases (2)
- # sql (10)
Enhanced Development Mode merged in master (https://github.com/metosin/malli/pull/980). Guide here: https://github.com/metosin/malli?tab=readme-ov-file#pretty-errors
How do I create a schema for a vector of two integers >= 0, where [val max], the second integer 'max' should always be >= val. Example [0 0], [1 3], [5 10], [0 9]
I don't know how to do that without the dreaded :fn schema, unless you make them distinct ranges, e.g.:
[:tuple [:int {:min 0 :max 10}] [:int {:min 10 :max 20}]]
I am having this val-max vector in my videogame for damage [min-max] or hitpoints [current-max].
Maybe...? The only other thing I can think of is:
[:and [:tuple [:int {:min 0}] [:int {:min 0}]] [:fn (fn [[a b]] (<= a b))]]
But I gather :fn
schemas are discouraged, and best avoided if you can find a different solution.
It would be nice to have a type :val-max because I am using the same schema at hp/mana/damage
I haven't used Malli that much either, and can't really answer why they're discouraged. But I've seen that mentioned a few times in this channel.
Here's another example that is an actual vector of two elements:
[:and [:vector {:min 2 :max 2} [:int {:min 0}]] [:fn (fn [[a b]] (<= a b))]]
[:and ... [:fn ...]]
is "bad" because it's opaque. you get a message that it failed because of the function and nothing else
but if you add in an :error/fn
metadata, you can customize
[:fn {:error/fn (fn [{[a b] :value} _]
(when (< b a)
(format "Expected a (%d) to be smaller than b (%d)" a b)))}
(fn [[a b]] (<= a b))]
This is giving me a NullponterException when 'explain' ing. Is it not possible to give a nicer error message?
(def test-schema (m/schema pos?))
(m/explain test-schema nil)
you could use fnil
to avoid this issue
i believe the issue comes from https://github.com/metosin/malli/blob/6f454709fd240913faa5eef9a56b6ef740547f77/src/malli/core.cljc#L679where there's no try/catch, just calling the given validator function (`pos?`) on the input (`nil`), which will result in a thrown exception in both clojure and malli
many of the Clojure built-its fail with nil
. We could wrap ’em all with m/-safe-pred
Wrote a quick doc on different ways to manage & reuse schemas: https://github.com/metosin/malli/blob/master/docs/reusable-schemas.md. And yes, I prefer the Plumatic-style Var-definitions of Schema over using spec-style global registry. But, both are and will be supported. comments and other viewpoints to comparison matrix welcome!
For Vars, could add mx/defschema
that adds the Var symbol and namespace into the schema as schema properties. Either separate or combined into a new key. so:
(ns my-domain
(:require [malli.experimental :as mx]))
(mx/defschemas Size [:enum "S" "M" "L"])
.. would create a Schema:
;; 1) separately, like Plumatic has (as metadata)
[:enum {:name 'Size
:namespace 'my.domain} "S" "M" "L"]
;; 2) concatenated into name, property name??
[:enum {:id 'my.domain/Size} "S" "M" "L"]
[:enum {:ref 'my.domain/Size} "S" "M" "L"]
[:enum {:name 'my.domain/Size} "S" "M" "L"]
The problem with plumatic style is that things like json schema generation dereference it recursively instead of lifting it to definitions because schemas are passed by value
I think if we just add the full Var symbol into properties, we can see “this is a my-domain.User
instead of an value.
so, referencing to a schema would inline the value, but with data saying what was it all about.
but, we need some way to reference to support recursion, maybe just use Vars like Schema does?