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

Reply via email to