如何解决此错误“在定义之前引用标识符:with”

时间:2012-07-10 11:40:01

标签: scheme racket plai

我正在学习“编程语言:应用程序和解释”,我可以在执行#lang plai后在DrRacket 5.2.1中运行前两章的示例。但是当我输入第3章的第一个例子如下:

(with (x 5) (+ x x))

我收到以下错误:

reference to an identifier before its definition: with

我在本书中没有找到with的定义。我需要一个图书馆吗?

3 个答案:

答案 0 :(得分:4)

with构造不是您在自己的程序中使用的东西 - 它是您定义的语言中存在的东西。换句话说,它是你实现的东西,而不是你使用的东西。请注意,这些书总是使用花括号{with {x ...} ...}来表示它,这是为了避免您所拥有的这种混乱 - 花括号总是在您实现的语言中的代码中使用,并且圆括号用于您自己的实现代码。

请注意,在Racket中定义自己的with很简单,但这样做会错,并且可能会让您更加困惑。你应该只关注这本书,而不是试图在Racket中使用它,在第3章的最后你将有一个WAE语言的工作解释器 - 然后你就可以用它来运行WAE程序了使用with

作为旁注,如果您正在寻找与with类似的球拍表单,请查看let - 唯一的区别是let允许您指定多个绑定而不只是一个。

答案 1 :(得分:1)

(with (x a) <body>) is just a synonym for ((lambda x <body>) a)

如果您仍有问题,可以使用

解决此问题
((lambda x (+ x x)) 5)

答案 2 :(得分:0)

对不起,我昨天无法测试这些例子! 似乎还有错误, 我输入了第3章末尾的这些代码如下:

(define (parse sexp)
    (cond
      [(number? sexp) (num sexp)]
      [(list? sexp)
       (case (first sexp)
         [(+) (add (parse (second sexp))
                   (parse (third sexp)))]
         [(-) (sub (parse (second sexp))
                   (parse (third sexp)))])]))

 (define-type WAE
    [num (n number?)]
    [add (lhs WAE?)(rhs WAE?)]
    [sub (lhs WAE?) (rhs WAE?)]
    [with (name symbol?) (named-expr WAE?)(body WAE?)]
    [id (name symbol?)])


(define (subst expr sub-id val)
       (type-case WAE expr
          [num (n) expr]
          [add (l r) (add (subst l sub-id val)
                  (subst r sub-id val))]
          [sub (l r) (sub (subst l sub-id val)
                  (subst r sub-id val))]
          [with (bound-id named-expr bound-body)
            (if (symbol=? bound-id sub-id)
                (with bound-id
                  (subst named-expr sub-id val)
                  bound-body)
                (with bound-id
                  (subst named-expr sub-id val)
                  (subst bound-body sub-id val)))]
          [id (v) (if (symbol=? v sub-id) val expr)]))


(define (calc expr)
    (type-case WAE expr
      [num (n) n]
      [add (l r) (+ (calc l) (calc r))]
      [sub (l r) (- (calc l) (calc r))]
      [with (bound-id named-expr bound-body)
            (calc (subst bound-body
                         bound-id
                         (num (calc named-expr))))]
           [id (v) (error 'calc "free identifier")]))

然后,我在第21页测试'with',如下所示

(calc(解析'{with {x {+ 5 5}} {+ x x}}))

我收到了错误:


"type-case: expected a value from type WAE, got: #"

原因是需要更新的解析,我从谷歌获得了关于第3章的一些片段,例如,在CS 345 Progamming Languages中,其解析的定义如下:

(define parse
  (lambda (sexp)
    (cond
      [(number? sexp) (num sexp)]
      [(symbol? sexp) (id sexp)]
      [(list? sexp)
       (case (first sexp)
         [(+)(add (parse (second sexp))
                  (parse (third sexp)))]
         [(-) (sub (parse (second sexp))
                   (parse (third sexp)))]
         [(with) (with (first (second sexp))
                       (parse (second (second sexp)))
                       (parse (third sexp)))]
         )])))

最后,我得到了一个正确的结果:

(calc(解析'{with {x {+ 5 5}} {+ x x}}))=&gt; 20