user=> (time (m/validate [:cat [:+ [:+ [:enum 0]]] [:enum 1]] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]) )
"Elapsed time: 0.582137 msecs"
true
user=> (time (s/valid? (s/cat :zeroes (s/+ (s/+ #{0})) :one #{1}) [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]))
"Elapsed time: 1265.3679 msecs"
(got the example from https://quanttype.net/posts/2021-03-06-clojure-spec-and-untrusted-input.html)Are there any examples of regexes that are slow in malli too?
Malli's regular expression matching algorithm is fundamentally different, so as far as i know, it does not have the exponential slow down problem. Probably you could still come up with some slow examples, but I don't have insight into what is slow and what is fast.
Because it doesn't have backtracking, right?
It does use backtracking, but see the ns docstring for discussion: https://github.com/metosin/malli/blob/master/src/malli/impl/regex.cljc
I did follow up with the example and it did work
I have a follow-up question, though
I’m wondering if m/decode
with the above schema is supposed to produce that result, and if so, I was wondering how to solve this so that I return [1.0 "A"]
from decode?
@arundilipan works on my machine:
(ns sample.core
(:require [malli.core :as m]
[malli.transform :as mt]))
(def GreaterThanZero
[:fn {:decode/string mt/-string->double}
'#(> % 0)])
(def TestEnum
[:enum "A" "B"])
(m/decode
[:catn
[:amount GreaterThanZero]
[:layout TestEnum]]
["1.0" "A"]
mt/string-transformer)
; => [1.0 "A"]
if the result doesn’t match the schema after the transformation, the top-level schema returns the original. this is a feature of the current regex impl, doesn’t support partial transformation:
(m/decode
[:catn
[:amount GreaterThanZero]
[:layout TestEnum]]
["1.0" "C"]
mt/string-transformer)
; => ["1.0" "C"]
Oh that’s it, you’re right
In that case I guess the thing to do would be do use something like edn/read-string
instead of decode
? I’d like to make sure that the number is parsed regardless of the result of the rest of the :catn
or, you could use non-regex schema like :tuple
:
(m/decode
[:tuple GreaterThanZero TestEnum]
["1.0" "C"]
mt/string-transformer)
; => [1.0 "C"]
no :tuplen
atm 😉
you could write issue about the partial decoding with regex?
(might be easy to fix)
Yea i’ll make an issue on the repo
Right now I’m trying to use the :catn
variants because of the coercion into a map
Done!