从 clojure 1.9 升级到 clojure 1.12 时出现以下错误
Syntax error macroexpanding defact at (up/lib/pvm/fact.clj:23:18).
Don't know how to create ISeq from: clojure.lang.Symbol
有问题的代码是这样的:
(defmacro defact
([name fields] (defact &form &env name nil fields nil nil))
([name doc-string? fields] (defact &form &env name doc-string? fields nil nil))
([name fields meta-key meta-val] (defact &form &env name nil fields meta-key meta-val))
([name doc-string? fields meta-key meta-val & meta-data]
(let [gname name
kfields (into [] (map keyword fields))
classword (str *ns* "/" gname)
md-list (when (and meta-key meta-val)
[meta-key meta-val])
md-list (if meta-data
(concat md-list meta-data)
md-list)
md (apply hash-map md-list)
md (if (empty? md) nil md)
doc (or doc-string? (str "Positional factory function for map " classword "."))]
`(do
(def ~(symbol (str gname '-meta)) ~md)
(def ~(symbol gname) ~classword)
(defn ~(symbol (str gname '?))
[m#]
(= ~classword (:fact-type m#)))
(defn ~(symbol (str 'map-> gname))
~doc
([m#]
(with-meta
(assoc m# :fact-type ~classword)
~md)))
(defn ~(symbol (str '-> gname))
~doc
([& m#]
(if (= ~(count kfields) (count m#))
(with-meta
(assoc
(zipmap ~kfields m#)
:fact-type ~classword)
~md)
(throw (ex-info "Incorrect number of arguments" {:got (count m#) :desired ~(count kfields)}))))))))
)
这是非常旧的遗留代码,我们需要升级 clojure 版本。由于某种原因,我仍然可以构建
uberjar
,但它在 lein check
期间失败,这是我们构建过程的一部分。
我认为这个问题与 1.9.0-alpha3 中的更改有关,但我在推荐的解决方案中找不到任何内容。这也是我们无法摆脱的低级代码。任何帮助将不胜感激
我尝试过删除和移动各种参数,但是我对 clojure 不太熟悉,这似乎利用了我不完全理解的语言的一些功能,而且我似乎找不到资源。
完整报告:
{:clojure.main/message
"Syntax error macroexpanding defact at (up/lib/pvm/fact.clj:23:18).\nDon't know how to create ISeq from: clojure.lang.Symbol\n",
:clojure.main/triage
{:clojure.error/phase :macro-syntax-check,
:clojure.error/line 23,
:clojure.error/column 18,
:clojure.error/source "fact.clj",
:clojure.error/symbol defact,
:clojure.error/path "up/lib/pvm/fact.clj",
:clojure.error/class java.lang.IllegalArgumentException,
:clojure.error/cause
"Don't know how to create ISeq from: clojure.lang.Symbol"},
:clojure.main/trace
{:via
[{:type clojure.lang.Compiler$CompilerException,
:message
"Syntax error macroexpanding defact at (up/lib/pvm/fact.clj:23:18).",
:data
{:clojure.error/phase :macro-syntax-check,
:clojure.error/line 23,
:clojure.error/column 18,
:clojure.error/source "up/lib/pvm/fact.clj",
:clojure.error/symbol defact},
:at [clojure.lang.Compiler macroexpand1 "Compiler.java" 7533]}
{:type java.lang.IllegalArgumentException,
:message "Don't know how to create ISeq from: clojure.lang.Symbol",
:at [clojure.lang.RT seqFrom "RT.java" 577]}],
:trace
[[clojure.lang.RT seqFrom "RT.java" 577]
[clojure.lang.RT seq "RT.java" 557]
[clojure.core$seq__5484 invokeStatic "core.clj" 139]
[clojure.core$map$fn__5952 invoke "core.clj" 2763]
[clojure.lang.LazySeq force "LazySeq.java" 50]
[clojure.lang.LazySeq realize "LazySeq.java" 89]
[clojure.lang.LazySeq seq "LazySeq.java" 106]
[clojure.lang.RT seq "RT.java" 555]
[clojure.core$seq__5484 invokeStatic "core.clj" 139]
[clojure.core.protocols$seq_reduce invokeStatic "protocols.clj" 24]
[clojure.core.protocols$fn__8258 invokeStatic "protocols.clj" 74]
[clojure.core.protocols$fn__8258 invoke "protocols.clj" 74]
[clojure.core.protocols$fn__8199$G__8194__8212
invoke
"protocols.clj"
13]
[clojure.core$reduce invokeStatic "core.clj" 6965]
[clojure.core$into invokeStatic "core.clj" 7038]
[clojure.core$into invoke "core.clj" 7029]
[up.lib.pvm.fact$defact invokeStatic "fact.clj" 31]
[up.lib.pvm.fact$defact doInvoke "fact.clj" 6]
[clojure.lang.RestFn applyTo "RestFn.java" 175]
[clojure.lang.Var applyTo "Var.java" 707]
[clojure.lang.Compiler macroexpand1 "Compiler.java" 7516]
[clojure.lang.Compiler analyzeSeq "Compiler.java" 7607]
[clojure.lang.Compiler analyze "Compiler.java" 7312]
[clojure.lang.Compiler analyze "Compiler.java" 7268]
[clojure.lang.Compiler$BodyExpr$Parser parse "Compiler.java" 6640]
[clojure.lang.Compiler$FnMethod parse "Compiler.java" 5982]
[clojure.lang.Compiler$FnExpr parse "Compiler.java" 4544]
[clojure.lang.Compiler analyzeSeq "Compiler.java" 7619]
[clojure.lang.Compiler analyze "Compiler.java" 7312]
[clojure.lang.Compiler analyzeSeq "Compiler.java" 7609]
[clojure.lang.Compiler analyze "Compiler.java" 7312]
[clojure.lang.Compiler access$200 "Compiler.java" 43]
[clojure.lang.Compiler$DefExpr$Parser parse "Compiler.java" 589]
[clojure.lang.Compiler analyzeSeq "Compiler.java" 7621]
[clojure.lang.Compiler analyze "Compiler.java" 7312]
[clojure.lang.Compiler analyze "Compiler.java" 7268]
[clojure.lang.Compiler eval "Compiler.java" 7695]
[clojure.lang.Compiler eval "Compiler.java" 7680]
[clojure.lang.Compiler load "Compiler.java" 8157]
[clojure.lang.RT loadResourceScript "RT.java" 401]
[clojure.lang.RT loadResourceScript "RT.java" 392]
[clojure.lang.RT load "RT.java" 479]
[clojure.lang.RT load "RT.java" 444]
[clojure.core$load$fn__6929 invoke "core.clj" 6189]
[clojure.core$load invokeStatic "core.clj" 6188]
[clojure.core$load doInvoke "core.clj" 6172]
[clojure.lang.RestFn invoke "RestFn.java" 411]
[user$eval52338$fn__52349
invoke
"form-init13786016343757455939.clj"
1]
[user$eval52338 invokeStatic "form-init13786016343757455939.clj" 1]
[user$eval52338 invoke "form-init13786016343757455939.clj" 1]
[clojure.lang.Compiler eval "Compiler.java" 7691]
[clojure.lang.Compiler eval "Compiler.java" 7681]
[clojure.lang.Compiler load "Compiler.java" 8157]
[clojure.lang.Compiler loadFile "Compiler.java" 8095]
[clojure.main$load_script invokeStatic "main.clj" 476]
[clojure.main$init_opt invokeStatic "main.clj" 478]
[clojure.main$init_opt invoke "main.clj" 478]
[clojure.main$initialize invokeStatic "main.clj" 509]
[clojure.main$null_opt invokeStatic "main.clj" 543]
[clojure.main$null_opt invoke "main.clj" 540]
[clojure.main$main invokeStatic "main.clj" 665]
[clojure.main$main doInvoke "main.clj" 617]
[clojure.lang.RestFn applyTo "RestFn.java" 140]
[clojure.lang.Var applyTo "Var.java" 707]
[clojure.main main "main.java" 40]],
:cause "Don't know how to create ISeq from: clojure.lang.Symbol",
:phase :macro-syntax-check}}
我将第一个调用修改为:
([name fields]
(println (str "defact: " name "---" fields))
(defact &form &env name nil fields nil nil))
当我运行服务器时,会打印以下内容:
defact: BasicSetReq []
defact: BasicSetResp [docs-map]
语法错误是由于
&form
和 &env
以及宏的重载方式造成的。重载函数调用:
([name fields] (defact &form &env name nil fields nil nil))
([name doc-string? fields] (defact &form &env name doc-string? fields nil nil))
([name fields meta-key meta-val] (defact &form &env name nil fields meta-key meta-val))
需要更改为:
([name fields] `(defact ~name nil ~fields nil nil))
([name doc-string? fields] `(defact ~name ~doc-string? ~fields nil nil))
([name fields meta-key meta-val] `(defact ~name nil ~fields ~meta-key ~meta-val))