2012-07-08 6 views
5

La funzione ClojurePerché non è una funzione Clojure che consiste esclusivamente di chiamate lazy function pigre?

(reductions + 0 (cycle [1 1 -1])) 

produce una sequenza [0 1 2 1 2 3 2 3 4 3 4 5 ...]. Sfortunatamente, questa sequenza non è pigra.

As cycle e reductions sono entrambi documentati come sequenze pigro di ritorno, mi aspettavo che questa combinazione di quelle funzioni restituisse anche una sequenza lenta. Perché non lo fa e come posso correggerlo per restituire la sequenza pigramente?

Un esempio più complesso che presenta lo stesso problema:

(reductions (fn [x f] (f x)) 0 (cycle [inc inc dec])) 

(mostro, perché questo è il tipo di versione desidero avere lavorare alla fine, nel caso che fa alcuna differenza)

risposta

9

Sfortunatamente, questa sequenza non è pigra.

Oh, sì, lo è. Possiamo controllare rapidamente che è pigro prendendo i suoi primi 10 elementi:

(take 10 (reductions + 0 (cycle [1 1 -1]))) 

Questo restituisce molto rapidamente una risposta, il che dimostra la sequenza è pigro. Se la funzione non fosse pigra, avrebbe cercato di realizzare tutti gli elementi nella sequenza infinita, e avrebbe soffiato la memoria, o sarebbe appesa a un loop infinito.

Quello che succede è che stai digitando questa funzione nel REPL, che tenta di realizzare la sequenza prima di mostrarla a te.

Modifica: Utilizzare questo suggerimento su stop infinite loops se si è scoperto che ne è stato attivato uno o si è tentato accidentalmente di realizzare un seq infinito.

+0

Grazie :). Ho provato ad aliasare la sequenza con una (def ...) dichiarazione per impedirlo, ma ovviamente (ora capisco) che non funziona. Chiamarlo con un (defn ...) funziona bene. – Confusion

+1

Un modo più accurato per verificare se una funzione è pigra è la sua realizzazione? . Se restituisce false la funzione è pigra. => (realizzato? (riduzioni +0 (ciclo [1 1 -1]))) false – NielsK

+1

'realizzato?' funziona molto male per questo scopo (anzi, per la maggior parte degli scopi, si spera che presto migliori). Prova "realizzato?" Su tutti questi valori: '[]', 'nil',' '(a b c) ',' (iterate inc 0) ', e vedrai cosa intendo. – amalloy