If all the functions you want to generate accept doubles, you can just
modify str-sym to include a (with-meta (symbol ...) {:tag 'double}) and it
should generate exactly the code in your hand-written version. As an aside,
there's no reason for str-sym to be a macro: it should just be a function
like (symbol (apply str args)).
On Monday, April 15, 2013 2:59:27 AM UTC-7, dannyg wrote:
>
> Hi all,
>
> I was writing some code and became idly curious about making it more
> 'general' but still performant. Specifically I thought it'd be neat
> to auto-generate a series of vector-based operations from a single
> specification. So instead of many functions like this by hand:
>
> (defn vadd3 [[^double a1 ^double a2 ^double a3] [^double b1 ^double b2
> ^double b3]]
> [(+ a1 b1) (+ a2 b2) (+ a3 b3)])
>
> I'd instead have a macro generate them. Pretty low level ops (yes not
> really suited for clojure but I like exploring the limits) and I was
> pretty happy with the performance:
>
> (bench 1e7 (vadd3 [1.1 2.2 3.3] [2.2 3.3 4.4]))
> "Elapsed time: 1799.587 msecs"
>
> Here we have my attempt to generalise it:
>
> (defmacro -make-vec-ops
> [{:keys [name op start end] :or {start 2}}]
> (cons `do (for [n (range start end)]
> `(defn ~(str-sym- \v n name)
> ~name
> [[~@(for [x (range n)] (str-sym- "a" x)) :as ~'a]
> [~@(for [x (range n)] (str-sym- "b" x)) :as ~'b]]
> [~@(for [x (range n)]
> `(~op ~(str-sym- "a" x) ~(str-sym- "b" x)))]))))
>
> (bench 1e7 (v3add [1.1 2.2 3.3] [2.2 3.3 4.4]))
> "Elapsed time: 2238.391 msecs"
>
> The performacne isn't 'too bad' at 25% lower. But it's frustratingly
> close to matching the original too! I tried toying with some other
> answers I found about generating type-metadat. Alas, my resulting
> macros were either malformed (unsupported binding forms) or didn't
> appear to generate anything in the final functions/performance was the
> same.
>
> I'd love to be wowed by a simple solution! Heck 'any' solution that
> works ;)
>
> As an aside, the macro is pretty ugly... I tried extracting the vector
> deconstruction to a second macro, like this
>
> (defmacro -varg [a n]
> `(~@(for [x (range n)] (str-sym- a x)) :as ~a))
>
> where str-sym-
>
> (defmacro str-sym- [& args] `(symbol (str ~@args)))
>
> But couldn't quite to get it to work :/
>
> Cheers,
> Daniel Grigg
>
--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
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
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.