5

Lavorando sul seguente esempio in "Clojure in azione":Errore con "applicare" la funzione in Clojure: "Non so come creare iseq da: java.lang.Long" (Pag. 63)

(defn basic-item-total [price quantity] 
    (* price quantity)) 

(defn with-line-item-conditions [f price quantity] 
    {:pre [(> price 0) (> quantity 0)] 
    :post [(> % 1)]} 
    (apply f price quantity)) 

valutazione sulla REPL:

(with-line-item-conditions basic-item-total 20 1) 

risultati nella seguente eccezione che sono gettati:

Don't know how to create ISeq from: java.lang.Long 
    [Thrown class java.lang.IllegalArgumentException] 

sembra che l'eccezione viene th rown dopo aver valutato la procedura di applicazione.

+1

'apply' è una funzione, non una macro. – amalloy

risposta

8

L'ultimo argomento per apply deve essere un sequence of arguments. Nel tuo caso, l'utilizzo potrebbe apparire più simile a questo:

(defn with-line-item-conditions [f price quantity] 
    {:pre [(> price 0) (> quantity 0)] 
    :post [(> % 1)]} 
    (apply f [price quantity])) 

apply è utile quando si lavora con un elenco di argomenti. Nel tuo caso, puoi semplicemente chiamare la funzione:

(defn with-line-item-conditions [f price quantity] 
    {:pre [(> price 0) (> quantity 0)] 
    :post [(> % 1)]} 
    (f price quantity)) 
+1

Grazie - Ora vedo che nel caso della macro applicata, la sequenza dovrebbe essere un vettore. Questo non era chiaro dopo aver letto la descrizione dopo aver valutato (doc apply): "Applica fn f alla lista degli argomenti formata dagli argomenti interminabili in argomento a args." – dtg

+2

Sì, alcune delle stringhe doc possono essere piuttosto opache. [Il cheatsheet] (http://clojure.org/cheatsheet) è un ottimo posto per gli usi di esempio. – Beyamor