在函数式编程中,我们倾向于区分数据和函数,但它们有什么区别呢?
如果我考虑一个常量,我可以把它看作一个函数,它只是返回相同的值:
(def x 5)
那么数据和函数之间的区别是什么呢?我看不出有什么区别。
数据
数据是一个值(具有特定类型)。
例如,
5
为Integer
类型的值,"abc"
为String
类型的值。组合值如[5 "abc"]
的类型为Vector
。相同类型的两个数据值总是可以比较是否相等.
数据从不执行。也就是说,控制线程(又名程序计数器或PC)永远不会进入数据结构。
函数(即"code")
函数的唯一类型是"code"
- 两个函数永远不相等,即使它们彼此是重复的。
函数产生当执行时的值(具有特定类型)(可能带参数)。
执行是指控制的线程输入代码数据结构。在这里遇到的代码和数据值可以完全控制发生的任何副作用,以及返回值。
编译和解释代码产生相同的结果。它们之间唯一的区别是在实现细节上权衡了复杂性和速度。
Eval
(eval ...)
特殊表单接受数据作为输入并返回函数作为输出。返回的函数可以被执行(即调用),这样控制线程就可以进入函数。为清楚起见,上面省略了阅读器等细节
宏最好被看作是编译器扩展嵌入到代码中,并且不影响数据与代码的区别。
h1>
<注:我突然想到原来的问题还没有得到充分的回答。考虑以下内容:
; A Clojure Var pointing to the value 5
(def five 5)
; A Clojure Var pointing to a function that always returns the value 5
(def ->five (fn [& args] 5))
,然后使用这两个变量:
five => 5
(->five) => 5
括号起了很大的作用。
参见:
- 勇敢Clojure
- LispCast
在具有同象性的语言中,代码即数据,数据即代码。这种代码数据的二元性模糊了代码和数据之间的区别。(我认为你的问题是关于lambda
和数据之间的区别-如果lambda
本身实际上也只是一个必须执行的数据结构…)
在同形符号语言中,数据可以变成lambda
(如果它包含lambda
的指令),反之亦然。
所以,区别可能仅仅在于它们的类型(函数与任何其他数据结构或基本数据类型)。