Fork me on GitHub
#malli
<
2019-11-02
>
roklenarcic18:11:30

I have a question related to malli, but it's probably just an error on my part but I cannot spot it: I defined macro as this (simplified example):

(defmacro x [y]
  `(println ~(m/schema [:tuple y])))
And when I call (x int?) I get:
Syntax error compiling fn* at (/private/var/folders/fm/5mzhclpd7mj0tzjjq796ftc00000gn/T/form-init14721255528686671623.clj:1:1).
Can't embed object in code, maybe print-dup not defined: malli.core$_tuple_schema$reify$reify__4266@2c3b816
However if I define macro as this it works:
(defmacro x [y]
  `(println (m/schema [:tuple ~y])))
=> #'clj-rest-client.core/x
(x int?)
[:tuple int?]

roklenarcic18:11:15

I wanted to compute the schema value at macro expansion time to make it faster, but it doesn't seem to work for some reason

roklenarcic18:11:35

maybe someone else can spot it, I've been looking at this for a while with no idea

ikitommi18:11:46

@roklenarcic macros should return source code, the first example returns a reified protocol instance. You can run (macroexpand ...) to that

ikitommi18:11:14

Just curious, "to make it faster"?

roklenarcic18:11:32

I thought that m/schema does some preprocessing

roklenarcic18:11:49

which would make it faster than sticking simply [:tuple x] in there

roklenarcic18:11:07

btw, it seems that [:tuple] doesn;'t work

roklenarcic18:11:51

(m/schema [:tuple]) -> :tuple but (m/schema [:tuple int?]) -> [:tuple int?]

ikitommi18:11:24

malli has it's own compiler for validation, explain & transform. Reaults of those should be pretty fast.

ikitommi18:11:34

Creation of schema has some overhead, but if you can store a reference to a transformer, it should be as fast as one can do with Clojure.

roklenarcic18:11:05

thanks for the info

ikitommi18:11:43

the :tuple thing... some schemas has a constraint that they should have 1+ childs. I guess tuple doesn't and empty tuple is ok...

roklenarcic18:11:43

I had spec1 code that said -> give me a vector of values and a vector of specs and I will generate a s/fdef spec (which uses s/cat), so the code generated a spec like this (s/cat :arg1 arg-spec1 ...) and potentially (s/cat) which took an empty sequence just fine. I replaced this with :tuple from malli and it seems to have a corner case for empty tuple

ikitommi18:11:25

should it require at least 1 child?

roklenarcic18:11:37

it works the opposite

roklenarcic18:11:03

(m/explain [:tuple] [])
Execution error (NullPointerException) at malli.core/-tuple-schema$reify$reify$fn (core.cljc:447).
null

roklenarcic18:11:24

but spec with empty (s/cat) would work fine

ikitommi18:11:32

Oh, that's a bug.

roklenarcic18:11:56

yeah I thought so

roklenarcic18:11:06

NPEs are usually not intended

roklenarcic18:11:57

I'm porting my rest client lib from spec to malli now... hopefully I'll have encode/decode soon

roklenarcic18:11:33

I'd like for user to be able to specify the transformation to string I should do before sending any opaque types over the wire

roklenarcic18:11:49

transforms seem to be doing the opposite direction

roklenarcic18:11:07

e.g. if user has LocalDateTime object I'd like for them to specify format in schema that I format it to before I send it...

ikitommi19:11:00

encode & decode is done (#99), but requires (#98) before will merge that in.

roklenarcic19:11:53

I'll be finally rid of the nightmare that is trying to conform s/merge specs