Scheme Eval不在球拍中工作

Scheme Eval不在球拍中工作,scheme,racket,Scheme,Racket,我正在使用以下修改自的代码以及atom-from的定义来拥有中缀算术解算器: (define atom? (or/c number? symbol? boolean? string?)) (define (solve expression) (define templist '()) (println expression) (if (atom? expression) expression (begin (set! templist (l

我正在使用以下修改自的代码以及atom-from的定义来拥有中缀算术解算器:

(define atom? (or/c number? symbol? boolean? string?)) 

(define (solve expression)
  (define templist '())
  (println expression)
  (if (atom? expression)
      expression
      (begin
        (set! templist (list (second expression)
                             (solve (first expression))
                             (solve (third expression))  ))
        (println templist)
        (eval templist) ) ) )

(solve '(3 + 2))
结果如下:

'(3 + 2)
3
2
'(+ 3 2)
+: unbound identifier;
 also, no #%app syntax transformer is bound in: +
因此,圣殿骑士的创建是正确的(+32),但在评估级别有错误。为什么“+”被视为“未绑定标识符”?eval函数在DrRacket中的命令行上运行良好:

> (eval '(+ 3 2))
5

问题在哪里?如何解决?谢谢。

您没有从前面问题的答案中学到什么吗?不要使用
set,这不是好的方案/球拍风格。这在这里尤其令人震惊,因为它完全没有做任何事情;取出并使用
let
(或者
local
,或者
block
,如果您愿意,可以使用内部定义)

除此之外,eval也同样邪恶,你在这里不需要它。功能是一流的;在符号和函数之间创建一个映射,然后使用该映射获取要调用的相关函数

(define (operator->procedure op)
  (case op
    [(+) +]
    [(-) -]
    [(*) *]
    [(/) /]
    [else (error 'operator->procedure "unknown operator ~v" op)]))

(define (solve expression)
  (if (atom? expression)
      expression
      ((operator->procedure (second expression))
       (solve (first expression))
       (solve (third expression)))))
更清楚的是,你可以使用Racket的模式匹配表,
match

(define (solve expression)
  (match expression
    [(? atom) expression]
    [(list a op b)
     ((operator->procedure op) (solve a) (solve b))]))

我用过一套!和templast只调试代码,否则只有“eval(list(secondexpression)…”是必需的。为什么设置了呢!如果语言中根本不使用它,那就有了它吗?谢谢你给出了一个很好的解释。@rnso也许吧,但是你的
设置!
在那里什么都做不了。即使是你的原始代码,你也可以使用一个本地绑定。我想说的是,在你对Scheme/Racket非常满意之前,永远不要使用
设置。甚至不用于调试。假装它不存在。@rnso
set!
对于在Scheme中实现一些低级构造很有用,但它在大多数用户代码中并不有用。通常可以完全避免变异,如果您真的真的希望某些东西是可变的,可以使用方框(但是我也会避免这些,除非你100%确定你需要它们)。谢谢你的解释。上面的代码对(3+2)这样的表达式很有效,但对(3+2+1)则不适用因为只对前3个元素进行了评估。有什么简单的解决方案吗?@rnso这是一个单独的问题,所以我不会在这里回答,但我认为这是你可以自己解决的问题。试试看,如果你真的陷入困境,问另一个问题。