函数和数据有什么区别?

Dav*_*vid 4 functional-programming clojure

在函数式编程中,我们倾向于区分数据和函数,但有什么区别呢?

如果我考虑一个常量,我可以把它看作一个函数,它只返回相同的值:

(def x 5)
Run Code Online (Sandbox Code Playgroud)

那么数据和函数有什么区别呢?我看不出区别。

Ala*_*son 5

数据

  • 数据一个值(具有特定类型)。

    • 例如,5是 type 的值Integer,并且"abc"是 type 的值String。复合值,例如[5 "abc"]具有类型Vector

    • 始终可以比较相同类型的两个数据值是否相等

  • 数据永远不会被执行。也就是说,控制线程(又名程序计数器或 PC)永远不会进入数据结构。

函数(又名“代码”)

  • 函数的唯一类型是“代码”。

    • 两个函数永远不会相等,即使它们彼此重复。
  • 函数在执行时(可能带有参数)产生一个值(具有特定类型)。

    • 执行意味着控制线程进入代码数据结构。在那里遇到的代码和数据值可以完全控制发生的任何副作用以及返回值。

    • 这两个编译和解释的代码产生相同的结果。它们之间的唯一区别是在复杂性与速度之间进行权衡的实现细节。

评估

  • (eval ...)特殊形式接受数据作为输入,并返回一个函数作为输出。可以执行(即调用)返回的函数,以便控制线程进入该函数。

    • 为清楚起见,以上省略了阅读器等细节。

    • 最好被视为嵌入在代码中的编译器扩展,并且不会影响数据与代码的区别。


后记

我突然想到原来的问题还没有完全回答。考虑以下:

; 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))
Run Code Online (Sandbox Code Playgroud)

然后使用这两个变量:

; 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))
Run Code Online (Sandbox Code Playgroud)

括号使一切变得不同。

也可以看看:

  • _函数在执行时(可能带有参数)会产生一个值(具有特定类型)。_这至少是很方便的。FP 意义上的函数不会产生值。它是从输入到输出的不可变映射。 (2认同)