Syl*_*ter 6 scheme runtime-error racket
在执行我的代码期间,我在不同的Scheme实现中遇到以下错误:
球拍:
application: not a procedure;
expected a procedure that can be applied to arguments
given: '(1 2 3)
arguments...:
Run Code Online (Sandbox Code Playgroud)
的Ikarus:
Unhandled exception
Condition components:
1. &assertion
2. &who: apply
3. &message: "not a procedure"
4. &irritants: ((1 2 3))
Run Code Online (Sandbox Code Playgroud)
鸡:
Error: call of non-procedure: (1 2 3)
Run Code Online (Sandbox Code Playgroud)
开局:
*** ERROR IN (console)@2.1 -- Operator is not a PROCEDURE
((1 2 3) 4)
Run Code Online (Sandbox Code Playgroud)
MIT计划:
;The object (1 2 3) is not applicable.
;To continue, call RESTART with an option number:
; (RESTART 2) => Specify a procedure to use in its place.
; (RESTART 1) => Return to read-eval-print level 1.
Run Code Online (Sandbox Code Playgroud)
Chez Scheme:
Exception: attempt to apply non-procedure (1 2 3)
Type (debug) to enter the debugger.
Run Code Online (Sandbox Code Playgroud)
诡计:
ERROR: In procedure (1 2 3):
ERROR: Wrong type to apply: (1 2 3)
Run Code Online (Sandbox Code Playgroud)
赤壁:
ERROR in final-resumer: non procedure application: (1 2 3)
Run Code Online (Sandbox Code Playgroud)
Syl*_*ter 10
Scheme过程/函数调用如下所示:
(operator operand ...)
Run Code Online (Sandbox Code Playgroud)
运算符和操作数都可以是变量test,并且+可以计算不同的值.对于过程调用来说,它必须是一个过程.从错误消息看来,这可能test不是一个过程而是列表(1 2 3).
表单的所有部分也可以是表达式,因此类似于((proc1 4) 5)有效语法,并且期望调用(proc1 4)返回一个过程,然后使用5它作为唯一参数进行调用.
尝试对表达式进行分组或创建块
(if (< a b)
((proc1)
(proc2))
#f)
Run Code Online (Sandbox Code Playgroud)
当谓词/测试为真时,Scheme假定将尝试评估两者(proc1),(proc2)然后(proc1)由于括号将调用结果.要在Scheme中创建块,请使用begin:
(if (< a b)
(begin
(proc1)
(proc2))
#f)
Run Code Online (Sandbox Code Playgroud)
在这里(proc1)只是为了效果而调用,而形式的结果将是最后一个表达式的结果(proc2).
影子程序
(define (test list)
(list (cdr list) (car list)))
Run Code Online (Sandbox Code Playgroud)
这里调用list该参数,使得该过程list在调用期间不可用.一个变量只能是Scheme中的过程或不同的值,最接近的绑定是您在操作符和操作数位置获得的绑定.这将是普通lispers的一个典型错误,因为在CL中他们可以使用它list作为参数而不会弄乱函数list.
包装变量 cond
(define test #t) ; this might be result of a procedure
(cond
((< 5 4) result1)
((test) result2)
(else result3))
Run Code Online (Sandbox Code Playgroud)
虽然谓词表达式(< 5 4) (test)看起来是正确的,因为它是一个检查thurthness的值,它与该else术语有更多共同之处,并且应该像这样写:
(cond
((< 5 4) result1)
(test result2)
(else result3))
Run Code Online (Sandbox Code Playgroud)
应该返回过程的过程并不总是如此
由于Scheme不强制执行返回类型,因此您的过程可以在一种情况下返回一个过程,在另一种情况下返回非过程值.
(define (test v)
(if (> v 4)
(lambda (g) (* v g))
'(1 2 3)))
((test 5) 10) ; ==> 50
((test 4) 10) ; ERROR! application: not a procedure
Run Code Online (Sandbox Code Playgroud)
未定义值一样#<void>,#!void,#<undef>,和#<unspecified>
这些通常值通过突变形式返回一样set!,set-car!,set-cdr!,define.
(define (test x)
((set! f x) 5))
(test (lambda (x) (* x x)))
Run Code Online (Sandbox Code Playgroud)
这个代码的结果是不确定的,因为set!可以返回任何值,我知道一些方案实现,如MIT Scheme实际上返回绑定值或原始值,结果将是25或10,但在许多实现中,你得到一个常量值#<void>,因为它不是一个程序,你得到同样的错误.依赖于一种在规范下使用的实现方法,可以为您提供不可移植的代码.
以错误的顺序传递参数
想象一下,你有这样一个功能:
(define (double v f)
(f (f v)))
(double 10 (lambda (v) (* v v))) ; ==> 10000
Run Code Online (Sandbox Code Playgroud)
如果你错误地交换了参数:
(double (lambda (v) (* v v)) 10) ; ERROR: 10 is not a procedure
Run Code Online (Sandbox Code Playgroud)
在更高阶的函数中,例如fold并且map不以正确的顺序传递参数将产生类似的错误.
尝试像Algol派生语言一样申请
在algol语言中,如JavaScript和C++,当尝试fun使用参数时,arg它看起来像:
fun(arg)
Run Code Online (Sandbox Code Playgroud)
这被解释为Scheme中的两个独立表达式:
fun ; ==> valuates to a procedure object
(arg) ; ==> call arg with no arguments
Run Code Online (Sandbox Code Playgroud)
fun使用argas参数的正确方法是:
(fun arg)
Run Code Online (Sandbox Code Playgroud)
多余的括号
这是一般的"抓住所有"其他错误.类似的代码((+ 4 5))在Scheme中不起作用,因为此表达式中的每组括号都是过程调用.你根本无法添加任意多个,因此你需要保留它(+ 4 5).
操作员位置中的表达式以及允许将变量作为库函数调用可以为语言提供表达能力.这些是你习惯的时候会喜欢的功能.
这是一个例子abs:
(define (abs x)
((if (< x 0) - values) x))
Run Code Online (Sandbox Code Playgroud)
这在执行(- x)和(values x)(返回其参数的标识)之间切换,并且您可以看到它调用表达式的结果.以下是copy-list使用cps 的示例:
(define (copy-list lst)
(define (helper lst k)
(if (null? lst)
(k '())
(helper (cdr lst)
(lambda (res) (k (cons (car lst) res))))))
(helper lst values))
Run Code Online (Sandbox Code Playgroud)
请注意,这k是一个我们传递函数的变量,它被称为函数.如果我们传递的不是其他任何东西,那么你会得到同样的错误.
一点也不.所有具有一个可以将函数作为参数传递的命名空间的语言都会遇到类 以下是一些类似问题的JavaScript代码:
function double (f, v) {
return f(f(v));
}
double(v => v * v, 10); // ==> 10000
double(10, v => v * v);
; TypeError: f is not a function
; at double (repl:2:10)
// similar to having extra parentheses
function test (v) {
return v;
}
test(5)(6); // == TypeError: test(...) is not a function
// But it works if it's designed to return a function:
function test2 (v) {
return v2 => v2 + v;
}
test2(5)(6); // ==> 11
Run Code Online (Sandbox Code Playgroud)