Funzione e procedure comportano in modo diverso con lo stesso codice di Mozart Oz?
Domanda
I provare a stampare la sequenza di Fibonacci in Oz con 2 approccio: la funzione e la procedura utilizzando Emac come redattore. Procedura va qui:
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}
e la funzione:
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}
Il problema è che l'unica procedura opere "loop". Il risultato è:
1
1
2
3
5
8
13
21
34
55
Funzione "Loo" non lo fa e getta un po 'difficile da capire gli errori:
%********************** 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)
Ancora non so perché. Come penso la funzione e la procedura ha effetto simile a OZ.
Soluzione
funzioni devono essere chiamato sia con la sintassi chiamata di funzione:
_ = {Loo 10}
o in alternativa con un parametro aggiuntivo a ricevere il valore:
{Loo 10 _}
_
si pronuncia "do not care" e significa che il valore della variabile non è necessaria.
Inoltre, le funzioni deve restituire un valore da avere un'espressione come l'ultima parte di ogni ramo. Così la funzione Loo
fisso sarebbe simile a questa:
fun {Loo L}
if L == 1 then
{Browse L}
unit
else
_ = {Loo L-1}
{Browse {Fibo L}}
unit
end
end
_ = {Loo 10}
Tuttavia, utilizzando una funzione per loop come questo non ha molto senso se non si ha nulla di interessante da ritorno. Forse quello che si vuole veramente è quello di costruire un elenco e restituirlo come risultato ?
Altri suggerimenti
Si dispone di un errore di battitura nella definizione di Loo
alla linea 13.
Loop
Si sta chiamando, che non esiste. Presumo si dovrebbe essere chiamando Loo
.
UPDATE: Quello che state vedendo è dovuto alla differenza tra le funzioni e le procedure; funzioni restituiscono sempre i valori, le procedure non lo fanno. Si stanno dando un singolo argomento per Loo
(K-1
), ma Loo
ha bisogno di due argomenti; una variabile di ingresso ed una variabile di catturare il valore restituito. Oz si dice questo dicendo che si sta applicando l'arietà sbagliato Loo
(si sta applicando un argomento (unario) quando si dovrebbe essere l'applicazione di due argomenti (binari)).
Questo significa che si deve assegnare il valore restituito a una variabile pure. Eseguire una:
-
A = {Loo K-1}
-
{Loo K-1 A}
A
è la variabile a cui verrà assegnato il valore di ritorno. Una convenzione comune per i casi in cui non si cura di ciò che la funzione ritorna è quello di utilizzare _
come il nome della variabile di ritorno.