lein 运行 和 REPL 之间的行为不一致
Inconsistent behaviour between lein run and REPL
我是 clojure 的新手,尝试通过解决 https://www.4clojure.com 中的问题来学习它。
任务是实现展平功能。
这是我的实现:
(ns clojure-noob.core
(:gen-class))
(defn -main
"I don't do a whole lot ... yet."
[]
(= ((fn [coll]
(let [flat (fn [coll]
(when-let [s (seq coll)]
(if (sequential? (first s))
(concat (flat (first s)) (flat (rest s)))
(cons (first s) (flat (rest s))))))]
(flat coll)))
'((1 2) 3 [4 [5 6]]))
'(1 2 3 4 5 6)))
当我在 REPL 中 运行 它像 (-main) 我明白了。
当我 运行 它作为 lein 运行 我得到这个异常:
线程 "main" java.lang.RuntimeException 中的异常:无法解析符号:在此上下文中为 flat,正在编译:(clojure_noob/core.clj:11:42)
在 clojure.lang.Compiler.analyze(Compiler.java:6688)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3766)
在 clojure.lang.Compiler.analyze 序列 (Compiler.java:6870)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3834)
在 clojure.lang.Compiler.analyze 序列 (Compiler.java:6870)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$IfExpr$Parser.parse(Compiler.java:2797)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6319)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$IfExpr$Parser.parse(Compiler.java:2797)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6319)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5380)
在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3972)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6866)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.access$300(Compiler.java:38)
在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6269)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5380)
在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3972)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6866)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3766)
在 clojure.lang.Compiler.analyze 序列 (Compiler.java:6870)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:1009)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler.analyze 序列 (Compiler.java:6863)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5380)
在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3972)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6866)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.access$300(Compiler.java:38)
在 clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:589)
在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868)
在 clojure.lang.Compiler.analyze(Compiler.java:6669)
在 clojure.lang.Compiler.analyze(Compiler.java:6625)
在 clojure.lang.Compiler.eval(Compiler.java:6931)
在 clojure.lang.Compiler.load(Compiler.java:7379)
在 clojure.lang.RT.loadResourceScript(RT.java:372)
在 clojure.lang.RT.loadResourceScript(RT.java:363)
在 clojure.lang.RT.load(RT.java:453)
在 clojure.lang.RT.load(RT.java:419)
在 clojure.core$load$fn__5677.invoke(core.clj:5893)
在 clojure.core$load.invokeStatic(core.clj:5892)
在 clojure.core$load.doInvoke(core.clj:5876)
在 clojure.lang.RestFn.invoke(RestFn.java:408)
在 clojure.core$load_one.invokeStatic(core.clj:5697)
在 clojure.core$load_one.invoke(core.clj:5692)
在 clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
在 clojure.core$load_lib.invokeStatic(core.clj:5736)
在 clojure.core$load_lib.doInvoke(core.clj:5717)
在 clojure.lang.RestFn.applyTo(RestFn.java:142)
在 clojure.core$apply.invokeStatic(core.clj:648)
在 clojure.core$load_libs.invokeStatic(core.clj:5774)
在 clojure.core$load_libs.doInvoke(core.clj:5758)
在 clojure.lang.RestFn.applyTo(RestFn.java:137)
在 clojure.core$apply.invokeStatic(core.clj:648)
在 clojure.core$require.invokeStatic(core.clj:5796)
在 clojure.core$require.doInvoke(core.clj:5796)
在 clojure.lang.RestFn.invoke(RestFn.java:408)
在用户 $eval1036$fn__1038.invoke(form-init8418556840412273777.clj:1)
在用户$eval1036.invokeStatic(form-init8418556840412273777.clj:1)
在用户$eval1036.invoke(form-init8418556840412273777.clj:1)
在 clojure.lang.Compiler.eval(Compiler.java:6927)
在 clojure.lang.Compiler.eval(Compiler.java:6917)
在 clojure.lang.Compiler.load(Compiler.java:7379)
在 clojure.lang.Compiler.loadFile(Compiler.java:7317)
在 clojure.main$load_script.invokeStatic(main.clj:275)
在 clojure.main$init_opt.invokeStatic(main.clj:277)
在 clojure.main$init_opt.invoke(main.clj:277)
在 clojure.main$initialize.invokeStatic(main.clj:308)
在 clojure.main$null_opt.invokeStatic(main.clj:342)
在 clojure.main$null_opt.invoke(main.clj:339)
在 clojure.main$main.invokeStatic(main.clj:421)
在 clojure.main$main.doInvoke(main.clj:384)
在 clojure.lang.RestFn.invoke(RestFn.java:421)
在 clojure.lang.Var.invoke(Var.java:383)
在 clojure.lang.AFn.applyToHelper(AFn.java:156)
在 clojure.lang.Var.applyTo(Var.java:700)
在 clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Unable to resolve symbol: flat 在此上下文中
在 clojure.lang.Util.runtimeException(Util.java:221)
在 clojure.lang.Compiler.resolveIn(Compiler.java:7164)
在 clojure.lang.Compiler.resolve(Compiler.java:7108)
在 clojure.lang.Compiler.analyze 符号处(Compiler.java:7069)
在 clojure.lang.Compiler.analyze(Compiler.java:6648)
... 还有 128 个
我怀疑它与名称空间有关,但我不知道如何解决。
在 flat
的 let 绑定中,您引用 flat
,它目前还不可见。 fn
有一个可选的名称参数,您可以使用它来解决此问题。
(defn -main
"I don't do a whole lot ... yet."
[]
(= ((fn [coll]
(let [flat (fn flat [coll]
(when-let [s (seq coll)]
(if (sequential? (first s))
(concat (flat (first s)) (flat (rest s)))
(cons (first s) (flat (rest s))))))]
(flat coll)))
'((1 2) 3 [4 [5 6]]))
'(1 2 3 4 5 6)))
此外,代码可以在不改变含义的情况下显着简化:
(defn -main
"I don't do a whole lot ... yet."
[]
(let [flat (fn flat [[el & els :as coll]]
(when coll
(if (sequential? el)
(concat (flat el) (flat els))
(cons el (flat els)))))]
(= (flat [[1 2] 3 [4 [5 6]]])
[1 2 3 4 5 6])))
我是 clojure 的新手,尝试通过解决 https://www.4clojure.com 中的问题来学习它。 任务是实现展平功能。 这是我的实现:
(ns clojure-noob.core
(:gen-class))
(defn -main
"I don't do a whole lot ... yet."
[]
(= ((fn [coll]
(let [flat (fn [coll]
(when-let [s (seq coll)]
(if (sequential? (first s))
(concat (flat (first s)) (flat (rest s)))
(cons (first s) (flat (rest s))))))]
(flat coll)))
'((1 2) 3 [4 [5 6]]))
'(1 2 3 4 5 6)))
当我在 REPL 中 运行 它像 (-main) 我明白了。
当我 运行 它作为 lein 运行 我得到这个异常:
线程 "main" java.lang.RuntimeException 中的异常:无法解析符号:在此上下文中为 flat,正在编译:(clojure_noob/core.clj:11:42) 在 clojure.lang.Compiler.analyze(Compiler.java:6688) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3766) 在 clojure.lang.Compiler.analyze 序列 (Compiler.java:6870) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3834) 在 clojure.lang.Compiler.analyze 序列 (Compiler.java:6870) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$IfExpr$Parser.parse(Compiler.java:2797) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6319) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$IfExpr$Parser.parse(Compiler.java:2797) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6319) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001) 在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5380) 在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3972) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6866) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.access$300(Compiler.java:38) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6269) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001) 在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5380) 在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3972) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6866) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3766) 在 clojure.lang.Compiler.analyze 序列 (Compiler.java:6870) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:1009) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler.analyze 序列 (Compiler.java:6863) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001) 在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5380) 在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3972) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6866) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6856) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.access$300(Compiler.java:38) 在 clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:589) 在 clojure.lang.Compiler.analyze 序列(Compiler.java:6868) 在 clojure.lang.Compiler.analyze(Compiler.java:6669) 在 clojure.lang.Compiler.analyze(Compiler.java:6625) 在 clojure.lang.Compiler.eval(Compiler.java:6931) 在 clojure.lang.Compiler.load(Compiler.java:7379) 在 clojure.lang.RT.loadResourceScript(RT.java:372) 在 clojure.lang.RT.loadResourceScript(RT.java:363) 在 clojure.lang.RT.load(RT.java:453) 在 clojure.lang.RT.load(RT.java:419) 在 clojure.core$load$fn__5677.invoke(core.clj:5893) 在 clojure.core$load.invokeStatic(core.clj:5892) 在 clojure.core$load.doInvoke(core.clj:5876) 在 clojure.lang.RestFn.invoke(RestFn.java:408) 在 clojure.core$load_one.invokeStatic(core.clj:5697) 在 clojure.core$load_one.invoke(core.clj:5692) 在 clojure.core$load_lib$fn__5626.invoke(core.clj:5737) 在 clojure.core$load_lib.invokeStatic(core.clj:5736) 在 clojure.core$load_lib.doInvoke(core.clj:5717) 在 clojure.lang.RestFn.applyTo(RestFn.java:142) 在 clojure.core$apply.invokeStatic(core.clj:648) 在 clojure.core$load_libs.invokeStatic(core.clj:5774) 在 clojure.core$load_libs.doInvoke(core.clj:5758) 在 clojure.lang.RestFn.applyTo(RestFn.java:137) 在 clojure.core$apply.invokeStatic(core.clj:648) 在 clojure.core$require.invokeStatic(core.clj:5796) 在 clojure.core$require.doInvoke(core.clj:5796) 在 clojure.lang.RestFn.invoke(RestFn.java:408) 在用户 $eval1036$fn__1038.invoke(form-init8418556840412273777.clj:1) 在用户$eval1036.invokeStatic(form-init8418556840412273777.clj:1) 在用户$eval1036.invoke(form-init8418556840412273777.clj:1) 在 clojure.lang.Compiler.eval(Compiler.java:6927) 在 clojure.lang.Compiler.eval(Compiler.java:6917) 在 clojure.lang.Compiler.load(Compiler.java:7379) 在 clojure.lang.Compiler.loadFile(Compiler.java:7317) 在 clojure.main$load_script.invokeStatic(main.clj:275) 在 clojure.main$init_opt.invokeStatic(main.clj:277) 在 clojure.main$init_opt.invoke(main.clj:277) 在 clojure.main$initialize.invokeStatic(main.clj:308) 在 clojure.main$null_opt.invokeStatic(main.clj:342) 在 clojure.main$null_opt.invoke(main.clj:339) 在 clojure.main$main.invokeStatic(main.clj:421) 在 clojure.main$main.doInvoke(main.clj:384) 在 clojure.lang.RestFn.invoke(RestFn.java:421) 在 clojure.lang.Var.invoke(Var.java:383) 在 clojure.lang.AFn.applyToHelper(AFn.java:156) 在 clojure.lang.Var.applyTo(Var.java:700) 在 clojure.main.main(main.java:37) Caused by: java.lang.RuntimeException: Unable to resolve symbol: flat 在此上下文中 在 clojure.lang.Util.runtimeException(Util.java:221) 在 clojure.lang.Compiler.resolveIn(Compiler.java:7164) 在 clojure.lang.Compiler.resolve(Compiler.java:7108) 在 clojure.lang.Compiler.analyze 符号处(Compiler.java:7069) 在 clojure.lang.Compiler.analyze(Compiler.java:6648) ... 还有 128 个
我怀疑它与名称空间有关,但我不知道如何解决。
在 flat
的 let 绑定中,您引用 flat
,它目前还不可见。 fn
有一个可选的名称参数,您可以使用它来解决此问题。
(defn -main
"I don't do a whole lot ... yet."
[]
(= ((fn [coll]
(let [flat (fn flat [coll]
(when-let [s (seq coll)]
(if (sequential? (first s))
(concat (flat (first s)) (flat (rest s)))
(cons (first s) (flat (rest s))))))]
(flat coll)))
'((1 2) 3 [4 [5 6]]))
'(1 2 3 4 5 6)))
此外,代码可以在不改变含义的情况下显着简化:
(defn -main
"I don't do a whole lot ... yet."
[]
(let [flat (fn flat [[el & els :as coll]]
(when coll
(if (sequential? el)
(concat (flat el) (flat els))
(cons el (flat els)))))]
(= (flat [[1 2] 3 [4 [5 6]]])
[1 2 3 4 5 6])))