University of Toronto - Winter
2007
Department of Computer Science
CSC 324:
Principles of Programming Languages
Assignment 4
Clarification Page
Communications
March 12: Recall that your assignment will be marked for correctness, style, and
documentation. Please consult the following
ML coding guideline.
Also recall that if your code does not pass the ML type-checker, you will
receive no marks for correctness.
Corrections or Clarifications
Question-Specific Clarifications
Question 1a
March 16 (Update to March 12 Clarification):
There have been a lot of questions about special cases for substitute, so I thought it
would be a good idea to post a lengthy, final clarification. All of the potential
problems arise when performing substitution inside of an Abs. Let's look at what might
go wrong. First, a bit of terminology. We call the expressions created with Abs
abstractions (hence the Abs). An abstraction is simply a function of one variable.
We say that the abstraction binds this variable in the body of
the abstraction, where the name of the bound variable is the first
argument to Abs and the body is the second argument to Abs. So, what
could go wrong with substitute? Let's look at some examples:
Case 1) The variable we are substituting by an expression occurs as the bound variable in an abstraction.
substitute("x", (Const 1) App(Abs("x", Plus(Var "x", Const 1)), (Const 3)))
The original expression represents (3 + 1), but if we perform substitution, we obtain the expression:
App(Abs("x", Plus(Const 1, Const 1)), (Const 3)))
which represents (1 + 1).
Case 2) The expression we are substituting for a variable contains a variable bound by an abstraction.
substitute("x", (Var "y"), App(Abs("y", Plus(Var "x", Var "y")), (Const 1)))
The original expression represents (x + 1), but if we perform substitution we obtain the expression:
App(Abs("y", Plus(Var "y", Var "y")), (Const 1))
which represents (1 + 1)
Case 3) The same variable is bound by several abstractions (this is not explicitly related to substitution, but is the same sort of problem):
App(Abs("y", App(Abs("y", Plus(Var "y", Var "y")), (Const 1))), (Const 2))
Does this represent (1 + 2) (1 + 1) (2 + 1) or (2 + 2)? It's hard to
say. Most programming languages (including scheme) use the most
recent binding, so all of the Var "y" expressions would be bound by
the inner abstraction, and we would have (1 + 1), but it could
theoretically be any of the above.
You should assume that none of these cases occur. Consider the ML
function substitute(n, e1, e2). We can represent this assumption as
its preconditions as:
- n is not bound by any abstraction in e2.
- No variable occuring in e1 is bound by an abstraction in e2.
- Abstractions in e2 have fresh variable names (No Name is bound than
one abstraction in e2 and no name bound by an abstraction occurs
outside the body of the abstraction).
There is probably a simpler single precondition that subsumes all of
these, but I feel that these are much clearer, as they point out all 3
problem cases. There are ways to deal with this problem rather than
ignoring it, of course. We could dynamically rename variables to
avoid problems 1) and 2), for instance. This is well beyond the scope
of this assignment, however.
IMPORTANT: Just because you can ignore these cases doesn't mean you
shouldn't state the above preconditions for substitute (and similarly
for eval in the case of precondition 3). You will lose marks if you
don't mention them (think of this as free marks for reading the
newsgroup and the clarifications page).
March 12: In the examples for substitute, all comments of the form:
(* Substitute every "x" in the expression Var "x" by Var "y" *)
Should read:
(* Substitute every Var "x" in the expression Var "x" by Var "y" *)
This is in accordance with the text immediately before the examples.
March 12: You should assume the following two preconditions for
substitute:
The name passed to substitute does not occur as the bound variable in any
abstraction in the last argument to substitute. That is, the first
argument of substitute should not occur as the first argument of any
Abs in a subexpression of the third argument of substitute.
All variables introduced by function abstraction are fresh. That is,
if an expression e contains subexpression of the form (Abs(n, e1)) then
(Var n) does not occur outside of e1.
Thus, the following example is not a valid uses of substitute (and
thus you don't need to worry about what happens in cases such as
this):
substitute("x", Var "y", Abs("x", Plus( Var "x", Var "z")))
Similarly, the following is not a valid expression (and you don't need
to worry about expressions such as this):
App(Abs("x", Plus(Var "x", Var, "z")), Mult(Var "x", Const 3))
Question 3
March 14 You do not have to implement the functions
and hand in the code. The only thing you have to hand in in the
file a4-3.sml is the type information that would be returned
from a correct implementation of the function specification. This
information is of course not legitimate sml code and if we
actually
loaded it, we would get all sorts of errors. (Naming the file with
an ".sml" extension is misleading in this regard.)
Back to the main page