3

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

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

我收到以下错误:

reference to an identifier before its definition: with

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

4

3 回答 3

4

构造with不是您在自己的程序中使用的东西——它是存在于您定义的语言中的东西。换句话说,它是你实现的东西,而不是你使用的东西。请注意,书籍总是将它与花括号一起使用,{with {x ...} ...}这是为了避免您遇到的这种确切的混淆——花括号始终用于您实现的语言的代码中,圆括号用于您自己的实现的代码。

请注意,在 Racket 中定义自己的with内容很简单,但这是错误的,并且可能会让您更加困惑。与其尝试在 Racket 中使用它,不如按照本书进行操作,在第 3 章结束时,您将拥有一个适用于 WAE 语言的解释器——然后您将能够使用它来运行 WAE 程序使用with.

附带说明一下,如果您正在寻找与 类似的 Racket 表单,with请查看let- 唯一的区别是它let允许您指定多个绑定,而不仅仅是一个。

于 2012-07-10T12:04:52.570 回答
1
(with (x a) <body>) is just a synonym for ((lambda x <body>) a)

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

((lambda x (+ x x)) 5)
于 2013-03-12T22:00:58.500 回答
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 (parse '{with {x {+ 5 5}} {+ xx}}))

我得到了错误:


"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 (parse '{with {x {+ 5 5}} {+ xx}}) ) => 20

于 2012-07-13T04:02:49.790 回答