2012-03-15 16 views
6

Im ottenendo il temuto * non può essere gettato per errore IFN con una semplice funzione matematica qui:Clojure: Integer non può lanciare a IFN

(defn calc [sc1 m1 alpha beta gamma ta1 tb1 min_m1 min_tca tca_ratio x32] 
     (* 
      (max(0, 
       (+ 
       (* alpha log(sc1)) 
       (* beta log(m1)) 
       (* gamma (/ ta1 tb1)) 
       (- log(ta1) log(tb1))))) 

      (max(x32,(/ m1 min_m1))) 

      (max(x32,(/ tca_ratio min_tca))))) 

;;;;;;;;;;;;

Gli argomenti sono semplicemente un po 'di numeri:

(calc 1 2 3 4 5 1 2 3 4 5 1) 

I miei pensieri/La mia domanda

Di solito, quando ottengo questo errore, trovo che sia dovuto al

1) Una parentesi in più (ovvero quando ho inserito accidentalmente una chiusura extra nel mio codice) O

2) Argomentazioni errate (ovviamente - un'eccezione cast).

La mia domanda è semplicemente ... come risolvere questo snippet e, facoltativamente, come posso sconfiggere questa eccezione comune una volta per tutte? Sembra che si verifichi abbastanza spesso nelle mie spedizioni in Clojure, e penso che forse non ho ancora avuto il giusto stile di sviluppo.

--------------------------------------------- ----------

UPDATE:

ho crivellato il mio codice con la sintassi unregular. Gli errori erano nelle funzioni interne, che utilizzava chiamate di funzione stile java/c: ad esempio max/log ...

risposta

6

Mi sembra che tu abbia un problema con le chiamate log(sc1), ecc.

dovrebbe guardare (log supponendo che è definita da qualche parte) qualcosa come:

(defn calc [sc1 m1 alpha beta gamma ta1 tb1 min_m1 min_tca tca_ratio x32] 
    (* 
    (max 0 
      (+ 
      (* alpha (log sc1)) 
      (* beta (log m1)) 
      (* gamma (/ ta1 tb1)) 
      (- (log ta1) (log tb1)))) 

    (max x32 (/ m1 min_m1)) 
    (max x32 (/ tca_ratio min_tca)))) 

Se si desidera utilizzare il registro di Java, sostituire log con Math/log che chiama la funzione di log statica in java.lang.Math

+0

consideri che passa una mappa come argomenti, invece di un milione di argomenti ordinati e utilizzare il ': keys' macro destrutturazione. –

14

Mi sembra che le espressioni offensive siano (x32, (/ m1 min_m1)) e (x32, (/ tca_ratio min_tca)) e anche i log (..).

Clojure segue la convenzione standard lisp di avere il primo elemento di una lista non quotata come una funzione da chiamare. In altre parole, vuoi avere (log ...) invece di log (...) e (max ...) invece di (max (...))

La cattura di questi errori è piuttosto facile in il vostro stile particolare: tutto ciò che corrisponde a "XXX (" dove XXX è un numero qualsiasi di non-spazio, i caratteri non-parentesi è un errore

0
how can I defeat this common exception once and for all 

con il tempo e la pratica si otterrà una migliore con dynamic typing

1
..

Il debug di questo tipo di cose trae vantaggio dall'uso di clojure.stacktrace o simili (potrebbero esserci opzioni migliori/migliorate in Clojure 1.3 che non ho ricercato), vedere Obtain a callstack in Clojure un d http://tech.puredanger.com/2010/02/17/clojure-stack-trace-repl/.

Nota che *e è associato all'eccezione più recente sul repl.

Ad esempio:

user=> (defn broken [x] 
     (let [internal (fn [y] (y))] 
      (internal x)))

user=> (broken 1) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)

user=> (use 'clojure.stacktrace)

user=> (print-stack-trace (root-cause *e) 2) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn at user$broken$internal__1206.invoke (NO_SOURCE_FILE:2) user$broken.invoke (NO_SOURCE_FILE:3)

Problemi correlati