TL;DR:你需要在操作符处有一个程序:
(+ 1 (length (cdr list))) ; notice the vital space between the symbol + and the number 1
更长的解释:
Scheme 评估运算符,例如。全局变量+ 计算为一个过程对象,该对象将其参数与括号一起添加,例如。 (+ a b) 评估变量 +、a 和 b,然后在 + 后面应用预期的过程对象。
1 和 +1 都是正数正数的文字。您可以在所有正数前面加上+,解析器不会做任何不同的事情。
因此,表达式(+1 (length (cdr list))) 将+1 评估为正数,将(length (cdr list)) 评估为0(因为一个元素列表是第一个被评估的应用程序),但是当Scheme 尝试应用它时它将失败因为数字不是程序。
在 Racket 中,您会收到正确的错误消息:
; application: not a procedure;
; expected a procedure that can be applied to arguments
; given: 1
1这里是因为解析器看到了+1,把它变成了数字1,但是错误永远看不到这个数字在源代码中是怎么写的。有很多方法可以写一个特定的数字,但它只会以一种方式显示数字。
1+ 和 1- 在 Common Lisp 中是完美且定义良好的函数,它们递增或递减参数,它们在 Scheme 中没有定义。你可以:
(define (1+ v)
(+ v 1))
(define (1- v)
(- v 1))
;; test
(1+ 4) ; ==> 5
(1- 4) ; ==> 3
在 Racket 中,它们由不同的名称定义:
(add1 4) ; ==> 5
(sub1 4) ; ==> 3
其他事情
不要使用#lang scheme。 Racket 曾经是 R5RS Scheme 的超集,但现在已经不是了。 #lang scheme 仍然只是 #lang racket 的同义词,它不再与 Scheme 语言兼容,你不能保证它在未来的 Racket 版本中也能正常工作。如果您更愿意使用标准 Scheme,请使用 #lang racket 而不是 #!r5rs、#!r6rs 或 #!r7rs。