在Luke VanderHart& Sons的Pratical Clojure的第19页中。 Stuart Sierra,第2章,有一段,
第一个问题,这里的表格字是拼写错误吗?这个词不是项目吗?如果没有, def 是表单吗?这意味着,此代码包含3个表单。 :-s
原因是稍后,当写作解释一个例子时,他使用了项目。
(def message "Hello, World!")
* 第二个问题,只有当列表的第一项是< strong>只预定了Clojure ?如果是,那么是否可以创建自定义特殊表格?那么自定义复合形式是否会被称为特殊形式?因为根据定义,我的自定义不是clojure内置的东西,而是在其他地方定义。
修改 我想我的第一个问题的答案是否定的,这不是一个错字。 def 是一种形式。
原因后来就写了,
这意味着,(println消息)&gt;整个事情是一个形式,它所拥有的其他东西(函数参数)也是一种形式。
但是,作者在开始时说,形式有四种基本形式。
根据书中符号的定义,它不是符号。
符号定义符号是解析为值的表单。它们可能被认为与变量大致相似,尽管这在技术上并不准确,因为它们实际上并不像大多数语言中的变量那样变化。在Clojure中,符号用于标识函数参数以及全局或本地定义的值。以下各节将更详细地讨论符号及其分辨率。原因,写入def并按回车键会产生以下错误消息,
在哪个类别中, def 属于?
答案 0 :(得分:3)
def是一种特殊形式。要了解原因,请考虑如果它是一个函数,您将如何评估def表达式。当您输入类似(square(* x y))的表达式时,您可以先评估子表达式(* x y),然后将square应用于任何值。这不是def所发生的事情,并且有充分的理由,如果你启动一个REPL你可以看到:
> (def a 1)
#'user/a
> (def a 2)
...
接下来会发生什么?如果def是正常函数,则REPL将评估a,然后尝试将def应用于参数1和2:也就是说,它将尝试重新定义1.但是,您可能期望做的是定义符号“ a“评估为2(在此过程中破坏旧符号)。为了从def和一些其他内置过程中获得所需的行为,如果将其作为函数进行求值,这些特殊形式将被编译到解释器中或实现为宏。
答案 1 :(得分:2)
我写了那一章。绝对可以写得更好,但我会尝试清理它:
回答你的第一个问题:是的,表格是正确的单词。单个符号(如def
)仍然是一种形式,因为形式只是可以评估的任何形式。我有时会说“项目”,但这只是一个更通用的词我用来指出列表中的“事物”。从技术上讲,如果它是用Clojure代码编写的并且可以进行评估,那么它就是一种形式。
对于你的第二个问题,不,复合形式是由其他形式构建的任何东西。例如,如果我定义它:
(defn sq [x] (* x x))
然后调用它,
(sq 3) => 9
表达式(sq 3)
是一个由两个其他形式组成的复合形式,第一个是符号sq
,它将对您的函数进行评估,第二个是文字3
。
术语“复合形式”不是一个正式的定义或任何东西,它只是我能想到的最简单的方式来表达形式可以用其他形式构建的事实。无论我想把3
放在哪里,它都是放置x
的有效语法,无论我放在哪里x
我都可以放(f x)
- 因为它们都只是形式。< / p>
为了回答你的最后一个问题,def
是一个对编译器有特殊意义的符号,因此在本书中使用的术语中,它是一种特殊的形式。
答案 2 :(得分:1)
第一个问题:
是的 - 在这种情况下,我认为“特殊形式的第一项”会更加明确。但由于符号本身就是一种形式,因此将其称为“特殊形式的第一种形式”在技术上也是正确的。
请注意,特殊情况中的第一项本身有时也称为特殊形式,如“def是一种特殊形式”。我认为这里的术语存在一些混淆,但只要你理解了一种特殊形式的概念,那么通常很明显是什么意思。一般来说,如果你认为“特殊形式”是指整个表格,那么你就是正确的。
question on the definition of a Lisp form在这里非常有帮助。
第二个问题
是 - 仅在第一个符号是Clojure中预定义的特殊形式符号之一时才存在特殊形式。有关有用的列表,请参阅http://clojure.org/special_forms。
您目前无法定义自己的特殊表单 - 尽管可以通过宏或函数为所有实际目标实现类似的结果,因此它永远不会成为问题。