[Fwd: Mozart 1.2.3]
Denys Duchier
Denys.Duchier at ps.uni-sb.de
Tue Jun 18 14:56:40 CEST 2002
phiho.hoang at rogers.com (PhiHo Hoang) writes:
> I am still a bit dense here. I try to add 'in' in front of 'fun
> {BinaryTree T}', then I got:
>
> %********************** static analysis error *******************
> %**
> %** unification error in needed statement
> %**
> %** First value: <P/2 BinaryTree>
> %** Second value: <P/2>
> %** in file "Oz", line 6, column 6
> %** ------------------ rejected (1 error)
Oh hum!... No, that's not what you get! Executing the code below, in
a fresh session:
local
fun {AndThen BP1 BP2}
if {BP1} then {BP2}
else false end
end
in
fun {BinaryTree T}
case T
of nil then true
[] tree(K V T1 T2) then
{AndThen
fun {$} {BinaryTree T1} end
fun {$} {BinaryTree T2} end}
else false end
end
end
gives you the following exception:
%********************* binding analysis error *******************
%**
%** variable BinaryTree not introduced
%**
%** in file "Oz", line 7, column 8
%** ------------------ rejected (1 error)
for the obvious reason that variable BinaryTree has not been
introduced :-) My guess is that you executed your code in an
environment in which BinaryTree had already been defined, in which
case the code above attempted to unify it with the new procedure
created by the `fun' statement (hence the unification error).
Note that executing the `fun' statement always creates a new
procedure. Consider
declare
fun {NEW}
fun {Foo} skip end
in
Foo
end
It is always the case that {NEW}=={NEW} is _false_ because each
invocation creates a new procedure (a new name for an abstraction, if
you wish). Why is this so? (1) it is simplest to model, explain, and
implement. (2) it neatly side-steps the undecidability of equivalence
between abstractions.
[subnote: the drawback is that strict adherence to this model forbids
lambda lifting.]
> I guess I need to add 'declare' in front of ''fun {BinaryTree T}' as
> well, but it seems that was not expected:
>
> **** parse error ************************
> %**
> %** unexpected token `declare'
> %**
> %** in file "Oz", line 6, column 6
> %** ------------------ rejected (1 error)
Indeed, `declare' can only occur at top-level. You have three options:
1. declare BinaryTree then bind it in a statement:
declare BinaryTree in
local fun {AndThen ...} ... end
in fun {BinaryTree ...} ... end
2. take advantage of convenient syntax support (which I did not
mention in my previous message) to achieve the same effect:
declare
local fun {AndThen ...} ... end
in fun {BinaryTree ...} ... end
end
Here, we have again a statement occurring in the DECLARATIONS
section of `declare'. This statement is a `local' construct. For
convenience the STATEMENTS of the `local' construct occurring
withint the DECLARATIONS section of an enclosing `declare' or
`local' are processed according to the same `convenience' rules
that I described previously.
Thus, in the above, it is considered that the variable BinaryTree
is introduced by the `declare'. In summary, the code above has
essentially the effect of:
declare BinaryTree in
local AndThen in
fun {AndThen ...} ... end
fun {BinaryTree ...} ... end
end
3. you could also omit the `in' of the `declare', but in this case you
must somehow indicate that the 1st occurrence of BinaryTree in its
definition is not a declaring one. This is done using the prefix `!'
declare BinareTree
local fun {AndThen ...} ... end
in fun {!BinaryTree ...} ... end
end
I can't see why anyone (except a compiler) would want to do this
here, but the technique is occasionally useful, so I thought I'd
mention it.
Cheers,
--
Dr. Denys Duchier Denys.Duchier at ps.uni-sb.de
Forschungsbereich Programmiersysteme (Programming Systems Lab)
Universitaet des Saarlandes, Geb. 45 http://www.ps.uni-sb.de/~duchier
Postfach 15 11 50 Phone: +49 681 302 5618
66041 Saarbruecken, Germany Fax: +49 681 302 5615
-
Please send submissions to users at mozart-oz.org
and administriva mail to users-request at mozart-oz.org.
The Mozart Oz web site is at http://www.mozart-oz.org/.
More information about the mozart-users
mailing list