首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scheme `fine`表达式返回什么?

Scheme `fine`表达式返回什么?
EN

Stack Overflow用户
提问于 2021-03-04 03:10:46
回答 4查看 126关注 0票数 1

我对这门语言非常陌生,我遇到了一个问题。希望有人能帮帮我。谢谢。

基本上,我想定义一个高阶函数make-adder。这是我的代码。

代码语言:javascript
复制
(define (make-adder num)
  (define (foo x)
    (+ x num)))

(define adder (make-adder 5))

(adder 8) ;error points to here

但是,我想知道为什么我会收到这个错误消息。

代码语言:javascript
复制
# Error: expected
#     4
# but got
#     Traceback (most recent call last):
#       ...
#     SchemeError: str is not callable: foo

我使用的另一个解释器也给了我一个错误,但以不同的方式

代码语言:javascript
复制
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)但当我尝试测试它时

代码语言:javascript
复制
scm> (define (foo x) (+ 1 x))
foo
scm> (string? (define (foo x) (+ 1 x)))
#f

所以它不是一个字符串。我真的很困惑。foo在这里代表什么?它是一个字符串还是别的什么?为什么我不能从它呼叫?

希望有谁能帮我。谢谢。

EN

回答 4

Stack Overflow用户

发布于 2021-03-04 19:41:09

从其他答案中看不清楚的是,(define ...)不是一个表达式:它是一个定义:一种特殊的语法,它只能出现在语言允许的特定位置。因此,它根本没有值,因为它不能出现在允许表达式的任何地方。

来自R6RS

定义不是表达式,并且不能出现在可能出现表达式的所有位置。此外,定义没有价值。

R5RS对此不是很清楚,但他说(这是第5章):

方案程序由一系列表达式、定义和语法定义组成。..。定义在允许表达式的某些(但不是所有)上下文中是有效的。它们只在的顶层和开头有效。

R7Rs说了类似的话。

这特别意味着定义不能在需要表达式的地方自由使用:你不能说

代码语言:javascript
复制
(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的这个属性非常令人困惑,因为最接近的等价形式是表达式(仍然有一些奇怪的非表达式的东西,只能在某些地方使用,比如声明,但函数和变量定义不在其中)。

票数 4
EN

Stack Overflow用户

发布于 2021-03-04 03:42:05

这是一种象征。

代码语言:javascript
复制
#;1> (symbol? 'foo)
#t

这样如何:

代码语言:javascript
复制
(define (make-adder num)
  (define (foo x)
    (+ x num))
  foo)
票数 1
EN

Stack Overflow用户

发布于 2021-03-04 03:44:24

应返回匿名函数(lambda):

代码语言:javascript
复制
(define (make-adder num)
  (lambda (x) (+ num x)))

(define adder (make-adder 5))
(adder 8)

(define (foo x) (+ 1 x))返回的值取决于开发环境(例如,DrRacket不返回任何内容),因为define没有返回值。您的集成开发环境可能返回symbol (尝试谓词symbol?)或仅返回函数名。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66463405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档