在Clojure中的一厢情愿

Mat*_*teo 4 lisp scheme clojure

在Scheme I中我习惯做这样的事情

(define (f x) (g x))
(define (g x) (+ x 42))
(g 0)
Run Code Online (Sandbox Code Playgroud)

也就是说,我习惯用其他瞬间无界函数来定义函数.为什么在Clojure中不可能这样做?例如,在Clojure REPL上,以下内容无效

(defn f [x] (g x))
(defn g [x] (+ x 42))
(g 0)
Run Code Online (Sandbox Code Playgroud)

lee*_*ski 11

事情是每一行都是在repl中编译的,所以在编译g时没有函数f.您应该在(declare g)之前添加,(defn f...以便编译器知道此函数:

user> (declare g)
#'user/g

user> (defn f [x] (g x))
#'user/f

user> (defn g [x] (+ x 42))
#'user/g

user> (g 0)
42
Run Code Online (Sandbox Code Playgroud)

  • @Matteo Rich Hickey在[本HN评论](https://news.ycombinator.com/item?id=2467809)中给出了这种行为的基本原理,这基本上归结为你希望对undefined有什么类型的错误符号:运行时还是编译时?Common Lisp选择运行时错误,Clojure选择编译时错误. (9认同)
  • @CurtisSummers:Common Lisp选择:编译时警告,后期绑定和运行时错误. (4认同)
  • 为什么REPL不会自动"声明"未定义的函数?不是更容易吗? (3认同)
  • CF Matthew Flatt,"最高级别无望." 我能找到最好的参考:http://calculist.blogspot.com/2009/01/fexprs-in-scheme.html (3认同)