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
-~----------~----~----~----~------~----~------~--~---

Reply via email to