Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redefining "def" in Clojure

Tags:

clojure

Is there anyway to define a new macro under the name def in Clojure? I defmacroed a new one after trying to :refer-clojure :exclude the original, but it used the built-in definition anyway.

I was trying to enable Scheme-style function definitions ((def (f x y) ...) as (defn f [x y] ...)) using the following code.

(defmacro def
  [ id & others ]
    (if (list? id)
        `(defn ~(first id) [~@(rest id)] ~@others)
        `(def ~id ~@others)))
like image 741
Jeremy Avatar asked Nov 21 '10 14:11

Jeremy


2 Answers

def is not a macro, it is a special form. It interns a symbol into current namespace. You cannot redefine special forms, but even if you could, how would you get same behavior?

The most straightforward way is to write define macro on base of def and defn. If you want to use def word, you can write a wrapper replace-my-def-with-normal-def around all the module, i.e.

(replace-my-def-with-normal-def

   (def x 0)
   (def y (inc x))
   (def z (inc y))
   (def (my-func a b) (println a b))

)

but I'm not sure it won't break other definitions, which depend on def (for example, defn).

like image 106
ffriend Avatar answered Sep 20 '22 23:09

ffriend


You can create a macro with the name of a special form (like if), but it won't help you. Special forms are evaluated before macros, therefore if you have a macro and a special form of same name the special form will always be used. More information here http://clojure.org/evaluation.

like image 21
moq Avatar answered Sep 18 '22 23:09

moq