In Clojure you can unquote-splice a list of values to generate code, e.g.
(def extra-values [1 2 3 4])
`(+ 100 200 ~@extra-values)
=> (clojure.core/+ 100 200 1 2 3 4)
It seems logical that the same approach should work in an unquoted context, e.g.
(def extra-values [1 2 3 4])
(+ 1000 ~@extra-values)
=> [an error, but one could argue that the answer should be 1010??]
Is there any deep technical/philosphical reason why this can't work?
One simple reason is that then
`(+ 100 200 ~@extra-values)
would be poorly defined: does it expand to
(+ 100 200 1 2 3 4)
or to
(+ 100 200 ~@extra-values)
? Both are valid interpretations if the ~@
construct is legal in that context.
It also causes serious issues in the macro system. Consider
(defmacro foo [x & args]
`(list ~x ~(count args)))
(let [data '(1 2 3)]
(foo "three" ~@data))
How can foo
know what args it is being passed? It certainly can't expand that at compile-time, so now unquote-splicing is only valid in some non-quoted contexts.
And overall it's just muddying up the language to accommodate for poor understanding of core concepts - if you really want to unquote-splice to build a complicated argument list, you can easily use apply
in something like
(apply + `(100 ~@extra-values 200))