我开始学习clojure。主要来自Java和一些脚本语言,作为clojure(以及所有函数式语言,我认为)的数据部分的代码并不那么清楚。
从书的第一页开始,我看到了表格。而且我看到它主要与数据相关联,例如#{1 2}
.但在其他地方,我看到Boolean
被贴上了form
的标签。
现在,我假设false
是Boolean
型的一种形式,但我没有看到type
被提及超过几次,所以我很困惑。
有人可以推动我理解表单的概念,并推动我能够将代码理解为语言的数据部分吗?
Clojure 之所以有形式,是因为它是一个 Lisp。
- Clojure表单是作为 一个程序。
- Clojure和其他Lisps在这个意义上有形式。
- 除了Lisps之外,大多数编程语言都没有:结构 用于编写程序结构与本机数据完全不同 结构。
- 函数式语言也不例外。例如,查看 ML 家族。
评估规则告诉您表单的工作原理。
- 使用本机数据结构来表达程序的回报 结构是你可以编写几乎可以操作表单的程序 就像您可以编写任何其他类型一样容易。
- 此类程序称为宏。
例如,查看and
的来源。你不能在Java中做到这一点。
这回答了你对 Lisps 的一般问题。
clojure表单是数据还是类型?
-数据
Clojure表单是一段被视为数据的代码。
Clojure形式具有化学性质。元素是这样的
- 数字 (
42
,3.1416
,22/7
) - 字符串 (
"1, 2, buckle my shoe."
) - 符号(
a5
,freds-white-teeth
),无论它们表示什么。
分子是这样的
- 表达式 (
(+ 1 1)
,(reduce * (range 1 n))
) - 参数列表 (
[f coll]
,[[forename surname :as name]]
)
唯一用于将分子形式结合在一起的结构是Clojure自己的数据结构。这就是代码即数据的含义。
Clojure用途
- 表达式列表;
- 参数列表(以及一般的绑定形式)的向量;
-
(关联绑定形式的映射)。
(暂时保留这些)。
在顶层,我们通常有def
和defn
表单。这些可以有很多层深。
def
是一种特殊形式。它有自己的评估规则。defn
看起来像一种特殊形式,但事实并非如此。
因为 Clojure程序是作为 Clojure 数据编写的,所以我们可以编写以下函数:
- 以形式为论据和
- 返回表单结果。
拼图的最后一部分是Clojure提供了一种特殊的功能模式,称为宏,即
- 将其参数作为形式进行操作
- 将调用表单转换为表单结果。
事实证明,这是一种强大的机制。例如,defn
是将fn
窗体包装在def
窗体中的宏。 一个便宜而欢快的类似物是
(defmacro my-defn [name & args-and-body]
(list 'def name (cons 'fn (cons name args-and-body))))
真正的defn
要复杂得多。但这一个足以应付
(my-defn twice [n] (* 2 n))
(twice 3)
;6
我们可以通过做看到发生了什么
(macroexpand '(my-defn twice [n] (* 2 n)))
;(def twice (fn twice [n] (* 2 n)))
我们甚至可以定义递归函数:
(my-defn fact [n]
(if (pos? n)
(* n (fact (dec n)))
1))
(map fact (range 1 5))
;(1 2 6 24)
- 以上适用于任何 Lisp,而不仅仅是 Clojure。
- 其他 Lisp 仅使用列表来构建表单。
- 没有其他重要语言将代码作为数据属性。
- 函数式语言也不例外:ML家族(ML,OCaml, 哈斯克尔, F#, ...具有相当传统的语法。