Common Lisp 中的值函数只是语法糖,用于将多个值打包到一个列表中,该列表会被调用者解构吗?我问是因为我认为 Common Lisp 支持“真正的”多值返回,而不是像 python 等其他语言那样返回元组或列表。有人刚刚告诉我这只是语法糖,所以我希望有人好心解释一下。为了尝试理解 values 函数返回的类型,我输入了 (type-of (values 1 2 3))
,输出为 BIT
。我在 Common Lisp 引用资料中搜索了它,但在数据类型部分找不到它。另外,任何人都可以分享一些资源来建议如何在 Common Lisp 中实现值功能吗?。谢谢。
最佳答案
CL 中的多个值
语言 Common lisp 在 ANSI 标准 INCITS 226-1994 (R2004) 中进行了描述,并且有许多 实现。 每个都可以实现multiple values 在它认为合适的情况下,当然,他们可以为他们列一个 list (实际上,the Emacs Lisp compatibility layer for CL does just that - 但它是,强调和有意地,不是 Common Lisp 实现)。
目的
但是,此设施的目的是为了让通过(至少 一些)多个值 without cons (即,没有分配 heap内存)和所有CL 我知道的实现是这样做的。 从这个意义上说,多值设施是一种优化。
当然,此功能的实现可能因人而异 不同的平台和场景。例如,前几个(例如 20 - required by the standard )是 存储在线程局部向量的静态中,接下来的几个(1000?)是 分配在堆栈上,其余的(如果需要)分配在 堆作为向量或列表。
用法
例如,函数 floor
返回两个值。
如果你写
(setq a (floor 10 3))
你只捕获第一个并丢弃第二个,你需要 写
(setf (values q r) (floor 10 3))
捕获两个值。这类似于 other languages可能表示为
q,r = floor(10,3)
使用 tuples , 除了 CL 做 不分配内存来传递(仅几个)多个值,并且 其他语言通常也是如此。
IOW,可以将多个值视为一个临时结构。
请注意,CL 可以将多个值转换为列表:
(destructuring-bind (q r) (multiple-value-list (floor 10 3))
; use q & r here
...)
而不是更高效简洁
(multiple-value-bind (q r) (floor 10 3)
; use q & r here
...)
MV & 类型
CL 没有“多值对象”的特殊类型
正是因为它没有分配一个单独的对象来传递
围绕多个值。从这个意义上说,我们确实可以声称
values
是句法糖。
但是,在 CL 中可以 declare A function type返回 multiple values :
(declaim (ftype (real &optional real) (values real real)) floor)
这意味着 floor
返回两个值,两者
real
s(相对于返回
(values real real)
类型的值,即,在这种情况下,可能
声明滥用符号。
你的情况
在您的具体情况下,type-of
是普通函数(即不是宏或特殊运算符)。
您将单个对象 1 传递给它,因为除非您使用
multiple-value-bind
和
friend ,只使用第一个值,所以
(type-of (values 1 2 3))
等同于
(type-of 1)
1 的类型是 bit
.
PS: 控制返回值
一次使用values
是为了
控制函数的返回值。
通常 CL 函数的返回值是最后一种形式的返回值。
有时这是不可取的,例如,最后一个表格返回多个
values 并且你希望你的函数返回一个值(或者没有,
喜欢void
在 C
中:
(defun 2values (x y)
(floor y x))
(defun 1value (x y)
(values (floor y x)))
(defun no-values (x)
(print x)
(values))
关于lisp - Common Lisp 中的值函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22795608/