我对这门语言非常陌生,我遇到了一个问题。希望有人能帮帮我。谢谢。
基本上,我想定义一个高阶函数make-adder。这是我的代码。
(define (make-adder num)
(define (foo x)
(+ x num)))
(define adder (make-adder 5))
(adder 8) ;error points to here但是,我想知道为什么我会收到这个错误消息。
# Error: expected
# 4
# but got
# Traceback (most recent call last):
# ...
# SchemeError: str is not callable: foo我使用的另一个解释器也给了我一个错误,但以不同的方式
Traceback (most recent call last)
0 (adder 8) [frame = Global]
Unable to pass parameters into the Symbol 'foo'首先,我想知道为什么我不能像在Python语言中那样使用这段代码来定义make-adder高阶函数。
其次,我假设define过程表达式返回的是一个字符串?(因为它显示为str foo is not callable)但当我尝试测试它时
scm> (define (foo x) (+ 1 x))
foo
scm> (string? (define (foo x) (+ 1 x)))
#f所以它不是一个字符串。我真的很困惑。foo在这里代表什么?它是一个字符串还是别的什么?为什么我不能从它呼叫?
希望有谁能帮我。谢谢。
发布于 2021-03-04 19:41:09
从其他答案中看不清楚的是,(define ...)不是一个表达式:它是一个定义:一种特殊的语法,它只能出现在语言允许的特定位置。因此,它根本没有值,因为它不能出现在允许表达式的任何地方。
来自R6RS
定义不是表达式,并且不能出现在可能出现表达式的所有位置。此外,定义没有价值。
R5RS对此不是很清楚,但他说(这是第5章):
方案程序由一系列表达式、定义和语法定义组成。..。定义在允许表达式的某些(但不是所有)上下文中是有效的。它们只在的顶层和开头有效。
R7Rs说了类似的话。
这特别意味着定义不能在需要表达式的地方自由使用:你不能说
(let ((x (define y 2)))
...)例如:这根本不是合法的方案。
特别是,你永远不能有一个定义,它的价值(或缺乏价值)可以意味着任何东西。这样做的一个后果是,我认为你的程序可能不是合法的。
这是不合法的,因为lambda的语法类似于:
(lambda <formals> <body>)
<body>在哪里
‘由零个或多个定义组成的序列,后跟一个或多个表达式。’
(我强调的是来自R7RS的文本。)
这意味着lambda表达式的主体至少应该有一个表达式:
(lambda ())不合法,因为它没有expressions;(lambda () (define x 1))也是非法的,因为它有一个定义,但仍然没有expressions;(lambda () (define x 1) x)是合法的,因为它有一个定义,一个expression;(lambda () 1)也是合法的(没有定义,一个expression).当然,实现可能允许(显然有时确实允许)等价于(lambda ())的表达式,但这些表达式不符合方案。
对于来自传统Lisp背景的人(像我)来说,Scheme中define的这个属性非常令人困惑,因为最接近的等价形式是表达式(仍然有一些奇怪的非表达式的东西,只能在某些地方使用,比如声明,但函数和变量定义不在其中)。
发布于 2021-03-04 03:42:05
这是一种象征。
#;1> (symbol? 'foo)
#t这样如何:
(define (make-adder num)
(define (foo x)
(+ x num))
foo)https://stackoverflow.com/questions/66463405
复制相似问题