“对象 square 不适用”,但 `square` 是 MIT-Scheme 中的一个内部过程

问题描述 投票:0回答:1

最近自学MIT 6.5151课程时,先看了CS 61AS Unit 0作为准备。然后我按照ps0的要求阅读了SICP 1到2.1(以及相关的讲义)(也按照CS 61A笔记的要求阅读了2.2.1),然后软件灵活性设计(SDF)序言,第1章和部分内容方案附录。

我使用 MIT-Scheme。

目前我正在阅读 SDF 第 2 章并做练习 2.5 (b)。

以下代码有奇怪的结果,抛出错误“;对象方块不适用。”和“;对象 (lambda (x) (square x)) 不适用。”。这里

func_polynomial_minimal_unit
在调用
(f(f(g(x)))
 时会计算类似 
(func_polynomial_minimal_unit '((f . 2) (g . 1)))

的内容
(define (compose f g)
  (define (the-composition . args)
    (call-with-values (lambda () (apply g args))
      f))
  the-composition)

(define (iterate n)
  (define (the-iterator f)
    (if (= n 0)
        identity
        (compose f ((iterate (- n 1)) f))))
  the-iterator)

(define (identity x) x)

(define (func_polynomial_minimal_unit . func_pow_pair_lst)
  (if (null? (car func_pow_pair_lst)) ; contain one null pair
    identity
    (let ((cur_func_pow (caar func_pow_pair_lst)))
      (newline)
      (display cur_func_pow)
      (compose 
        ((iterate (cdr cur_func_pow)) (car cur_func_pow)) 
        (func_polynomial_minimal_unit (cdr func_pow_pair_lst))))))

;; equivalent lambda for the following `func_polynomial_minimal_unit`.
((lambda (x) (expt (* x 9) (expt 2 3))) 3)
;; these works
((compose ((iterate 3) (lambda (x) (square x))) (lambda (x) (* 3 x))) 3)
((compose ((iterate 3) square) (lambda (x) (* 3 x))) 3)

;; these doesn't work
((func_polynomial_minimal_unit '((square . 3) ((lambda (x) (* 3 x)) . 2))) 3)
((func_polynomial_minimal_unit '(((lambda (x) (square x)) . 3) ((lambda (x) (* 3 x)) . 2))) 3)

但如上面的代码所示,这些过程是可以应用的。那么为什么会抛出这些错误呢?

function arguments scheme parameter-passing mit-scheme
1个回答
0
投票

符号和变量是不同的东西。代码中的裸符号是变量(或类似

let
的语法),引用列表中的相同符号只是与变量
square
或变量
a

无关的符号

当您编写像

(square a)
这样的代码时,Scheme 会计算运算符,即变量
square
。由于它评估一个过程,因此它评估变量
a
,然后将过程与评估的操作数一起应用。

现在,如果我要列出一个清单,例如。像

(define to-apply '(square a)))
一样应用,然后尝试打印这个
(display to-apply)
,你会看到与你写的完全相同的内容,因为你引用了它。 (apply (car to-apply) (cdr to-apply)) 将为您提供与您遇到的完全相同的错误消息,因为符号
square
不是一个过程。

但是,如果您将其定义为

(define to-apply (list square a)))
然后执行
(display to-apply)
,您会看到类似
(#<procedure-suqare> 3)
的内容,并且
(apply (car to-apply) (cdr to-apply))
会给您
9

© www.soinside.com 2019 - 2024. All rights reserved.