tags:

views:

145

answers:

3

A while ago this code seemed to work, but now it doesn't anymore. Is there something wrong with it?

user=> (defn sum [a b] (a + b))
#'user/sum
user=> (sum 3 4)
java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
user=>

It's probably time to take a break :)

+6  A: 

Perhaps try:

(defn sum [a b] (+ a b))

Clojure, being a member of the Lisp family, always uses prefix notation for arithmetic expressions.

Greg Hewgill
Yeah, I forgot.
StackedCrooked
+1  A: 

Since you're trying to write such a function, I wonder if it might be helpful to point out that + is just a regular function in Clojure, as it is in any other Lisp. In fact, there are no special "arithmetic expressions" in Clojure, just function applications whose arguments are numbers and whose operator functions perform arithmetic operations.

In fact, in most Lisps there are no special "operators" in the sense distinguished pieces of syntax which would need to be wrapped for their functionality to be available in the form of a function. Clojure is unusual as a Lisp in this regard in that it explicitly depends on its host platform for some fairly basic features; e.g. floating-point exponentiation is available in vanilla Clojure in the form of the pow method of the java.lang.Math class (but see clojure.contrib.math for some nice functions to perform various arithmetic ops not in clojure.core).

Java methods would have to be wrapped in Clojure to be used as functions (e.g. passed to map etc.), so in that way they might bring to mind operators from languages such as C, Python or indeed Java itself. They are still called using prefix notation, though.

Michał Marczyk
+1  A: 
  • There is already a + function in clojure.core, so be very careful when redefining it, you're probably better off avoiding this.
  • All Lisps including Clojure use prefix notation. You should call a function like (fn-name args). In your example Clojure tries to call an Integer as a function, because that's the first element of the list. Integers do not implement the IFn interface, so that explains the error message.
  • You can in fact get an infix notation for mathematical functions using a function. For this function see page 13 of the first chapter of The Joy Of Clojure, freely available here: http://www.manning.com/fogus/Fogus_MEAP_Ch1.pdf.
Michiel Borkent
Even though that particular infix example will not make it into the final draft, I should note that it was implemented as a function, not a macro.
fogus
@fogus Edited correspondingly.
Michiel Borkent