I've started to learn Oz/Mozart recently, and for practice, I'm trying to write the code of a simple "For" procedure, that loops from "Init" to "End" values, and in each cycle print the current cycle number to the Browser. Here is the code:
This procedure creates a list from Init to End value:
declare
fun {Listing Init End}
if Init == End then
[Init]
else
Init|{Listing Init+1 End}
end
end
This do the loop and applies the function "F" in each cycle:
declare ForList
fun {ForList F L}
case L of H|T then
{F H}|{ForList F T}
else nil end
end
This wrap the above functions, so that can work receiving Init and End values, instead of a list:
declare MyFor L X in
proc {MyFor F Init End}
L = {Listing Init End}
X = {ForList F L}
end
Finally, I call MyFor:
{MyFor Browse 1 4}
When I try to compile, I get this error:
%*************** Error: illegal number of arguments *************
%**
%** In statement: {<P/1 Browse> 1 _<optimized>}
%** Expected: 1 argument
%** Found: 2 arguments
%**
%** Call Stack:
%** procedure 'ForList' in file "Oz", line 11, column 0, PC = 15793
(The line 11 is "fun {ForList F L}")
I've tried swaping "func" and "proc" in some of the subroutines to see if something changes, but I really don't know what I'm doing wrong.
ForList
expects a function that maps elements to a result. But Browse
is a procedure that does not return anything. ForList
should probably look more like this:
proc {ForList F L}
case L of H|T then
{F H}
{ForList F T}
else
skip
end
end
This is exactly the difference between the built-in function List.forAll
and List.map
.
BTW, in the definition of MyFor
you are using global variables X
and L
. This will cause problems when MyFor
is called more than once. You should use local variables instead. Like so:
proc {MyFor F Init End}
L X
in
L = {Listing Init End}
X = {ForList F L}
end