Git Product home page Git Product logo

eopl3's Introduction

This is all the code from the book Essentials of Programming Languages, 3rd edition, by Friedman and Wand.

The code dates from 2009. It has now been updated and should run right out of the box on Racket version 6.11.

To run any of the languages, select "Choose language from source", and run top.scm in any of the language directories (chapterN/*-lang).

The file test-all.rkt will go through and test all of the testable languages.

If you are feeling adventurous, you can try to adapt the code base to use the rackunit testing framework instead of the kludgy one I threw together for the book.

Enjoy!

--Mitch

eopl3's People

Contributors

calvis avatar mwand avatar simonh1000 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eopl3's Issues

Errata for Page 341 and 362

Hi, Mitch

From page 341

(define apply-method
  (lambda (m self args)
    (cases method m
      (a-method (vars body super-name field-names)
                (value-of body
                          (extend-env* vars (map newref args)
                                       (extend-env-with-self-and-super
                                        self super-name
                                        (extend-env field-names (object->fields self) ; <---- should be extend-env*
                                                    (empty-env)))))))))

From page 362, line -2 of the display

It then goes through each class or instance declaration

"instance " should be "interface"

Regards,
chansey97

fact/k registerized has wrong fact1-cont?

Hi, Mitch

In the page 195, the fact/k registerized figure 6.1, it shows the fact1-cont as below:

(define apply-cont
  (lambda ()
    (cases continuation cont
      (end-cont () val)
      (fact1-cont (saved-n saved-cont)
        (begin
          (set! cont saved-cont)
          (set! n saved-n)
          (apply-cont))))))

The fact1-cont continuation should change the register val as below:

(fact1-cont (saved-n saved-cont)
        (begin
          (set! cont saved-cont)
          (set! val (* val saved-n))  ;; changed here
          (apply-cont)))

So that we can have correct val register in the final end-cont.
Is that correct?

Errata for Page 303

Hi, Mitch

From page 303

(define-datatype type-environment type-environment?
  (empty-tenv)
  (extend-tenv ...as before...)
  (extend-tenv-with-module ...as before...)
  (extend-tenv-with-type
   (name type?)  ; <----- this should be (name symbol?)
   (type type?)
   (saved-tenv type-environment?)))

The code on GitHub is correct, but errata is not updated.

Regards,
chansey97

Errata for Exercise 2.19

Hi Mitch,

AFAIK, this hasn't been reported yet so here goes. On page 44 of the textbook, we're instructed to implement move-to-left-son and move-to-right-son, but the example immediately following calls them simply move-to-left and move-to-right, respectively.

I'm currently working through the text and coding every exercise with rackunit tests. As a token of my appreciation for co-authoring such an excellent text, I'd be quite happy to share any and all of my code for you to use however you please. Perhaps the unit tests will come in handy or something.

Don't know how to setup

Apologies but I have no idea how to view the content. I don't know what a .rkt or .scm file is. Can someone guide me on what to do after cloning the repo?

Maybe an erratum on page 116

On figure 4.6 of page 116, probably the return type of procedure value-of should be Answer instead of ExpVal?

exercise 7.28 example code

The example code of map in Page 273 is shown below:

let
  ? map (f : ?) =
         letrec
            ? foo (x : ?) = if null?(x)
                                  then emptylist
                                  else cons((f car(x)),
                                                  ((foo f) cdr(x)))
         in foo
in letrec
        ? even (y : ?) = if zero?(y)
                                 then zero?(0)
                                 else if zero?(-(y, 1))
                                         then zero?(1)
                                         else (even -(y, 2))
    in pair(((map proc(x : int) -(x, 1))
                 cons(3, cons(5, emptylist))),
                ((map even)
                  cons(3, cons(5, emptylist))))

I think (foo f) is wrong, since f is a procedure, however foo wants a list. It should just be foo instead of (foo f).

Another problem is the syntactic sugar let func(x) = .... It seems that the textbook has not mentioned this syntax.

one-armed if's

There are quite a few one-armed if's floating around the code. These are primarily used for tracing, and most, if not all, should be replaced by "when".

There may be a few one-armed if's that should not be when's-- eg in chapter2/utils.scm (already fixed).

exercise 2.20 (page 45) minor fix

exercise 2.20 on page 45 asks you to reimplement the procedures form exercise 2.19 as well as move-up, at-root? and at-leaf?

However exercise 2.19 already includes at-leaf?, so this can be removed from exercise 2.20.

Possible erratum for exercise 2.25

Hi Mitch,

I think I may have found another erratum. This time in exercise 2.25 on page 50. The exercise for max-interior gives some test cases. The last of these is

(max-interior tree-3) ;; => baz

and goes on to say that 'foo is also acceptable as an answer. However, would 'bar not be an acceptable answer? In fact, I submit that it is a better answer than 'baz since that is the key assigned to the interior-node that is the root node, tree-3. In which case, it tells us nothing since either the left child (interior-node bar)or right child (leaf-node 1) might have the greater sum.

Sorry if that's a bit tough to follow. In short, I believe the correct answer should be 'bar and not 'baz for this exercise, while 'foo remains valid.

Here (only) you can see my implementation where I've highlighted the relevant cond clause: https://github.com/christianromney/eopl3/blob/9c6be1f609492449fcd0fd5bffc8d89e12b8921a/src/ch02/bintree/datatype.rkt#L55-57

You can also see my test case, again highlighted with the relevant test:
https://github.com/christianromney/eopl3/blob/9c6be1f609492449fcd0fd5bffc8d89e12b8921a/test/ch02/bintree.rkt#L125-127

Again, it is this test case which I submit should be changed to accept 'bar.

Regards,
Christian Romney

An erratum on page 226

About the code of exercise 6.34 in page 226, I think it should be

(define fib/anf
  (lambda (n)
    (if (< n 2)
        n
        (let ((val1 (fib/anf (- n 1)))
              (val2 (fib/anf (- n 2))))
          (+ val1 val2)))))

instead of

(define fib/anf
  (lambda (n)
    (if (< n 2)
        1
        (let ((val1 (fib/anf (- n 1)))
              (val2 (fib/anf (- n 2))))
          (+ val1 val2)))))

Errata for Page 180

The third line from the end of page 180 says:

So the first two items, 300 and 205, are printed by the main thread.

But according to the program on page 181:

let buffer = 0
       in let producer = proc (n)
              letrec
                wait4(k) = if zero?(k)
                           then set buffer = n
                           else begin
                                  print(-(k,-200));
                                  (wait4 -(k,1))
                                end
                in (wait4 5)
          in let consumer = proc (d)
                  letrec busywait(k) = if zero?(buffer)
                                       then begin
                                             print(-(k,-100));
                                             (busywait -(k,-1))
                                            end
                                       else buffer
                  in (busywait 0)
              in begin
                  spawn(proc (d) (producer 44));
                  print(300);
                  (consumer 86)
                 end

205 is printed by subthread. So the text on page 180 might be:

So the first two items, 300 and 205, are printed by the main thread and the subthread respectively.

SLLGEN cannot report error when input string is illegal.

Run chapter6/cps-lang/cps-in-lang.scm in DrRacket and attempt to parse the following string:

(just-scan "(foo 123abc)")

;; ((literal-string51 "(" 1)
;;  (identifier foo 1)
;;  (number 123 1)
;;  (identifier abc 1)
;;  (literal-string51 ")" 1))

(scan&parse "(foo 123abc)")

;; #(struct:a-program
;;   #(struct:call-exp
;;     #(struct:var-exp foo)
;;     (#(struct:const-exp 123) #(struct:var-exp abc))))

Notice that the input program has a syntax error, i.e.123abc is neither a number nor an identifier.

The expected behavior is to report a error, but SLLGEN give the wrong AST, which has no syntax error.

That means we cannot detect this error by traverse the AST in the subsequent pass.

My current workaround is to add a new Regexp-and-action in the-lexical-spec.

It makes 123abc a legal identifier:

(define the-lexical-spec
  '((whitespace (whitespace) skip)
    (comment ("%" (arbno (not #\newline))) skip)
    (identifier
     (letter (arbno (or letter digit "_" "-" "?")))
     symbol)
    (identifier ;; <----- new `Regexp-and-action`
     (digit (arbno digit) (or letter "_" "-" "?") (arbno (or letter digit "_" "-" "?")))
     symbol)
    (number (digit (arbno digit)) number)
    (number ("-" digit (arbno digit)) number)
    ))

But this seems not a good way.

Can SLLGEN report error when scanning the input characters.

Thanks.

A type error in example code ?

Hi Mitch,
At page 290, ex8.5,

Allow let and letrec declarations to be used in module bodies.
For example, one should be able to write

     module even-odd
       interface
        [even : int -> bool
         odd  : int -> bool]
       body letrec
        bool local-odd (x : int) = ... (local-even -(x,1)) ...
        bool local-even (x : int) = ... (local-odd -(x,1)) ... 
         in [even = local-even
            odd  = local-odd]

I think the interface should be written as:

    interface [ even : (int -> bool)
                 odd : (int -> bool)]

since we have proc-type in grammar.

Incorrect code sample in exercise 7.28

I think the code sample should be fixed as follow:

- let
+ letrec
   ? map (f : ?) =
      letrec
       ? foo (x : ?) = if null?(x)
                       then emptylist
                       else cons((f car(x)),
-                                ((foo f) cdr(x)))
+                                ((map f) cdr(x)))
      in foo
  in letrec
      ? even (y : ?) = if zero?(y)
                       then zero?(0)
                       else if zero?(-(y,1))
                            then zero?(1)
                            else (even -(y,2))
     in pair(((map proc(x : int)-(x,1))
             cons(3,cons(5,emptylist))),
             ((map even)
              cons(3,cons(5,emptylist))))

The specifications for deref-exp and setref-exp are not quite correct

See page 109.

I'll just explain the issue with the deref-exp specification since the issue is the same for the setref-exp specification.

Take (value-of exp ρ σ_0) = (l, σ_1). l is an ExpVal. This means to get the reference we have to do (expval->ref l). The specification as written doesn't do that.

Suggestion 1:

      (value-of exp ρ σ_0) = ((ref-val l), σ_1)
---------------------------------------------------------------
(value-of (deref-exp exp) ρ σ_0) = (σ_1(l), σ_1)

Suggestion 2:

                  (value-of exp ρ σ_0) = (val, σ_1)
------------------------------------------------------------------------------------
(value-of (deref-exp exp) ρ σ_0) = (σ_1((expval->ref val)), σ_1)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.