Dear Craig,
Here are some answers for you.
Craig Ugoretz wrote:
1.
* _Free and bound identifiers_. Consider the following statement:
*
proc {P X}
if X>0 then {P X-1} end
end
*
Is the second occurence of the identifier P free or bound? Justify your
answer. Hint: this is easy to answer if you first translate to kernel
syntax.
/
The kernel syntax for the above code is as follows:
*
*/P/ /= proc {$ X}
local P in
local T in
T = (X > 0)
if T then P = proc {$ X-1} end
end
end
/
There's several problems in your translation. First, you seem to
confuse the procedure call {P X-1} with a procedure declaration. The
"proc" you've added inside the procedure body is wrong. Second, nothing
indicates that P should be declared inside the procedure body, there is
no declaration of P there.
Here is a correct translation:
P = proc {$ X}
local T in
T = X>0
if T then
local Y in
Y=X-1
{P Y}
end
else
skip
end
end
end
With this, you can now revise your conclusion. P is declared outside
the procedure definition, it is therefore a free identifier...
The second occurence of the parameter P is bound. The P in the inner
statement is declared by a local statement that is inserted into
the code upon translation to the kernel syntax. Because the P is
declared as a local variable, it is added to the environment and its value
is placed on the store, making it executable.
/*
2.
* _Contextual environment_. Section 2.4 explains how a procedure call is
executed. Consider the following procedure MulByN:*
declare MulByN in
N = 3
proc {MulByN X ?Y}
Y=N*X
end
*
together with the call {MulByN A B}. Assume that the environment at the
call contains {A->10, B->x1}. When the procedure body is
executed, the mapping N->3 is added to the environment. Why is this a
necessary step? In particular, would not N->3 already exist
somewhere in the environment at the call? Would not this be enough to
insure that the identifier N already maps to 3? Give an example
where N does not exist in the environment at the call. Then give an
example where N does exist there, but is bound to a different value
than 3.
/
Before the procedure application the kernel semantics looks like:
/*
( [ ( { MulByN A B}, {A->a, B->x1, N->n, MulyByN->m} ) ], { m = ( proc
{$ X Y} Y=N*X ) end, {N->n} ), a=10, b, n=3 } )
*/
After the procedure application the kernel semantics looks like:
/*
( [ ( Y = N*X, {X->a, Y->x1, N->n} ) ], { m = ( proc {$ A B} Y=N*X ) , {
N->n } ), a = 10, b, n = 3 } )
*/
Correct.
Although the mapping N->n exists in the environment and the mapping n=3
exists in the store before the procedure application, it is
necessary to have mapping N->n in the procedure value to identify the
contextual environment such that the external reference can be
mapped to the formal parameters of MulByN. In another case, there could
be other mappings in the environment that do not factor into
the procedure application, and we do not want to get them confused with
MulyByN's formal parameters.
Here is an example where N does not exist in the environment at the time
of the call:
/*
declare MulByN in
proc {MulByN X ?Y}
Y=N*X
end
*/
Well, this example is not correct, since N is not defined at the
declaration. Therefore the procedure value m below is not valid...
Before the procedure application the kernel semantics looks like:
/*( [ ( { MulByN A B}, {A->a, B->x1, MulByN->m} ) ], { m = ( proc {$ X Y
} Y=N*X ) end }, a=10, b } )*
/
The procedure application is suspended because the contextual
environment for N is missing.
Here is an example where N exists at the time of the call, but is bound
to a different value than 3.
/*
declare MulByN in
N = 3
proc {MulByN X ?Y}
Y=N*X
end
local N in
N = 5
{MulByN A B}
end
*/
This other example is correct, and your semantic analysis of it is perfect:
Before the procedure application, the kernel semantics looks like:
/*( [ ( { MulByN A B}, {A->a, B->x1, N->n', MulyByN->m} ) ], { m = (
proc {$ X Y} Y=N*X ) end, {N->n} ), a=10, b, n=3, n'=5 } )* /
After the procedure application the kernel semantics looks like:
/*( [ ( Y = N*X, {X->a, Y->x1, N->n} ) ], { m = ( proc {$ A B} Y=N*X ) ,
{ N->n } ), a=10, b, n=3, n'=5 } )*
/This is the other case mentioned above. The variable N is mapped to the
value n', yet the procedure application changes this mapping /
/back to the value n because this was the value mapped to by the
contextual environment./
Cheers,
raph
_________________________________________________________________________________
mozart-users mailing list
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users