clojure-spec

About: http://clojure.org/about/spec Guide: http://clojure.org/guides/spec API: https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html
rival 2020-07-08T07:21:15.451200Z

Hi everyone 👋 to get my head around spec, I decided to just pick the FIX protocol and spec it. The result is my first Clojure lib https://github.com/rvalentini/fix.core. However the way I used spec felt a little bit "forced" here and there. At some point, I had the feeling that I was wrapping my validation logic into a thin spec wrapper definition for the sake of using spec, without much benefits. I couldn't find a clean/nice way how to build the validation logic as composition of individual specs. To illustrate what I mean: in https://github.com/rvalentini/fix.core/blob/master/src/fix/spec/primitives_spec.clj it felt for me like an "intended" usage of spec, where the individual spec definitions compose quite nicely. But here https://github.com/rvalentini/fix.core/blob/master/src/fix/spec/message_spec.clj it felt more like I misused spec, since the spec definition is just like a facade. Any advice on how I could improve this is much appreciated!

misha 2020-07-08T15:05:02.457100Z

@riccardovalentini1854 Spec's strengths are granular errors, parsing, generators. Since you basically use/provide neither of those, and just give "yes/no" answer to "valid?" – I think, such validation would be "lighter" with instaparse, or just giant regex. What can be alternatively useful, though, is a speced (with generators) edn DSL + an encode/decode functions to/from that edn data structure to FIX string messages. (pretty much what I'm doing for graphviz dot files, right now)

rival 2020-07-09T07:04:49.459500Z

@misha Thanks a lot for your feedback! As a next step I planned to improve the error reporting for the client, so that in case the validation fails, the client receives some message indicating which part of the FIX message is invalid. I could make use of spec's granular error reporting there I think. I will also have a look at custom generators and think about how I could apply them to the internal edn representation of the parsed FIX messages. A nice encoder to produce FIX messages also sounds like a good idea! 👍

misha 2020-07-08T15:13:10.459200Z

user then can explore "WTH is FIX message, anyway?" with s/exercise, and assemble messages as familiar maps/vectors with core functions, validate, get granular errors, etc, and then convert them into message strings.