Fork me on GitHub
#malli
<
2020-09-17
>
Stefan09:09:59

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.

jeroenvandijk11:09:32

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

borkdude11:09:09

Although @ikitommi mentioned that the goal of the current Clojurists Together funding is to make a stable (non-alpha) release?

borkdude11:09:31

With spec it remains to be seen. It's been in alpha for over 4 years.

jeroenvandijk11:09:52

Good point 🙂

rschmukler20:09:03

There's some discussion on github that might be interesting: https://github.com/metosin/malli/issues/207

jeroenvandijk11:09:52

@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

jeroenvandijk14:09:57

Maybe useful information; I’ve reduced the usage of :or and used :multi instead to prevent super long lists of errors (reduces branching factor)

jeroenvandijk14:09:30

I think I broke proper spell check feedback by not using a keyword as dispatch function. I’ll look into this soon again

ikitommi11:09:27

@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.

ikitommi11:09:49

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.

borkdude11:09:25

@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.)

ikitommi11:09:25

1.0.0 might be soon too, after feedback from the community.

ikitommi11:09:24

@borkdude sorry, read you message, but didn’t have time to answer. There is no GraalVM tests atm, should be.

borkdude11:09:48

I will publish dynaload 0.2.0 or so that will have breaking changes to fix this problem, but I'll notify you

borkdude11:09:52

and possibly make a PR

ikitommi11:09:24

that would be great! GraalVM support is top priority, don’t want bloated binaries 🙂

ikitommi11:09:49

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.

borkdude11:09:52

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 interop

borkdude11:09:20

yeah, it's the namespace interop

borkdude11:09:37

I think using this interop will make GraalVM think it should hold on to more that it actually needs

borkdude11:09:02

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.

ikitommi11:09:43

is there a :preload thing with deps? other than the -e from command line?

ikitommi11:09:32

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

borkdude11:09:50

for graalvm builds with deps.edn that may work

borkdude11:09:00

with the lein + uberjar approach it may not

borkdude11:09:45

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

ikitommi11:09:20

where is borkdude/am-i-in-graalvm library?

ikitommi11:09:22

so: 1. cljs: preload or direct require 2. jvm: just in a classpath 3. graalvm: direct require , right?

ikitommi11:09:44

or: 2. jvm: just direct require

ikitommi11:09:10

can one differentiate if the lib is required or just in the classpath in 2? could be an option in dynaload?

borkdude11:09:54

@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.

borkdude11:09:34

Checking whether you are in a GraalVM binary already works, but that's too late. You have to check at (Clojure) compile time.

borkdude11:09:32

So based on setting -J-Dborkdude.dynaload.target=graalvm-native we could alter the behavior or 2 to 3

borkdude11:09:17

or -J-Dborkdude.dynaload.resolve-time=compile

eskos13:09:04

re: graalvm library, shouldn’t that be called antioch ?)

borkdude21:09:17

@ikitommi Pushed dynaload 0.2.1 with better support for GraalVM binaries: https://github.com/borkdude/dynaload#graalvm

🎉 3