无法对 Racket 中的用户输入使用 eval

Unable to use eval on user input in Racket

我目前正在学习 Scheme(使用 Racket),但我面临的挑战之一是尝试执行以下代码,这意味着使用 [=11 从用户输入执行 Racket 代码=]:

(display (eval (read)))

这是我目前观察到的一些奇怪行为:

    定义 window 中的
  1. (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)

  2. 另一方面,使用(display ((eval (read)) 1))并提供输入
    (lambda (x) (+ x 1))

    returns 错误
    lambda: unbound identifier; also, no #%app syntax transformer is bound in: lambda

  3. 但是,运行宁 (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