Lisp中的所有数据都是不可变的吗?

时间:2012-04-17 05:11:38

标签: lisp

this article中,作者赞扬了具有两个主要优点的函数式编程。 但他没有提到(Common)Lisp。

Lisp的数据是否符合“所有数据都是不可变的”?

3 个答案:

答案 0 :(得分:7)

在Common Lisp中,默认情况下所有数据(例如原始变量引用,列表,数组和散列表)都是可变的,因此没有什么可以阻止某人更改变量的值,序列的元素或者结构领域。

但是,如果我们不是在谈论原始数据类型而是关于用户定义的数据,那就是关于CLOS结构和类,它们的插槽可以是只读的。例如,对于结构:

(defstruct person
  (name nil :type string :read-only t)
  (age nil :type (integer 0 100)))

(let ((john (make-person :name "John" :age 30)))
  (princ john)
  ;; * `age' is mutable:
  (incf (person-age john))
  (princ john)
  ;; * `name' is not:
  ;; (setf (person-name john) "garbage name")
  ;; ^ you can't do this because the `defstruct' macro just don't emit SETFer
  ;;   for the `name' slot as you made it read-only.
  )

类为插槽提供了更多的访问控制(这类似于C中const限定符的机制,区别在于Common Lisp中它不是编译时保证,而是一个例外,可以在重启时处理),你可以给他们读写,只读,只写或不访问。


有关详细信息,请参阅以下链接:

答案 1 :(得分:6)

在Common Lisp中,您可以选择使用功能样式。避免使用setfsetq等,并且您拥有函数式编程语言。换句话说,不要更改任何变量值,不要在创建后更改复合数据结构(缺点,向量,结构等)的内容。函数接受输入并产生输出而不修改状态。

因此,虽然Common Lisp提供了必要的操作,但如果您不想这样做,则不需要使用它们。

答案 2 :(得分:0)

没有。 Common Lisp中的数据不是不可变的。

使用setf函数

在SBCL中看到
* (setf x 0)
0
* x
0
* (setf x 1)
1
* x
1