Let's create our own 78 digits long string type:
(def hex-digit (set "0123456789"))
(defn hex-digit? [x] (contains? hex-digit x))
(defn hex-str? [s] (every? hex-digit? (seq s)))
(s/def ::hash (s/and hex-str? #(= (count %) 78)))
::hash is now registered, now we go to the REPL:
(s/valid? ::hash "23179372")
;;=> false
(s/valid? ::hash "nope93721907914920047210715459933122004671648400678953445710500236944435987060")
;;=> false
(s/valid? ::hash "231793721907914920047210715459933122004671648400678953445710500236944435987060")
;;=> true
That's cool, but we want to generate too:
(defn hex-str-gen [n] (let [digit (g/elements hex-digit)] (g/fmap clojure.string/join (g/vector digit n))))
(s/def ::hash (s/with-gen (s/and hex-str? #(= (count %) 78)) #(hex-str-gen 78)))
We extended our ::hash spec with a generator function, so we can do this now:
(g/generate (s/gen ::hash))
;;=> "310584715385467847758653938894742415543975445356609397864862925839413265904779"
(+ Pro tip: you could spec functions too)
Learn more about spec here: https://clojure.org/guides/spec
This is not a conventional way at all. It would be really hard to explain properly, but I have a simple example for you: The REPL
It means: Read -> Eval -> Print -> Loop and is a very basic and common thing that relies on homoiconicity, haha
1. "Has clojure.spec worked out in terms finding bugs during refactoring/maintenance and general QA?" - Spec worked out as a much more useful library than we expected. You could describe any data structures with it, then validate, generate, regenerate it. I think spec is a must have for any Clojure programmer from 2018.
2. "Do you make use of the Lispy-ness" Macros are super useful sometimes, but in general we try to avoid them, because we prefer to solve everything with just pure functions. Homoiconicity and the "code is data" aspect are must haves in any programming language after you realised their power.
3. "is it generally an anti-pattern to use these language features in daily development?" macros are feel like cheating sometimes, and we fear the consequences, but homiconicity is useful for us on a daily basis.
4. "Do you wish you had static types?" We prefer to create our own "types" up to complex data structures. A built-in type system seems like a downgrade from here.
5. "I often have the feeling that I'm not smart enough to use Lisp." I think you are just scared from the unknown, Clojure is an alien technology compared to most of the currently popular languages.
Any kids could learn programming in Clojure due to its simplicity and the REPL driven workflow. Its an interactive experience and very likeable.