0

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.

Granjero
  • 340
  • 3
  • 13
  • 1
    Something is missing in your code. You don't seem to call `ForList` anywhere? – wmeyer Mar 18 '13 at 21:11
  • 1
    My guess is you are calling `ForList` without consuming its result. In Oz, the return value of a function is considered an argument, too. So it is obligatory to use it (with an assignment like `Res = {Function Arg1 Arg2}`). – wmeyer Mar 18 '13 at 22:19
  • Yes, sorry, I've edited now (the call to ForList is inside the declaration of MyFor). I've added the variable X to hold the return value of For List, but now I'm getting a similar error (I've put it in the edited message). I tried holding the return value also when I call MyFor, but that doesn't work neither, instead it gives me this error: %*************** Error: illegal number of arguments ********* %** In statement: {

    1 4 A} %** Expected: 3 arguments %** Found: 4 arguments

    – Granjero Mar 19 '13 at 02:42

1 Answers1

1

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
wmeyer
  • 3,426
  • 1
  • 18
  • 26
  • Thank you, it works now! So the problem was I was trying to "assign" the result of Browse to H|T. I'm a little confused about local variables though; I thought that by doing "declare foo MyFunc in fun {MyFunc arg1} end" I was already making foo a variable local to MyFunc (because of the keyword "in"), and that to declare it as global I just had to do "declare foo". Maybe they are 2 different ways to do the same? – Granjero Mar 19 '13 at 14:34