Clojure: An integer cannot be passed to IFn

Im getting scary * cannot be passed to IFn error with a simple math function here:

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

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

Arguments are just a bunch of numbers:

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

My thoughts / My question

Usually, when I get this error, I find that this is due to

1) An extra parenthesis (i.e. when I accidentally added an extra closure to my code) OR

2) Arguments that are incorrectly ordered (obviously, an exception to the list).

My question is simple ... how to fix this fragment and, possibly, how can I defeat this general exception once and for all? It seems like this happens quite often on my Clojure expeditions, and I think maybe I don't have the right development style yet.

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

UPDATE:

I encoded my code with irregular syntax. Errors were in internal functions that used java / c style function calls: for example, max / log ...

+6
source share
4 answers

It looks like insulting expressions: (x32, (/ m1 min_m1)) and (x32, (/ tca_ratio min_tca)), as well as the log (..).

Clojure follows the standard lisp convention that the first element of an unquoted list is a call function. In other words, you want to have (log ...) instead of log (...) and (max ...) instead of (max (...))

Capturing these errors is pretty straightforward in your particular style: anything that matches "XXX (" where XXX is any number of characters without spaces that are not brackets "is an error.

+14
source

It seems to me that you have a problem with calls to log(sc1) , etc.

It should look (assuming log is defined somewhere), something like:

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

If you just want to use Java log , replace log with Math/log , which calls the static log function in java.lang.Math

+6
source

Debugging these kinds of benefits when using clojure.stacktrace or the like (options in Clojure 1.3 that I have not explored can be improved / improved, see Get a column in Clojure and http://tech.puredanger.com/2010/02/17 / clojure-stack-trace-repl / .

Note that *e tied to the most recent exception in repl.

For instance:

 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)

+1
source
 how can I defeat this common exception once and for all 

With time and practice, you will become better with dynamic typing .

0
source

Source: https://habr.com/ru/post/910847/


All Articles