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 [email protected]
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
-~----------~----~----~----~------~----~------~--~---