Функция и процедура ведут себя по-разному с одним и тем же кодом в Моцарте Оз? - PullRequest
7 голосов
/ 29 апреля 2011

Я пытаюсь распечатать последовательность Фибоначчи в Оз, используя 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.

Ответы [ 2 ]

6 голосов
/ 30 апреля 2011

Функции должны вызываться с синтаксисом вызова функции:

_ = {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}

Однако, использование функции для такого цикла не имеет большого смысла, если у вас нет ничего интересного для возврата. Может быть, вы действительно хотите построить список и вернуть его в результате ?

3 голосов
/ 29 апреля 2011

У вас есть опечатка в определении Loo в строке 13.

Вы звоните Loop, которого не существует. Я полагаю, вы должны звонить Loo.

ОБНОВЛЕНИЕ: То, что вы видите, связано с различием между функциями и процедурами; функции всегда возвращают значения, процедуры - нет. Вы даете один аргумент Loo (K-1), но Loo требуется два аргумента; одна входная переменная и одна переменная для захвата возвращаемого значения. Оз говорит вам об этом, говоря, что вы применяете неправильную арность к Loo (вы применяете один аргумент (унарный), когда вы должны применять два аргумента (двоичный)).

Это означает, что вы также должны присвоить возвращаемое значение переменной. Выполните одно из:

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

A - переменная, которой будет присвоено возвращаемое значение. Общепринятое соглашение для случаев, когда вам не важно, что возвращает функция, это использовать _ в качестве имени возвращаемой переменной.

...