Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/scheme/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Functional programming 在Scheme中,我如何理解;(定义(f x.y)(cons x y))“;_Functional Programming_Scheme_Lisp - Fatal编程技术网

Functional programming 在Scheme中,我如何理解;(定义(f x.y)(cons x y))“;

Functional programming 在Scheme中,我如何理解;(定义(f x.y)(cons x y))“;,functional-programming,scheme,lisp,Functional Programming,Scheme,Lisp,我不熟悉Scheme,这里我遇到了点列表的麻烦,下面是一个示例: (define (f x . y) (cons x y)) (定义(f x.y)(cons x y)) 当我输入:(f 1 2 3)时,结果是'(1 2 3)。是的,它返回一个列表,此时 x => 1 and y => '(2 3). x=>1和y=>”(23) 我的问题是,当f使用不固定长度的args时,解释器如何知道这一点呢?解释器知道f有一个名为x的参数,后跟参数列表y。因此,当它遇到对f的调用时,它会将第一

我不熟悉Scheme,这里我遇到了点列表的麻烦,下面是一个示例:

(define (f x . y) (cons x y))
(定义(f x.y)(cons x y))

当我输入:
(f 1 2 3)
时,结果是
'(1 2 3)
。是的,它返回一个列表,此时

x => 1 and y => '(2 3).
x=>1
y=>”(23)


我的问题是,当
f
使用不固定长度的args时,解释器如何知道这一点呢?

解释器知道
f
有一个名为
x
的参数,后跟参数列表
y
。因此,当它遇到对
f
的调用时,它会将第一个参数放入
x
,将剩余的参数放入
y

(f x.y)
语法意味着
定义的第一个参数是一个“不正确的”列表(相当于从
(cons'f(cons'x'y))得到的)
而不是来自
(cons'f(cons'x(cons'y nil)))
。因此,当调用函数时,每件事都会依次绑定。首先,x绑定到1,然后列表的其余部分绑定到Arment列表的尾部。因为此时,它是一个符号,所以y绑定到’(2 3).

在scheme中,形式参数前的点
表示 该过程将是一个列表,包含所有剩余参数。因此,正如您在帖子中正确显示的那样,
y
过程中是一个列表,
'(2 3)
。在
f
x中,将其视为正常参数

(define (f x . y)
 (display "y: ")
 (display y) (newline)) 

(f 1 2 'this 'is 'a 'list)
y: (2 this is a list)
以下是Guile参考手册对此的说明:

(variable1…variablen.variablen+1)

如果在最后一个变量之前有一个空格分隔的句点,则该过程将接受n个或>多个变量,其中n是句点之前的形式参数数。句点之前必须至少有一个参数。前n个实际参数将存储到前n个形式参数和序列的新分配位置欧洲 剩余的实际参数将转换为一个列表,并存储到最后一个正式参数的位置。如果正好有n个实际参数,则为空列表 存储到最后一个形式参数的位置

我不熟悉这个计划,这里我遇到了点列表的麻烦,这里是一个 例如:

(define (f x . y) (cons x y))
当我输入:(F123)结果是“(1233)。是的,它返回一个 列表,此时

x => 1 and y => '(2 3).
我的问题是,当f取时,口译员如何知道这一点 args的未固定长度

如果说
f
接受的参数数量不固定或任意,这是不正确的。它至少需要一个参数。如果您尝试调用
(f)
,您将得到一个错误。理解这里发生的事情的关键可能是理解Lisps中的虚线对表示法。它在另一个堆栈溢出问题中进行了讨论,但简短的版本是每个列表都是由对构建的。单个对可以写成
(car.cdr)
。例如,
(cons 1 2)=>(1.2)
。像
(1.2.3)
这样的列表实际上是一对,其
cdr
是另一对,其
cdr
是另一对,等等:
(1.(2.3.()
。因为这很难阅读,我们通常在编写一个对链时除去最后一个点以外的所有点,如果最后一个
cdr
()
,我们省略了点和
()
,所以

(1 . (2 . (3 . 4))  === (1 2 3 . 4)
(1 . (2 . (3 . ())) === (1 2 3)
请注意,虽然默认打印机不会以这种方式打印,但列表
(1 2 3 4)
也可以通过以下方式写入:

(1 . (2 3 4)) === (1 2 . (3 4)) === (1 2 3 . (4))
虽然它不会以这种方式打印,但您可以编写它,系统会理解它。例如

> '(1 2 . (3 4))
(1 2 3 4)
这可能是理解lambda列表表示法的关键。当我们为函数编写lambda列表时,它表示一个函数,并且lambda列表会根据参数进行解构。因此,如果我们有以下lambda列表并使用它们来解构参数列表
(1 2 3)
,我们会得到结果绑定:

lambda-list    x             y      z
-------------------------------------
(x y z)        1             2      3
(x y . z)      1             2    (3)
(x . y)        1         (2 3)    n/a
x              (1 2 3)     n/a    n/a
最后一种情况可能会令人惊讶,但您可以测试所有这些情况是否真的按预期工作:

((lambda (x y z)   (list x y z)) '(1 2 3)) => (1 2 3)
((lambda (x y . z) (list x y z)) '(1 2 3)) => (1 2 (3))
((lambda (x . y)   (list x y))   '(1 2 3)) => (1 (2 3))
((lambda x         (list x))     '(1 2 3)) => ((1 2 3))
最后一个有点简洁,因为这意味着如果它还不是语言的一部分,你可以:

(define (list . elements) elements)

解释器是否也知道args
1 2 3
将被解析为一个列表
'(1 2 3)
?@kedebug解释器知道
(cons 1'(2 3))
的计算结果为
'(1 2 3)
如果你是这么问的。很抱歉,我的意思是
f
需要
1 2 3
,它可以是三个参数,但是它被解析成一个列表
'(1 2 3)
。我很难理解这一点。@kedebug它没有被解析成
'(1 2 3)
。你用
(cons 1'(2 3))在过程的主体中创建这个列表
将其称为“点”比“句号”更合适。Cons单元格有时被称为“点对”。谢谢@ChrisJester Young它是固定的!谢谢,Joshua,你找到我了。你可以使用点符号来表示正确的列表('a.'))是一个正确的列表。cons单元格由两个指针组成。因此,在类似于So的参数列表中使用时,它是将
cdr
指针的内容绑定到一个值的一种方式,而不是依次绑定每个
car
的内容。