17

Even looking closely over documentation on Clojure, I do not see any direct confirmation as to whether or not Clojure supports operator overloading.

If it does, could someone provide me with a quick snipplet of how to overload, let's say, the "+" operator to delegate to some predefined method that we can call myPlus.

I am very new to Clojure, so someone's help here would be greatly appreciated.

Ryan Delucchi
  • 7,718
  • 13
  • 48
  • 60

2 Answers2

26

Clojure's (as any Lisp's) operators are plain functions; you can define an "operator" like a function:

(defn ** [x y] (Math/pow x y))

The "+" operator (and some other math-operators) is a special case in Clojure, since it is inlined (for the binary case, at least). You can to a certain extent avoid this by not referring to clojure.core (or excluding clojure.core/+) in your namespace, but this can be very hairy.

To create a namespace where + is redefined:

(ns my-ns
  (:refer-clojure :exclude [+]))

(defn + [x y] (println x y))

(+ "look" "ma")

One good strategy would probably be to make your + a multimethod and call core's + function for the numeric cases.

Community
  • 1
  • 1
pmf
  • 7,619
  • 4
  • 47
  • 77
  • So, if I were to exclude clojure.core/+, I could do the following (defn + [x y] (myPlus x y)) correct? If so, that is exactly what I want to do. How do I exclude clojure.core/+ from my namespace? – Ryan Delucchi Oct 08 '09 at 02:08
  • 1
    I've added this to my answer. – pmf Oct 08 '09 at 02:14
  • Actually, after trying this: it doesn't seem to work. I try it and get the following error: java.lang.Exception: Name conflict, can't def + because namespace: my-ns refers to:#'clojure.core/+ (NO_SOURCE_FILE:5) – Ryan Delucchi Oct 08 '09 at 06:39
  • Please enable public editing so I can fix my vote on your answer (and give you a well-deserved +1) – Ryan Delucchi Oct 08 '09 at 06:46
  • I don't actually know how to do this. – pmf Oct 08 '09 at 15:22
  • Make some arbitrary changes to your answer, and I should be able to fix my voting mistake. – Ryan Delucchi Oct 08 '09 at 16:39
5

Take a look at this: http://clojure.org/multimethods

Certain functions, like + are core and cannot be redefined.

You could make a new function and call it ".+" or "!+" for example, which is similar in terms of readability.

Using the information in the multimethods URL included above, you can build a function that tells your .+ which implementation to use.

Mark Bolusmjak
  • 23,606
  • 10
  • 74
  • 129
  • You didn't answer his question one way or the other. – chollida Oct 08 '09 at 01:51
  • `+` can be easily redefined in a different namespace. In fact you can even redefine `+` in clojure.core if you like (though not recommended....) – mikera Jan 02 '13 at 05:35