无法对 Racket 中的用户输入使用 eval
Unable to use eval on user input in Racket
我目前正在学习 Scheme(使用 Racket),但我面临的挑战之一是尝试执行以下代码,这意味着使用 [=11 从用户输入执行 Racket 代码=]:
(display (eval (read)))
这是我目前观察到的一些奇怪行为:
定义 window 中的 (display (eval (read)))
提示键盘输入,正如预期的那样,当定义为 运行 时。但是,提供输入
((lambda (x) (+ x 1)) 1)
给出错误
?: function application is not allowed;
no #%app syntax transformer is bound in: ((lambda (x) (+ x 1)) 1)
另一方面,使用(display ((eval (read)) 1))
并提供输入
(lambda (x) (+ x 1))
returns 错误
lambda: unbound identifier;
also, no #%app syntax transformer is bound in: lambda
- 但是,运行宁
(display (eval (read)))
并在控制台窗格中提供 ((lambda (x) (+ x 1)) 1)
,而不是定义窗格,按预期打印出 2
。
这种行为的原因是什么?
您似乎没有设置命名空间。如果您在文件中 运行 (eval (read))
,则它不起作用,因为默认情况下 current-namespace
设置为空命名空间。您可以通过先执行 (current-namespace (make-base-namespace))
来设置带有 racket/base
的命名空间:
#lang racket
(current-namespace (make-base-namespace))
(println (eval (read)))
运行 这个程序并给它输入 ((lambda (x) (+ x 1)) 1)
结果它打印 2
.
它在交互 window(您的怪异行为列表的第 3 项)中起作用的原因是在交互 window 中,current-namespace
参数设置为文件的命名空间。
主程序的定义 window 不是这样,因此您必须自己设置 current-namespace
,或者将命名空间作为第二个参数传递给 eval
:
#lang racket
(define ns (make-base-namespace))
(println (eval (read) ns))
Racket 软件包同时支持 R5RS 和 R6RS,并且可能会支持 R7RS。该软件在其自己的 Racket 语言家族中也有几种非标准语言,这些语言与 Scheme 有很多共同点,但 不是 Scheme。亚历克斯已经为该语言做出了很好的回答,所以我虽然我会添加有关 Scheme 的信息,因为你写你正在学习 Scheme,这与学习 Racket 不同,当涉及到一些极端情况时,包括 eval
.
eval
是一个程序,自从它在 R5RS 中成为强制性的以来,它在不同的 Scheme 报告之间发生了重大变化。以下是来自不同版本标准的一些示例:
#!r6rs
(import (rnrs)
(rnrs eval))
(display (eval '((lambda (x) (+ x 1)) 1)
(environment '(rnrs))))
; ==> undefined, prints 2
稍旧但仍被普遍使用的R5RS:
#!r5rs
(display (eval '((lambda (x) (+ x 1)) 1)
(scheme-report-environment 5)))
; ==> undefined, prints 2
目前只有小版本的R7RS即将上市:
#!r7rs
(import (scheme)
(scheme eval))
(display (eval '((lambda (x) (+ x 1)) 1)
(environment '(scheme))))
; ==> undefined, prints 2
我目前正在学习 Scheme(使用 Racket),但我面临的挑战之一是尝试执行以下代码,这意味着使用 [=11 从用户输入执行 Racket 代码=]:
(display (eval (read)))
这是我目前观察到的一些奇怪行为:
-
定义 window 中的
(display (eval (read)))
提示键盘输入,正如预期的那样,当定义为 运行 时。但是,提供输入
((lambda (x) (+ x 1)) 1)
给出错误
?: function application is not allowed; no #%app syntax transformer is bound in: ((lambda (x) (+ x 1)) 1)
另一方面,使用
(display ((eval (read)) 1))
并提供输入
(lambda (x) (+ x 1))
returns 错误
lambda: unbound identifier; also, no #%app syntax transformer is bound in: lambda
- 但是,运行宁
(display (eval (read)))
并在控制台窗格中提供((lambda (x) (+ x 1)) 1)
,而不是定义窗格,按预期打印出2
。
这种行为的原因是什么?
您似乎没有设置命名空间。如果您在文件中 运行 (eval (read))
,则它不起作用,因为默认情况下 current-namespace
设置为空命名空间。您可以通过先执行 (current-namespace (make-base-namespace))
来设置带有 racket/base
的命名空间:
#lang racket
(current-namespace (make-base-namespace))
(println (eval (read)))
运行 这个程序并给它输入 ((lambda (x) (+ x 1)) 1)
结果它打印 2
.
它在交互 window(您的怪异行为列表的第 3 项)中起作用的原因是在交互 window 中,current-namespace
参数设置为文件的命名空间。
主程序的定义 window 不是这样,因此您必须自己设置 current-namespace
,或者将命名空间作为第二个参数传递给 eval
:
#lang racket
(define ns (make-base-namespace))
(println (eval (read) ns))
Racket 软件包同时支持 R5RS 和 R6RS,并且可能会支持 R7RS。该软件在其自己的 Racket 语言家族中也有几种非标准语言,这些语言与 Scheme 有很多共同点,但 不是 Scheme。亚历克斯已经为该语言做出了很好的回答,所以我虽然我会添加有关 Scheme 的信息,因为你写你正在学习 Scheme,这与学习 Racket 不同,当涉及到一些极端情况时,包括 eval
.
eval
是一个程序,自从它在 R5RS 中成为强制性的以来,它在不同的 Scheme 报告之间发生了重大变化。以下是来自不同版本标准的一些示例:
#!r6rs
(import (rnrs)
(rnrs eval))
(display (eval '((lambda (x) (+ x 1)) 1)
(environment '(rnrs))))
; ==> undefined, prints 2
稍旧但仍被普遍使用的R5RS:
#!r5rs
(display (eval '((lambda (x) (+ x 1)) 1)
(scheme-report-environment 5)))
; ==> undefined, prints 2
目前只有小版本的R7RS即将上市:
#!r7rs
(import (scheme)
(scheme eval))
(display (eval '((lambda (x) (+ x 1)) 1)
(environment '(scheme))))
; ==> undefined, prints 2