在Clojure中,如果在定义之前调用函数,例如
(foo (bar 'a))
(defn bar [] ...)
Run Code Online (Sandbox Code Playgroud)
它没有编译.应该补充一点
(declare bar)
Run Code Online (Sandbox Code Playgroud)
之前(foo (bar 'a)).为什么Clojure是这样设计的?我的意思是,在大多数语言中,除了C/C++,如Java,Python,PHP,Scala,Haskell甚至其他Lisps,特别是在动态类型语言中,不需要函数声明,也就是说,函数定义可以放在在通话之前或之后.我觉得使用起来很不舒服.
nha*_*nha 18
Clojure进行单遍编译(我简化,阅读以下链接):
因此,如果您只阅读一次源代码,从上到下,您就无法获得前向声明等内容并安全地执行,这似乎是合乎逻辑的.
引用Rich(第一个链接):
但是,这里应该发生什么,当编译器从未见过bar?
Run Code Online (Sandbox Code Playgroud)`(defn foo [] (bar))`或在CL中:
Run Code Online (Sandbox Code Playgroud)`(defun foo () (bar))`CL很乐意编译它,如果从未定义bar,则会发生运行时错误.好吧,但是,在编辑期间,什么具体化的东西(符号)用于吧?读取表单时它所占用的符号.因此,当您收到运行时错误并意识到该条在您忘记导入的另一个包中定义时会发生什么.你试图导入other-package和BAM !,另一个错误 - 冲突,其他包:bar与read-in-package冲突:bar.然后你去学习uninterning.
在Clojure中,表单不会编译,您会收到一条消息,并且没有为bar实现内容.您需要其他命名空间并继续.
我非常喜欢这种体验,因此做出了这些权衡.使用非实习阅读器和仅仅在定义/声明方面实现了许多其他好处.我不倾向于放弃它们,也不倾向于前面提到的好处,以支持循环引用.
| 归档时间: |
|
| 查看次数: |
1928 次 |
| 最近记录: |