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.


Reply via email to