在-main中调用函数时的Clojure顺序依赖关系
我是Clojure的新手,正在尝试构建一些示例应用程序来适应语法。我注意到以下顺序依赖行为 我创建了一个名为timex的项目来计算两个日期之间的时间(以周为单位)。我使用clj时间函数计算日期差 如果my core.clj如下所示:在-main中调用函数时的Clojure顺序依赖关系,clojure,Clojure,我是Clojure的新手,正在尝试构建一些示例应用程序来适应语法。我注意到以下顺序依赖行为 我创建了一个名为timex的项目来计算两个日期之间的时间(以周为单位)。我使用clj时间函数计算日期差 如果my core.clj如下所示: (ns timex.core (:gen-class)) (defn -main "Calculate weeks between dates." [& args] dp ) (require '[clj-time.core :a
(ns timex.core
(:gen-class))
(defn -main
"Calculate weeks between dates."
[& args]
dp
)
(require '[clj-time.core :as t])
(def d2 (t/date-time 1989 01 07))
(def dw (t/in-weeks (t/interval d2 (t/now))))
(def dp (str "The number of weeks between Jan 7, 1989 and now is " dw "!"))
**
如果运行lein repl,则会出现以下错误:
#CompilerException java.lang.RuntimeException:无法解析此上下文中的符号:dp,正在编译:(timex/core.clj:4:1)
但是如果我重新排列文件中的行,并将def和require语句放在main之前,那么
(ns timex.core
(:gen-class))
(require '[clj-time.core :as t])
(def d2 (t/date-time 1989 01 07))
(def dw (t/in-weeks (t/interval d2 (t/now))))
(def dp (str "The number of weeks between Jan 7, 1989 and now is " dw "!"))
(defn -main
"Calculate weeks between dates."
[& args]
dp
)
**
然后,当我运行lein repl并调用(-main)函数时,我得到:
timex.core=> (-main)
"The number of weeks between Jan 7, 1989 and now is 1341!"
这种明显的订单依赖是正常的还是我做错了什么?如果是后者,那么我将非常感谢任何我应该审查的建议或文件。谢谢。Clojure中的编译单元是
s-expression
,而不像许多其他语言那样是一个完整的文件。加载文件时,将在一次过程中从上到下对该文件进行评估。变量(通过调用def
创建的)必须在使用它们的位置上方创建,或者如果需要相互递归,可以使用declare
,尽管这种情况很少
花一些时间来习惯传统意义上的编译文件和lisp意义上的加载文件之间的区别是值得的,因为它是宏系统和语言的许多其他方面的基础。当您需要命名空间中的文件,或从repl调用load file
时,将调用clojure编译器并重复读取,宏将展开,然后从顶部开始计算文件中的每个文件。第一行告诉它定义事物的名称空间,这就是为什么ns
表达式首先出现的原因。然后,进一步的表单定义该名称空间中的内容。如果再次加载文件,它只不过是从顶部重新读取文件而已。它不会清除名称空间或任何其他魔法,因此,如果您对文件求值,然后更改顺序并再次求值,它可以继续工作,因为在运行第二个过程时,所需的函数已经在名称空间中定义(存储在memeory中)。习惯了这一点后,经常运行lein check
,以确保事情井然有序
注:对require
的调用绝大多数时间都是在文件顶部的ns
表单中进行的。有一篇文章讨论了与编译单元相关的设计思想。