Homework #16: Slug Part 2
Out: ? Wednesday, April 12th, Due: ? Wednesday, April 19th, 11:00pm (master homework)


This homework is only required for master students. Undergrads can do it too, and you will be graded as usual — but you will not be able to withdraw a graded homework grade, so submit only if you think that your work is good enough to improve your grade. (Note: the homework grades are all weighted to compute your overall grade, so adding another grade means that you get smaller portions for more grades, which can serve as protection against local disasters.)

Note that while undergrads are not required to submit a solution, it will be a very good idea to read the homework and go through the solution when it is later posted — since you are expected to know the material.

This homework is a quick continuation of the previous one.

The language for this homework is:

#lang pl 16

Question #1

Why is macro expansion mixed with parsing?

(Note: you need an exact answer — this is not an essay question.)

Strong Hint: consider the following code:

{with-stx {fun {}
              {{fun x y}
                {+ x y}}}
  {fun 5 9}}

and think what would be needed to still make it work.

Question #2

It is nice to have with-stx in the language so that users can extend their own set of syntactic constructs. However, this is a difficult job, and we want to give them some pre-defined syntaxes. Do this by implementing a global-transformers which is provided as the initial argument to parse-sexpr. Populate this with a few useful syntax transformers, like the above do (you will need to write Racket code that generates the same transformer). Also, for fun, add a prog syntax that makes it possible to write definitions followed by a body expression — which is being translated to a sequence of nested bind expressions. It should be used like this:

{prog x := 1
      y := 2
      {foo n} := {+ n x}
      x := {+ x 1}
  {* x {foo y}}}

which evaluates to 6. A more complete example is writing code that looks like the above:

  {twice b} := {do {curval <- {unref b}}
                {set-ref! b {* 2 curval}}}
  {do {i <- {newref 1}}
      {twice i}
      {print 'i now holds: '}
      {v <- {unref i}}
      {print {number->string v}}
      {twice i}
      {print ', and now it holds: '}
      {v <- {unref i}}
      {print {number->string v}}
      {print '\n'}}}