Lisp中的值函数 [英] values function in Common Lisp

查看:94
本文介绍了Lisp中的值函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Common Lisp中的values函数是否只是语法糖,用于将多个值打包到一个被调用者解构的列表中?我之所以问是因为我认为Common Lisp支持真"多值返回,而不是像其他语言(如python)那样返回元组或列表.有人刚刚告诉我,这只是语法糖,所以我想请您解释一下.为了尝试理解values函数返回的类型,我键入了(type-of (values 1 2 3)),输出为BIT.我在Common Lisp参考中进行了搜索,但在数据类型部分中找不到该参考.另外,任何人都可以共享一些资源来建议如何在Common Lisp中实现值功能吗?谢谢.

Is the values function in Common Lisp just syntactic sugar for packaging multiple values into a list that gets destructured by the caller?. I am asking because I thought Common Lisp supports "true" multiple value return rather than returning a tuple or a list as in other languages, such as python. Someone just told me that it's just syntactic sugar, so I would like someone to kindly explain it. To try to understand the type that is returned by the values function, I typed (type-of (values 1 2 3)), and the output was BIT. I searched in the Common Lisp reference for that and I couldn't find it mentioned in the datatypes section. Also, can anyone share some resources that suggest how the values function is implemented in Common Lisp?. Thank you.

推荐答案

CL中的多个值

ANSI 标准 INCITS中描述了语言常见的口吻. 226-1994(R2004),并具有许多实现. 每个人都可以实现合适的多个值 , 他们当然可以为他们列出一份清单 (实际上, CL的Emacs Lisp兼容层仅- 但却有意,有意地并非 Common Lisp实现).

Multiple Values in CL

The language Common lisp is described in the ANSI standard INCITS 226-1994 (R2004) and has many implementations. Each can implement multiple values as it sees fit, and they are allowed, of course, to cons up a list for them (in fact, the Emacs Lisp compatibility layer for CL does just that - but it is, emphatically and intentionally, not a Common Lisp implementation).

但是,此功能的意图是允许在不经过同意的情况下(至少分配一些)多个值 (即,不分配

However, the intent of this facility is to enable passing (at least some) multiple values without consing (i.e., without allocating heap memory) and all CL implementations I know of do that. In this sense the multiple values facility is an optimization.

当然,对于不同的平台和方案,此功能的实现可能会非常不同.例如,前几个(例如, 20-标准所要求的)存储在静态的线程局部向量,接下来的几个(1000?)分配在堆栈上,其余的(如果需要)作为向量或列表分配在堆上.

Of course, the implementation of this feature can be very different for different platforms and scenarios. E.g., the first few (say, 20 - required by the standard) are stored in a static of thread-local vector, the next several (1000?) are allocated on the stack, and the rest (if needed) are allocated on the heap as a vector or list.

例如,函数 floor 返回两个值. 如果您写

E.g., the function floor returns two values. If you write

(setq a (floor 10 3))

您仅捕获第一个,而丢弃第二个,则需要编写

you capture only the first one and discard the second one, you need to write

(setf (values q r) (floor 10 3))

捕获两个值.这类似于其他语言可能表示为

to capture both values. This is similar to what other languages might express as

q,r = floor(10,3)

使用元组,除了CL不会将内存分配给传递(仅几个)多个值,其他语言经常这样做.

using tuples, except that CL does not allocate memory to pass (just a few) multiple values, and the other languages often do.

IOW,人们可以将多个值视为一种短暂的结构.

IOW, one can think of multiple values as an ephemeral struct.

请注意,CL可以将多个值转换为列表:

Note that CL can convert multiple values to lists:

(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确实具有多值对象"的特殊类型,正是因为它确实 not 分配了一个单独的对象来传递多个值.从这个意义上说,确实可以声称values是语法糖.

MV & type

CL does not have a special type for the "multiple value object" exactly because it does not allocate a separate object to pass around multiple values. In this sense one can, indeed, claim that values is syntactic sugar.

但是,在CL中,可以声明一个函数类型返回多个值:

However, in CL one can declare a function type returning multiple values:

(declaim (ftype (real &optional real) (values real real)) floor)

这意味着floor返回两个值,都为 real s(而不是返回类型为(values real real)的值),也就是说,在这种情况下,可能会要求滥用符号.

This means that floor returns two values, both reals (as opposed to returning a value of type (values real real)), i.e., in this case one might claim abuse of notation.

在您的特定情况下, type-of 是普通函数(即,宏或特殊运算符). 您将其传递给单个对象1,因为除非使用 multiple-value-bind ,朋友,只使用第一个值,所以

In your specific case, type-of is an ordinary function (i.e., not a macro or special operator). You pass it a single object, 1, because, unless you are using multiple-value-bind and friends, only the first value is used, so

(type-of (values 1 2 3))

等同于

(type-of 1)

,类型1为 bit .

and type of 1 is bit.

values 的一种用法是 控制函数的返回值. 通常,CL函数的返回值是最后一种形式的返回值. 有时是不理想的,例如最后一个表单返回倍数 值,并且您希望函数返回一个值(或不返回任何值,例如 void >):

One use of values is to control the return values of a function. Normally a CL function's return values are those of the last form. Sometimes it is not desirable, e.g., the last form return multiple values and you want your function to return one value (or none, like void in C):

(defun 2values (x y)
  (floor y x))
(defun 1value (x y)
  (values (floor y x)))
(defun no-values (x)
  (print x)
  (values))

这篇关于Lisp中的值函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆