Hi all, somebody pointed me to Malli (thx @borkdude @hobosarefriends) because of the situation with spec being alpha and spec2 on the horizon. But then I noticed in the Malli readme that it says: “Pre-alpha”, which scares me a bit. Can somebody clarify the situation and whether or not this is a good time to start using Malli? Our situation by the way is that we have a big existing codebase without any sort of spec/schema, so in that respect we’re starting from scratch.
@ikitommi A small heads up I have generated a Malli spec that can validate all of our cfn templates (around 30, pretty big and complete). I’ll try to publish it soon and point to some pitfalls. One thing that is hard to debug are (deeply nested) recursive schemas. Without the use of [:ref …]
it will give a stackoverflow error without a good pointer. And I had to do a trick in the :multi
dispatch to prevent :invalid-type
errors and to stay compatible with spell-check. All in all it works pretty well! Thanks
All the solutions are officially still alpha. Trying any of them is a good learning experience. If you don’t have specific requirements, I would suggest to start with clojure.spec (1) as it has the most examples and documentation. I think Malli is modelled like spec(2) so any learnings with clojure.spec will be applicable later in malli
Although @ikitommi mentioned that the goal of the current Clojurists Together funding is to make a stable (non-alpha) release?
With spec it remains to be seen. It's been in alpha for over 4 years.
@stefan.van.den.oord Just checked that last bullet on “last things before initial stable release” yesterday. will clean up corners and will ship the alpha, most likely next week.
the public api has been mostly stable since june, there has been small changes in the advanced user / extender api, and most likely will be after the first release.
@ikitommi (Note my remarks on borkdude/dynaload. I'm currently solving a problem with GraalVM. Using resolve at runtime bloats the binary with +20MB. But it does work.)
1.0.0 might be soon too, after feedback from the community.
@borkdude sorry, read you message, but didn’t have time to answer. There is no GraalVM tests atm, should be.
I will publish dynaload 0.2.0 or so that will have breaking changes to fix this problem, but I'll notify you
and possibly make a PR
that would be great! GraalVM support is top priority, don’t want bloated binaries 🙂
when writing libraries, the goals matter a lot. few years ago, didn’t know much about perf. can’t add that later. now, the cljs bundle size, learned how to handle that. Next: GraalVM as a target.
yeah. I have a dynaload-graal-friendly
branch, with script/graal-test
.
currently this code still bloats:
#?(:clj (defn resolve* [sym]
;; TODO: this adds + 20MB to the GraalVM binary
#_(let [ns (symbol (namespace sym))
v (symbol (name sym))]
(when-let [ns (find-ns ns)]
(.getMapping ^clojure.lang.Namespace ns v)))))
so it's either in find-ns or in the namespace interopyeah, it's the namespace interop
I think using this interop will make GraalVM think it should hold on to more that it actually needs
Good point 🙂
so what we can do is only resolve at compile time. The user should take care of requiring the lib namespace before they load the dynaloaded code, else it will be considered not there.
is there a :preload
thing with deps? other than the -e
from command line?
no
have this on my project Justfile:
# start backend nrepl
@backend:
clj -A:dev:test:common:backend -e "(require '[hashp.core])" -m nrepl.cmdline -i -C
for graalvm builds with deps.edn that may work
with the lein + uberjar approach it may not
just take care in your main to require those libs first, then it will be solved. we can make this behavior graalvm only for example by reading an environment variable or java property
where is borkdude/am-i-in-graalvm
library?
so: 1. cljs: preload or direct require 2. jvm: just in a classpath 3. graalvm: direct require , right?
or: 2. jvm: just direct require
can one differentiate if the lib is required or just in the classpath in 2? could be an option in dynaload?
@ikitommi 1) I think in CLJS the order of require doesn't matter, because the check happens at runtime at the first deref. 2) this works because CLJ has runtime require 3) Like 1, but now the order matters, since we check at compile time, before the deref. About checking the classpath: not sure how this would look. That's kind of the same as compile time resolve.
Checking whether you are in a GraalVM binary already works, but that's too late. You have to check at (Clojure) compile time.
So based on setting -J-Dborkdude.dynaload.target=graalvm-native
we could alter the behavior or 2 to 3
or -J-Dborkdude.dynaload.resolve-time=compile
re: graalvm library, shouldn’t that be called antioch
?)
@ikitommi Here is the current state of my AWS cloudformation malli code https://github.com/jeroenvandijk/aws.cloudformation.malli/blob/master/src/adgoji/aws/cloudformation/malli/validation.clj#L15-L232
(now public)
Maybe useful information; I’ve reduced the usage of :or
and used :multi
instead to prevent super long lists of errors (reduces branching factor)
I think I broke proper spell check feedback by not using a keyword as dispatch function. I’ll look into this soon again
There's some discussion on github that might be interesting: https://github.com/metosin/malli/issues/207
@ikitommi Pushed dynaload 0.2.1 with better support for GraalVM binaries: https://github.com/borkdude/dynaload#graalvm