This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-01-11
Channels
- # ai (1)
- # announcements (59)
- # aws (3)
- # babashka (16)
- # beginners (36)
- # calva (29)
- # cider (7)
- # clj-kondo (33)
- # clojure (77)
- # clojure-austin (1)
- # clojure-australia (4)
- # clojure-europe (16)
- # clojure-france (7)
- # clojure-nl (2)
- # clojure-spec (1)
- # clojure-sweden (8)
- # clojure-uk (4)
- # clojurescript (17)
- # cloverage (4)
- # conjure (2)
- # cursive (3)
- # datomic (22)
- # emacs (16)
- # fulcro (10)
- # graphql (3)
- # helix (13)
- # jobs (1)
- # kaocha (1)
- # lsp (7)
- # malli (1)
- # nextjournal (1)
- # off-topic (32)
- # pedestal (8)
- # polylith (5)
- # reitit (4)
- # reveal (1)
- # shadow-cljs (67)
- # spacemacs (7)
- # tools-deps (6)
- # xtdb (4)
Initial (early) release of https://github.com/exoscale/lingo - a lib that extends spec explain-data and helps with formatting error messages from these extensions
When I try to load it with bb I get:
$ bb -cp $(clojure -Spath -Sdeps '{:deps {org.babashka/spec.alpha {:git/url "" :git/sha "1a841c4cc1d4f6dab7505a98ed2d532dd9d56b78"}}}') -e "(require '[exoscale.lin
go])"
----- Error --------------------------------------------------------------------
Type: clojure.lang.ExceptionInfo
Message: Cyclic load dependency: [ exoscale.lingo ]->[ exoscale.lingo ]
Why does the namespace load itself?if I remove that it works:
$ bb -cp ... -e "(require '[exoscale.lingo :as l] '[clojure.spec.alpha :as s]) (s/def ::int int?) (l/explain ::int :foo)"
1 error found
:foo is an invalid :user/int - should be an Integer
yeah, it's intentionally no-dependency, runs in bb and I guess in cljs without too much trouble
I didn't mention expound directly but I do mention that lingo is more data centric, expound works on explain
and explain-str
another thing, expound does not try to give a way to interpret predicates from the user side. Every custom message has to be applied on a registered spec and if/when that spec rejects a value it will just return that message, there's no predicate context
I wanted to have this added to expound but the author didn't like the idea. hence lingo
no clue, I am not even sure the current code runs in cljs (it should but I didn't test it). It's a very early release, in many ways, there are a lot of perf improvements that are possible left & right as well, the current impl. for pred parsing is quite naive for instance.
keeping js-bundle size small is not easy, defs & multimethods can’t be DCEd and anything they use will be dragged in too, e.g. regex-schemas etc. Not a concern in most apps, but still a concern.
at some point, want an expound-grade prettier printer for malli too, current just Fipps out with colors, not marking errors / hiding details on large errors. Good to see more development in this space.
yeah, arguably that should be mostly for dev time usage in cljs, or cases where you just don't care.
I thought about using fipp, but for now I like being dependency free. But I also know pprint is crazy slow, so we'll see
it would be nice to have spec/select spec/schema as a library until spec2 settles (if ever), I suppose that could mitigate some of that
there are some tricks to remain dependency free + optional namespaces which, when loaded, register some "plugin" which, if available, can be used for certain features.
depending on what the lib does and its size, just copying the code is often better imho
another option is to provide the dependency function just an as argument option and you can program against some protocol
I do a similar plugin thing in #nbb where cljs.pprint
is compiled into a different module than the rest of the stuff. So when you don't use cljs.pprint
you don't load that 200kb of JS all the time. Everything is advanced compiled.
I think I might just throw in a try requiring-resolve .... around fipp fn and be done with it
and it's not so good with graalvm native image either. This is a better approach: https://github.com/seancorfield/honeysql/pull/378/commits/e331ba0a0e44bec5da7e094f0c699181dd8d6cde
I.e. do the resolving on the top level. For CLJS you will have to require people to load a namespace and in that namespace you can register whatever function you need. If that functions isn't available (due to the namespace not having loaded) then you assume the user doesn't want to use that dep.
Here is another solution that works in both CLJ and CLJS: https://github.com/borkdude/dynaload
but I prefer the namespace solution, that simplifies things drastically and also works in babashka even.
(ns core-ns)
(def optional-function (volatile! nil))
(defn api-fn []
(if-let [f @optional-function ...] ...))
(ns optional-ns (:require [core-ns] [pprint]))
(vreset! core-ns/optional-function pprint/pprint)
just getting the humanized error messages from specs is actually useful in normal CLJS apps, e.g. with form validation. Seen libs like https://github.com/alexanderkiel/phrase used there.
I personally prefer to stay close/extend explain-data output, it's easier to port to it and also staying at the explain-data.problems[] level makes it easier to use in various contexts (web-form rows, cli, backend etc). But the more the merrier. All these libs are not a lot of code.
yes, the ^ stuff. did a placeholder repo 3y ago for just pretty error printing lib, but no time, have copy-pasted the same fipp-stuff between libs (reitit, malli). Modular, but incomplete (and works with expound) https://github.com/metosin/virhe
that one you mean? https://github.com/metosin/malli/blob/master/src/malli/dev/virhe.cljc
yes, that, here’s it in action: https://twitter.com/ikitommi/status/1480215765143932931