在Scheme中,我们只定义了所有定义,为什么Clojure和Lisp对不同的声明使用不同的关键字?
答案 0 :(得分:16)
defn
,defmacro
,defstruct
等只是用于定义相应结构的宏,因此无需编写样板代码。例如,defn
使编写函数变得更容易,因为您不再需要担心放入lambda术语(您可以在Scheme中执行,只需在定义名称后立即包围参数):
方案:
(define hello
(lambda (name)
(display (string-append "hello, " name))))
(define (hello name)
(display (string-append "hello, " name)))
Clojure的:
(def hello
(fn [name]
(println (str "hello, " name))))
(defn hello [name]
(println (str "hello, " name)))
您可以将defn
视为def
+ fn
的mnemomic设备。这样的快捷方式可以减少样板编码,并使代码更容易阅读。我正在教某人如何对Scheme进行编程,我让他们使用长形式,以便他们始终记住语言正在做什么(当他们最终开始时,他们会更加欣赏节省工作的宏使用它们。)
define
或def
表单为后面的某个表达式命名。 lambda
或fn
表单在define
或def
表达式中使用时,会为名称提供一组绑定。这就是事情开始变得更加复杂的地方,使用宏观形式可以让你保持理智并保护你免于输入无聊。
答案 1 :(得分:2)
它们定义了不同类型的对象(函数,特殊变量,宏,结构,类,泛型函数,方法,包)。在Common Lisp中,它们也位于不同的命名空间中。不同的定义形式也有不同的语法(Scheme的define
结合了变量和函数定义。但它能定义一个类吗?)
答案 2 :(得分:1)
def
是一种特殊的形式,保持特殊形式尽可能简单和原始是很好的。 defn
是一个添加糖的宏,可以轻松设置文档字符串和元数据,并且(正如其他人所说的那样)消除了对外来parens的需求。 defn
还会自动为您的函数本身设置一些元数据(显示arglists等),这对于一般def
毫无意义。
到目前为止,函数是Clojure中最常用的函数。不鼓励使用Toplevel可变变量。因此,有一种简单快捷的方法来定义顶层函数是有意义的。使用def
获取所有内容会产生大量样板。如果没有defn
我们都会自己重新发明,以免被人惹恼。