在莫扎特奥兹中,函数和过程在相同的代码中表现不同



我尝试在Oz中使用2种方法打印斐波那契数列:使用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中有相似的效果。

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

_ = {Loo 10}

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

{Loo 10 _}

_读作"don't care",表示不需要该变量的值。

同样,函数必须通过在每个分支的最后使用表达式来返回一个值。固定的Loo函数是这样的:

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

但是,如果没有任何有趣的东西要返回,那么像这样使用函数进行循环就没有多大意义。也许您真正想要的是构建一个列表并将其作为结果返回?

在第13行Loo的定义中有一个错别字。

您拨打的Loop号码不存在。我想你应该打电话给Loo

UPDATE:你看到的是函数和过程之间的差异;函数总是返回值,而过程不会。你给Loo (K-1)一个参数,但Loo需要两个参数;一个输入变量和一个捕获返回值的变量。Oz告诉你,你对Loo应用了错误的校验(当你应该应用两个参数(二进制)时,你应用了一个参数(一元))。

这意味着您还必须将返回值赋给一个变量。执行以下命令之一:

  1. A = {Loo K-1}
  2. {Loo K-1 A}

A是赋值给返回值的变量。当您不关心函数返回什么时,一个常见的约定是使用_作为返回变量名。

最新更新