Ваша спецификация генерируется символически во время компиляции? Если это так, возможно, вы могли бы использовать макрос, как вы предлагали.
(ns foo.core)
(defmacro gen-spec []
`'~(into '[:first-name string?] '[:surname string?]))
(defmacro apply-macro [name args-form]
`(~name ~@(eval args-form)))
Вот пример использования
$ clj -m cljs.main
ClojureScript 1.10.339
cljs.user=> (require '[clojure.spec.alpha :as s])
nil
cljs.user=> (require-macros 'foo.core)
nil
cljs.user=> (foo.core/gen-spec)
[:first-name string? :surname string?]
cljs.user=> (foo.core/apply-macro s/cat (foo.core/gen-spec))
{:cljs.spec.alpha/op :cljs.spec.alpha/pcat, :ps [#object[cljs$core$string_QMARK_] #object[cljs$core$string_QMARK_]], :ret {}, :ks [:first-name :surname], :forms [cljs.core/string? cljs.core/string?], :rep+ nil}
Обратите внимание, как gen-spec
символически создает спецификацию и возвращает ее в кавычках.