Il problema è che con chiamata/cc il risultato dipende dall'ordine di valutazione. Considera il seguente esempio in Haskell. Supponendo abbiamo la chiamata/cc operatore
callcc :: ((a -> b) -> a) -> a
callcc = undefined
definiamo
example :: Int
example =
callcc (\s ->
callcc (\t ->
s 3 + t 4
)
)
Entrambe le funzioni sono puri, così il valore di example
dovrebbero essere univocamente determinata. Tuttavia, dipende dall'ordine di valutazione. Se viene valutato prima s 3
, il risultato è 3
; se viene valutato prima t 4
, il risultato è 4
.
Ciò corrisponde a due esempi distinti monade di continuazione (che impone ordine):
-- the result is 3
example1 :: (MonadCont m) => m Int
example1 =
callCC (\s ->
callCC (\t -> do
x <- s 3
y <- t 4
return (x + y)
)
)
-- the result is 4
example2 :: (MonadCont m) => m Int
example2 =
callCC (\s ->
callCC (\t -> do
y <- t 4 -- switched order
x <- s 3
return (x + y)
)
)
Persino dipende se un termine viene valutata affatto o meno:
example' :: Int
example' = callcc (\s -> const 1 (s 2))
Se s 2
viene valutato, il risultato è 2
, altrimenti 1
.
Ciò significa che il Church-Rosser theorem non detiene in presenza di chiamata/cc. In particolare, i termini non hanno più normal forms.
Forse una possibilità sarebbe di visualizzare chiamata/cc come operatore non deterministica (non costruttivo) che combina tutti i possibili risultati ottenuti da (non) valutare diverse sotto-termini vario ordine. Il risultato di un programma sarebbe quindi l'insieme di tutte le possibili forme normali. Tuttavia, l'implementazione standard call/cc selezionerà sempre solo uno di essi (in base al suo particolare ordine di valutazione).
fonte
2014-07-12 09:39:08