SICP/Scheme中的apply函数

The apply function in SICP/Scheme

我在这里问了几个关于 Scheme/SICP 的问题,答案经常涉及使用 apply 过程,我在 SICP 和本书的索引中都没有看到,它只列出了一次,结果是一个脚注。

一些用法的例子基本上是这个问题的每一个答案:.

我对 apply 的工作原理很感兴趣,我想知道是否有一些示例可用。怎么把apply过程重写成另一个函数,比如把map改写成这样?

#lang sicp

(define (map func sequence)
    (if (null? sequence) nil
        (cons (func (car sequence)) (map func (cdr sequence)))))

似乎它只是用第一个参数进行函数调用?类似于:

(apply list '(1 2 3 4 5)) ; --> (list 1 2 3 4 5)
(apply + '(1 2 3))        ; --> (+ 1 2 3)

所以在 Python 中可能有类似的内容?

>>> args=[1,2,3]
>>> func='max'
>>> getattr(__builtins__, func)(*args)
3

apply 用于调用具有动态数量参数的函数。

您的 map 函数只允许您调用仅接受一个参数的函数。您可以使用 apply 使用可变数量的列表来映射具有不同数量参数的函数。

(define (map func . sequences)
  (if (null? (car sequences))
      '()
      (cons (apply func (map car sequences))
            (apply map func (map cdr sequences)))))

(map + '(1 2 3) '(4 5 6))
;; Output: (5 7 9)

您要求查看 apply 如何编码,而不是如何使用它。

#lang sicp

; (define (appl f xs)    ; #lang racket
;   (eval 
;     (cons f (map (lambda (x) (list 'quote x)) xs))))

(define (appl f xs)      ; #lang r5rs, sicp
  (eval
    (cons f (map (lambda (x) (list 'quote x)) 
                 xs))
    (null-environment 5)))

#lang sicp 下的 Racket 中试用:

> (display (appl list '(1 2 3 4 5)))
(1 2 3 4 5)

> (display (     list   1 2 3 4 5 ))
(1 2 3 4 5)

> (appl + (list (+ 1 2) 3))
6

> (     +       (+ 1 2) 3 )
6

> (display (appl map (cons list '((1 2 3)  (10 20 30)))))
((1 10) (2 20) (3 30))

> (display (     map       list  '(1 2 3) '(10 20 30)  ))
((1 10) (2 20) (3 30))

这是关于 eval 的 link 文档。

它需要一个 environment 作为第二个参数,所以我们为它提供 (null-environment 5) 只是 returns 一个空的环境,它看起来像。我们实际上不需要任何环境,因为此时已经完成了参数的评估。