Metadata (including type hints) are attached to symbols by the reader, so I'm thinking something like:
(def a 1) (def b 2) (defn greatest-by "Return the 'largest' argument, using compare-fn as a comparison function." [compare-fn & args] (reduce #(if (pos? (compare-fn %1 %2)) %1 %2) args)) (defmacro generic-max [a b] (if (or (and (instance? Number a) (instance? Number b)) (and (= (:tag (meta a)) 'int) (= (:tag (meta b)) 'int))) (do (println "Using max") `(max ~a ~b)) (do (println "Using greatest-by") `(greatest-by compare ~a ~b)))) user> (generic-max 1 2) Using max 2 user> (generic-max "one" "two") Using greatest-by "two" user> (generic-max a b) Using greatest-by 2 user> (generic-max #^int a #^int b) Using max 2 All of the above calls to generic-max should be compiling down to a call to either max or greatest-by, so there should be no runtime overhead, and no need to have two separate functions. What I'm asking is, if it is possible formalize this into something like: (defmultimacro generic-max (fn [x y] [(:tag (meta x)) (:tag (meta y))]) :default) (defmethodmacro generic-max ['int 'int] [x y] `(max ~x ~y)) (defmethodmacro generic-max :default [x y] `(greatest-by compare ~x ~y)) I guess this is problematic, because when the dispatch function for generic-max is called it would eval x and y. Just thinking out loud. The only funny thing that happens is (generic-max #^int a #^int b) will compile down to a call to max, but when I do this: user> (macroexpand '(generic-max #^int a #^int b)) Using greatest-by The type hints aren't being effective. I'm probably missing and/or abusing something here, so maybe my whole thought experiment is flawed? Paul On Tue, Nov 4, 2008 at 12:46 PM, Konrad Hinsen <[EMAIL PROTECTED]> wrote: > > On Nov 4, 2008, at 18:18, Paul Stadig wrote: > >> Is it possible to create "generic" macros? I mean macros are basically >> a way to extend the compiler, right? Wouldn't it be useful to be able >> to dispatch a macro based on the type hint of its parameters (or some >> other criteria)? > > A macro gets its arguments unevaluated (necessarily, being called at > compile time). I don't see how it could know their types. Given > something like > > (max a b) > > how could you figure out the types of the values that will be bound > to a and b when the macro-generated code is executed? > > Konrad. > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---