2012-03-15 41 views
6

即時得到可怕的*不能轉換到IFN錯誤用一個簡單的數學函數在這裏:的Clojure:整數無法投射到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))))) 

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

的ARG遊戲只是一串數字:

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

我的想法/我的問題

通常,當我得到這個錯誤,我發現這是由於

1 )一個額外的括號(即,當我意外地在我的代碼中加入額外的封閉)或

2)錯誤排列的參數(顯然 - 演員例外)。

我的問題是簡單的...如何解決這個片段,以及可選的 - 我怎麼能一勞永逸地打敗這個常見的異常?看來它在我的Clojure編碼考察中經常發生,我想也許我還沒有得到正確的開發風格。

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

UPDATE:

我已經千瘡百孔我的代碼以unregular語法。這個錯誤發生在內部函數中,其中 使用了一個java/c風格函數調用:例如max/log ...

回答

6

它在我看來像你有一個log(sc1)等調用的問題。

應然看(假設日誌某處定義)是這樣的:

(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)))) 

如果你只想使用Java日誌,用Math/log取代log這java.lang.Math中調用靜態日誌功能

+0

考慮通過一個地圖作爲參數,而不是一百萬有序的參數和使用':keys'解構宏。 – 2014-04-12 14:45:56

14

在我看來像有害的表達式是(x32,(/ m1 min_m1))和(x32,(/ tca_ratio min_tca))以及log(..)ones。

Clojure遵循標準的lisp約定,即將不帶引號的列表的第一個元素作爲調用函數。換句話說,您希望(log ...)而不是(log)(...)和(max ...)而不是(max(...))

捕獲這些錯誤非常簡單您的特定風格:一切符合「XXX(」 XXX是任意數量的非空間,非括號字符是一個錯誤

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

隨着時間的推移和實踐,你會得到與dynamic typing更好

1

使用clojure.stacktrace或類似工具(在Clojure 1.3中可能有更好的/改進的選項,我還沒有研究過)來調試這種東西,請參見Obtain a callstack in Clojure d http://tech.puredanger.com/2010/02/17/clojure-stack-trace-repl/

請注意,*e綁定到repl上的最新異常。

例如:

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)