【发布时间】:2009-07-22 04:20:28
【问题描述】:
在Scheme中,我们只是定义了所有的定义,为什么Clojure和Lisp在不同的声明中使用不同的关键字?
【问题讨论】:
在Scheme中,我们只是定义了所有的定义,为什么Clojure和Lisp在不同的声明中使用不同的关键字?
【问题讨论】:
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 的助记符。这样的快捷方式可以减少样板代码,并使代码更容易阅读。我现在正在教某人如何编程 Scheme,我让他们使用长格式,以便他们始终牢记该语言正在做什么(并且当他们最终开始时会更加欣赏节省工作的宏使用它们)。
define 或 def 形式为后面的某些表达式命名。当在define 或def 表达式中使用时,lambda 或fn 形式为名称提供了一组绑定。这就是事情开始变得更加复杂的地方,使用宏形式可以让您保持清醒并避免打字无聊。
【讨论】:
define 的语法,以便与 s 表达式松散地相关,而不是为名称(原子)赋予值。我猜是潜意识注意到的“语义不精确”让我感到不安。
f 本身也有一个值,也有一个代数等价物:“将 f(x) 定义为 x^2,计算 f 的导数”。
(define (function arg)... 对我来说一直很陌生。再次感谢您指出使用它的理由。
它们定义了不同类型的对象(函数、特殊变量、宏、结构、类、通用函数、方法、包)。在 Common Lisp 中,它们也位于不同的命名空间中。不同的定义形式也有不同的语法(Scheme的define结合了变量和函数的定义,但是可以定义一个类吗?)
【讨论】:
lambda不定义了一个函数,它只创建了一个函数。 define 用于所有定义。是的,“Scheme”没有类,但实际上在所有 Scheme 类系统(几乎所有实现都有一些 OO 系统)中,define 也用于定义类,只是碰巧在定义评估为一个类。
Clojure 中的def 是一种特殊形式,保持特殊形式尽可能简单和原始是很好的。 defn 是一个宏,它添加了糖以轻松设置文档字符串和元数据,并且(正如其他人所说)消除了对无关括号的需要。 defn 还会自动在您的函数本身上设置一些元数据(显示 arglist 等),这对于一般的 def 来说毫无意义。
到目前为止,函数是您将要在 Clojure 中定义顶层的最常见的东西。不鼓励顶级可变变量。因此,有一种简单快捷的方法来定义顶级函数是有意义的。对所有内容使用def 会产生大量样板文件。如果没有defn,我们都会自己重新发明它以避免被气死。
【讨论】: