目的/使用程序采取任意数量的论点?

时间:2013-10-12 21:33:32

标签: lambda scheme

在类(方案)中,我们最近了解了允许函数采用任意数量参数的语法,例如;

(define len
  (lambda args
    (length args)))

>(len 1 2 3)
3

使用此表单而不是首先将参数作为单个列表传递有什么好处?你如何在程序中(而不是在命令行上)将参数传递给这些类型的函数?有没有办法制作一个返回一系列未包含在列表中的值的过程?

3 个答案:

答案 0 :(得分:1)

可变函数

一个非常有用的例子是

(define (list . elements) elements)
; or
(define list (lambda elements elements))

Variadic函数对于自然 n -ary函数的函数也很方便。例如,如果您已经有二进制加法函数add2,则可以执行

(define + (lambda addends (foldl add2 0 addends)))
; or
(define (+ . addends) (foldl add2 0 addends))

除了称之为

之外
(+ 1 2 3)
;=> 6

当您已在列表中包含参数时,也可以使用apply

(apply + '(1 2 3))
;=> 6

这样做的一个优点是可以更容易地编写使用不同参数约定的函数。我不知道这在Scheme中是否特别常见,但您可以使用它来获取关键字/命名参数。例如,而不是定义

(define (subseq lst start end) ...)

你总是必须提供开始和结束参数,你可以做

(define (subseq lst . args) ...)

因此lst始终是必需的,但是args可以包含或不包含start和end参数。您可以使用它来实现默认值。例如,

(subseq lst 'start 3 'end 6) ; specify both expllicitly
(subseq lst 'end 6)          ; default value for start, e.g., 0
(subseq lst 'start 4)        ; default value of end, e.g., length of list
(subseq lst)                 ; default for both, copy the list

您必须编写代码来提取指定值或默认值,但这并不太难。

多个值

对于返回多个值,您可以使用恰当命名的values

返回多个值
(values 1 2 3)
;=> 1
;=> 2
;=> 3

但这与采用任意数量参数的函数无关,因为它们与列表相关联,而values实际上与列表无关。

答案 1 :(得分:0)

是的,您可以使用values过程返回多个值,并且可以使用apply将任意参数传递给过程。但是你的课程可能还没有教过这些概念。 : - )

答案 2 :(得分:0)

假设您有以下两个'len'函数:

(define len1
  (lambda args (length args)))

(define len2
  (lambda (lst) (length lst)))

您可以将它们调用为:

> (len1 1 2 3)
3
> (len2 (list 1 2 3)
3

正如您所看到的,没有太大区别。在len2的情况下,您创建了列表;在len1的情况下,编译器创建了列表。可以说编译器可以更有效率。

让我们假设您已经有一个列表,你想要的长度。对于这两个你使用:

> (define l '(1 2 3))
> (apply len1 l)
3
> (len2 l)
3
; note
> (len1 l)
1

apply函数为其第二个参数获取一个列表,并将列表元素“呈现”为其第一个参数的参数(在本例中为len1)。

如果您不想返回列表但想要返回多个值,则使用values作为

(define my-return-3-values-function
  (lambda (a b c)
    (values a b c)))