In class, we implemented mutation (set expressions) using Scheme boxes. Scheme boxes provide a form of assignment operator. Thus, we used assignment in the implementation language to add assignment to our new language. What if you had to implement set expressions in a language that doesn't have assignment operators? (such languages do exist!)
Implement an interpreter for (at least) FAE! from the mutation notes (ie, the language with at least num, id, add, set, with (via the parser), fun and app) with eager evaluation and static scoping. Use environments. Your implementation may not use any Scheme assignment operator (such as boxes, set!, any operator with ! in its name, etc). You will be penalized for any violations of the spirit of this assignment, so don't expend energy trying to find what you think are loopholes. Examples of loopholes would be hash-tables (which use state in their implementations) and foreign function calls to functions with state in other languages. You don't need any fancy mechanisms beyond what you've already programmed with in the course.
You may start with either your own latest interpreter or the one from the class notes. If your own interpreter still isn't running, start with the one from the notes. If your own interpreter is working fine, build set into that (so you can experiment with the richer language you've implemented so far).
Think hard about this for a while. If you're still stuck after a couple of days (not hours!), here's a small hint or two.
Side note: In general, if you want to know what answer your mutating interpreter should yield on a particular program, you can run the corresponding program in Scheme that replaces set with set! with with let, and fun with lambda. Scheme follows the same semantics for assignment that we defined for set.