EECS 395 Programming Languages: Homework 5

Due: Wednesday, February 3rd, 2010, 5pm

Part 1 – Shorthands

Add with to the parser for the FAE language, according to this rule:

{with {x FAE1} FAE2} =>
{{fun {x} FAE2} FAE1}

Add multiple argument functions to the parser for the FAE language, according to these rules:

{FAE1 FAE2 FAE3 FAE4 ...} =>
{{FAE1 FAE2} FAE3 FAE4 ....}

{fun {ID1 ID2 ID3 ...} FAE} =>
{fun {ID1} {fun {ID2 ID3 ...} FAE}}

The ellipses following a non-terminal above means that the rules apply with an arbitrary number of expressions in place of the non-terminal that appears just before the ellipsis. These are example uses of above rules:

{f x y z} => {{f x} y z} => {{{f x} y} z}

{fun {a b} {+ a b}} => {fun {a} {fun {b} {+ a b}}}

Nullary functions and application expressions with no arguments should both be syntax errors. Also note that these rules are intended to be schematic, not precise descriptions of how to implement your parser.

Part 2 – Conditionals, again

Add if0 to your interpreter with the same syntax as homework 4 but, unlike homework 4, you must be careful that the test position can be any value at all, not just a number. If the test position is a procedure, it is treated the same as any other non-0 value.

Part 3 – Errors

There are a three different kinds of errors that can occur (at runtime) in this language and for each error in the input program, your interpreter must signal an error that includes one of the following phrases:

free identifier
application expected procedure
numeric operation expected number

Part 4 – Pairs

The programming language you've implement has enough power to define a pairing operator (something like a simplified version of rec from homework 3.

Define a pair function that accept two arguments and returns a value. Define fst and snd functions that accept whatever pair produces and return the original arguments passed to pair. Note that pairs can be paired (not just numbers).

For example,

{with {pair ...}
  {with {fst ...}
    {with {snd ...}
      {fst {pair 1 2}}}}}
 => 1
Simlarly, with the appropriate with wrappers, you should get this:
{snd {pair 1 2}} => 2
{snd {fst {pair {pair 1 2} {pair 3 4}}}} => 2
{with {p {pair 1 2}}
  {+ {fst p} {snd p}}} => 3
{with {p {pair {fun {x} {+ x 1}} 2}}
  {{fst p} {snd p}}} => 3

Hint: there are only two choices of values that you might use to represent pairs, numbers and functions. While numbers are plentiful enough, a pair of functions is going to be difficult to turn into a number. So, if functions represent pairs, then consider what the function has to do to be able to act like a pair: it has to be able to return the first and the second pieces of the original pair.

Part 5 – Lists & summation

Once you have pairs, you can use them to build lists. Specifically, a list is either the number 0 (representing an empty list), or a pair of a number and another list. Use this data definition and build a summation function that takes one of these lists and returns the sum of the values in the list.

For example,

{with {pair ...}
  {with {fst ...}
    {with {snd ...}
      {with {sum ...}
        {sum 0}}}}}  => 0
and, again, with the same with expressions wrapped around these calls:
{sum {pair 1 0}} => 1
{sum {pair 1 {pair 2 {pair 3 0}}}} => 6

Part N – Handin instructions

The final program you handin should use this precise define-type definition for FAE.

(define-type FAE
  [num (n number?)]
  [add (lhs FAE?) (rhs FAE?)]
  [sub (lhs FAE?) (rhs FAE?)]
  [id (name symbol?)]
  [if0 (test FAE?) (then FAE?) (else FAE?)]
  [fun (param symbol?) (body FAE?)]
  [app (fun FAE?) (arg FAE?)])

Provide a definition of interp-expr : FAE -> number or 'procedure, as above.

Provide a definition of parse : sexpression -> FAE, as above.

Bind your definitions of pair, fst, snd, and sum to PLAI-level definitions of the same name, e.g.,

(define pair `{fun {x y} ...})
(define fst `{fun {p} ...})
(define snd `{fun {p} ...})
(define sum `{fun {l} ...})


Last update: Wednesday, January 27th, 2010
robby@eecs.northwestern.edu