使用def和defn而不仅仅是定义的理由是什么?

时间:2009-07-22 04:20:29

标签: lisp clojure scheme

在Scheme中,我们只定义了所有定义,为什么Clojure和Lisp对不同的声明使用不同的关键字?

3 个答案:

答案 0 :(得分:16)

defndefmacrodefstruct等只是用于定义相应结构的宏,因此无需编写样板代码。例如,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进行编程,我让他们使用长形式,以便他们始终记住语言正在做什么(当他们最终开始时,他们会更加欣赏节省工作的宏使用它们。)

definedef表单为后面的某个表达式命名。 lambdafn表单在definedef表达式中使用时,会为名称提供一组绑定。这就是事情开始变得更加复杂的地方,使用宏观形式可以让你保持理智并保护你免于输入无聊。

答案 1 :(得分:2)

它们定义了不同类型的对象(函数,特殊变量,宏,结构,类,泛型函数,方法,包)。在Common Lisp中,它们也位于不同的命名空间中。不同的定义形式也有不同的语法(Scheme的define结合了变量和函数定义。但它能定义一个类吗?)

答案 2 :(得分:1)

Clojure中的

def是一种特殊的形式,保持特殊形式尽可能简单和原始是很好的。 defn是一个添加糖的宏,可以轻松设置文档字符串和元数据,并且(正如其他人所说的那样)消除了对外来parens的需求。 defn还会自动为您的函数本身设置一些元数据(显示arglists等),这对于一般def毫无意义。

到目前为止,函数是Clojure中最常用的函数。不鼓励使用Toplevel可变变量。因此,有一种简单快捷的方法来定义顶层函数是有意义的。使用def获取所有内容会产生大量样板。如果没有defn我们都会自己重新发明,以免被人惹恼。