Reputation: 2084
I am studying "Programming Languages: Application and Interpretation" and I can run the first two chapters' examples in DrRacket 5.2.1 after executing #lang plai
. but when I typed the 3rd chapter's first example as below:
(with (x 5) (+ x x))
I got the following error:
reference to an identifier before its definition: with
I did not find the definition of with
in this book. Do I need a library?
Upvotes: 3
Views: 1991
Reputation: 310
(with (x a) <body>) is just a synonym for ((lambda x <body>) a)
If you still have problem with that you can solve this by using
((lambda x (+ x x)) 5)
Upvotes: 1
Reputation: 2084
I am so sorry I could not test these examples yesterday! it seems that there are still error, I typed these codes of the end of chapter 3 as follows:
(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")]))
and then, I test 'with' as below in page 21
(calc (parse '{with {x {+ 5 5}} {+ x x}}))
I got the error:
"type-case: expected a value from type WAE, got: #"
the reason for this is that a updated parse is needed,I got some snippets from google about chapter 3, for example, in CS 345 Progamming Languages, its parse's definition is as follows:
(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)))]
)])))
finally, I got a right result:
(calc (parse '{with {x {+ 5 5}} {+ x x}}) ) => 20
Upvotes: 0
Reputation: 29556
The with
construct is not something that you use in your own programs -- it's something that exists in the language that you define instead. In other words, it's something that you implement not something that you use. Note that the books always uses it with curly braces, {with {x ...} ...}
, and that's intended to avoid this exact confusion that you're having -- curly braces are always used in code that is in the language you implement, and round parentheses are used for your own implementation's code.
Note that defining your own with
is simple in Racket, but it would be wrong, and is likely to get you more confused. Instead of trying to use it in Racket, you should just follow the book, and at the end of chapter 3 you will have a working interpreter for the WAE language -- and then you'll be able to use it to run WAE programs that use with
.
As a side note, if you're looking for a Racket form that is similar to with
, then look into let
-- the only difference is that let
allows you to specify multiple bindings instead of just one.
Upvotes: 4