Using core.match with function arguments
Recently I started learning Clojure (partly in preparation for its upcoming section in my tour through seven languages) and I ran into a problem when trying to pattern match on arguments. You can’t just pass them straight to match
and expect to follow most current online examples. The types aren’t quite right! You’ll always get back the :else
clause or some other odd behaviour.
Function arguments in Clojure are of type ArraySeq
(and for good reason), but using core.match with Seqs requires a different (slightly more verbose) syntax. The simplest way to make things work as you might expect is to convert the arguments into a Vector first.
Solution
Use vec to convert the function arguments into a vector before passing them to match
:
(use '[clojure.core.match :only (match)])
(defn -main [& args]
(println (match (vec args)
["echo" word] word
:else "Invalid command")))
Alternate Solution
If spending time and processing power just to spare some syntax is unappealing to you, then I’d recommend using core.match’s Seq Matching capabilities directly:
(use '[clojure.core.match :only (match)])
(defn -main [& args]
(println (match [args]
[(["echo" word] :seq)] word
:else "Invalid command")))
Note the differences:
(match [args]
- The arguments are wrapped in a vector instead of being converted to one[(["echo" word] :seq)] word
- Any patternx
is enclosed like so:[(x :seq)]
Hope this has helped!