2014-07-21 17 views
5

La macro for di Clojure accetta due argomenti: una sequenza di forme vincolanti e un'espressione del corpo. In quanto tale, se voglio fare più cose nel ciclo, devo racchiudere più espressioni in un blocco do per renderle una singola espressione.Perché Clojure per macro accetta solo un'espressione del corpo?

Confronta:

(doseq [a (range 3)] 
    (prn 'a a) 
    (inc a)) 

a:

(for [a (range 3)] 
    (prn 'a a) 
    (inc a)) 

I doseq funziona come previsto. Il for lamenta:

clojure.lang.ArityException: Wrong number of args (3) passed to: core/for 

La mia domanda è, perché non fa questo lavoro? Perché i progettisti di Clojure non hanno consentito più espressioni "body" nel ciclo for, come hanno fatto in doseq e when? Non è che ci sia qualche ambiguità semantica, giusto?

+1

Una grande differenza è che 'for' è pigro, mentre' doseq' (principalmente per indurre effetti collaterali) non lo è. 'when' valuta il suo corpo in un' do' implicito. Vedi anche http://stackoverflow.com/q/4725417 –

risposta

13

Clojure's for non è un loop, è una lista pigra di comprensione. Poiché viene restituito solo il valore dell'ultima espressione nel corpo di un (implicito) do, qualsiasi altra espressione dovrebbe esistere solo per gli effetti collaterali. L'esecuzione per gli effetti collaterali è il lavoro di doseq, motivo per cui ha un implicito do. Che for non dovrebbe essere un promemoria, vuoi davvero effetti collaterali nella tua sequenza pigra? Sebbene ci siano ragioni legittime per farlo, è necessario garantire che tali effetti collaterali vengano eseguiti quando lo si desidera.

(def foo (for [a (range 32)] 
      (do 
      (prn (str "a is " a)) 
      (inc a)))) 

(take 1 foo) 
;=> 
    ("a is 0" 
    "a is 1" 
    ... 
    "a is 31" 
    1) ; <= the return value 

(take 10 foo) 
;=> 
    (1 2 3 4 5 6 7 8 9 10) ; aw, no side effects this time 
+0

Una buona risposta, anche se penso che la parte chunking alla fine sia per lo più un'aringa rossa, e non spiegata abbastanza bene da essere utile comunque. – amalloy

+0

Ah, questo ha senso. Grazie per aver spiegato. –

Problemi correlati