使用Mozart Oz中的相同代码,函数和过程的行为会有所不同吗?

时间:2011-04-29 09:16:17

标签: function procedure oz mozart

我尝试使用2种方法在Oz中打印Fibonacci序列:使用Emac作为编辑器的函数和过程。 程序在这里:

declare 
fun {Fibo N} 
   case N of 
      1 then 1 
   [] 2 then 1
[] M then {Fibo (M-1)} + {Fibo (M-2)} 
   end 
end 
declare
proc {Loop K}
   if K ==1 then  {Browse K}
   else
      {Loop K-1}
       {Browse {Fibo K}}
   end
end
{Loop 10}

和功能:

declare 
fun {Fibo N} 
   case N of 
      1 then 1 
   [] 2 then 1
[] M then {Fibo (M-1)} + {Fibo (M-2)} 
   end 
end
declare
fun {Loo L}
   if L ==1 then  {Browse L}
   else
      {Loo L-1}
       {Browse {Fibo L}}
   end
end
{Loo 10}

问题是唯一的程序“循环”有效。结果是:

1
1
2
3
5
8
13
21
34
55

功能“Loo”没有,它会引发一些难以理解的错误:

%********************** static analysis error *******************
%**
%** illegal arity in application
%**
%** Arity found:          1
%** Expected:             2
%** Application (names):  {Loo _}
%** Application (values): {<P/2> _<optimized>}
%** in file "Oz", line 13, column 6

%********************** static analysis error *******************
%**
%** illegal arity in application
%**
%** Arity found:          1
%** Expected:             2
%** Application (names):  {Loo _}
%** Application (values): {<P/2> 10}
%** in file "Oz", line 17, column 0
%** ------------------ rejected (2 errors)

我仍然不知道为什么。我认为功能和程序在OZ中具有类似的效果。

2 个答案:

答案 0 :(得分:6)

必须使用函数调用语法调用函数:

_ = {Loo 10}

或者使用附加参数来接收值:

{Loo 10 _}

_发音为“不关心”,表示不需要变量的值。

此外,函数必须通过将表达式作为每个分支的最后部分来返回值。因此,您的固定Loo函数将如下所示:

fun {Loo L}
   if L == 1 then
      {Browse L}
      unit
   else
      _ = {Loo L-1}
      {Browse {Fibo L}}
      unit
   end
end
_ = {Loo 10}

但是,如果没有任何有趣的东西可以返回,那么使用这样的循环函数没有多大意义。也许你真正想要的是build a list and return it as the result

答案 1 :(得分:3)

第13行的Loo定义中有拼写错误。

您正在呼叫Loop,但这不存在。我假设您应该致电Loo

更新:您看到的是由于功能和程序之间的差异;函数总是返回值,程序没有。您向LooK-1)提供了一个参数,但Loo需要两个参数;一个输入变量和一个用于捕获返回值的变量。 Oz告诉你这个说你正在将错误的arity应用于Loo(当你应用两个参数(二进制)时,你应用一个参数(一元))。

这意味着您还必须将返回值分配给变量。做其中一个:

  1. A = {Loo K-1}
  2. {Loo K-1 A}
  3. A是将为其分配返回值的变量。对于不关心函数返回的情况,常见的约定是使用_作为返回变量名。