Is it possible to parse streams or lazy seqs with spec? Specifically, I'm interested in a stream where trying to consume too much data would cause it to hang forever.
To clarify that a little, there would be a number at the beginning that tells me how many more numbers to consume.
Spec is not designed to be used for parsing. I suspect you already know that but it's worth repeating.
Huh, I guess I'd forgotten that. So definitely worth repeating! Thanks!
(you can abuse Spec for parsing but it will often be suboptimal... at best)
@seancorfield I understand that Spec is not meant for high performance parsing. I do find it useful and use it sometimes to parse datastructures. Do you know of a nice alternative that is performant?
https://github.com/youngnh/parsatron this library could be a good starting point but it was designed to parse strings instead of data so might need some tweaks
That's useful as well as alternative to instaparse. Thank you
instaparse can not be turned into the parser of data structures unfortunately. Only strings are allowed and this is deeply hidden inside of implementation details
Yeah I might have combined instaparse with clojure.spec. Not sure actually
https://github.com/metosin/malli and https://github.com/noprompt/meander come to mind. They attack different problems, but are both useful when working in the domain of "I need to interpret some data structures".
I just read this article: https://juxt.pro/blog/posts/parsing-with-clojure-spec.html (a small parser for ical-entries) and watched this video: https://www.youtube.com/watch?v=xLB8Xgt8lpA (a simple hiccup-parser). These seemed (to me, as a spec beginner) reasonable applications of spec - maybe, because, they are quite simple? Would there be a problem for using spec at this scale?
Additional question: is it considered idiomatic to dispatch a multimethod on the result of a s/conform? Are there drawbacks?
I have done that. Cannot think of real drawbacks expect for that if your spec changes you have to update the multimethods
(Changing) dispatch functions of multimethods are a bit of a hassle in a repl environment as it is hard to undefine (for good reasons). But to make this work in the repl you need to use some tricks
ok, thanks!
Temporarily placing (def my-multimethod nil)
in front of the defmulti
and then recompiling the namespace is an easy way to do it!
@dergutemoritz This is true, but you have to reload all the namespace or the method is not extended the way you expect. My trick is to define a dispatch function and define the method as (defmulti my-method #'dispatch-my-method)
. This has been the most reliable way for me when working in the repl for a long time
Ah right, if you have method implementations in other namespaces, then this trick won't suffice, good point 🙂
Good idea with the var