On 29 Jul 2011, at 12:56, Ken Wesson wrote:
>>> 
>> 
>> That seems to blow up
> 
> How so?

(defn binding-vec [foos]
 (vec (interleave names (take (count names) (repeat `(count ~foos))))))

(defmacro magic-fn
[& forms]
(let [args (gensym 'args)]
  `(fn [& ~args]
     (let ~(binding-vec args)
       ~@forms))))

((magic-fn (+ size 10)) 1 2) ;=> Unable to resolve symbol: size in this context

> 
> (defmacro with-arg-params [bindings & body]
>  (let [bindings (apply array-map bindings)]
>    `(fn
>      ~@(for [i (range (inc (count bindings)))]
>          `(~(vec (take i (keys bindings)))
>             (let ~(vec (mapcat identity (drop i bindings)))
>               ~@body))))))
> 
> => (def x (with-arg-params [foo 1 bar 2 baz 3] (+ foo bar baz)))
> #'user/x
> => (x 4 5 6)
> 15
> => (x 4 5)
> 12
> => (x 4)
> 9
> => (x)
> 6

Ah, very neat :-)

However... (apologies, there always seems to be a however from me in this 
thread!)

This totally satisfies the "general gist" part of my description but doesn't 
allow for the "bunch of other neat tricks I can do here" part. The behaviour of 
with-arg-params needs to match the behaviour of other functions in my system 
for consistency. The other tricks are keyword args and even a combination of 
keyword args and normal args. I have the majority of code to implement all this 
behaviour - I can generate the correct vector of bindings given a list of 
supplied args and some defaults. However, it's the ability to dynamically 
create a let binding within a function for which the bindings themselves are a 
function of the actual function's args (and some constant(s)) which is evading 
me.

This seems the closest I can get to a solution:

(defn binding-vec [foos]
 (fn-which-returns-a-vec-of-alternating-symbols-and-vals foos)

(defmacro magic-fn
[& forms]
(let [args (gensym 'args)]
  `(fn [& ~args]
     (let ~(binding-vec args)
       ~@forms))))

((magic-fn (+ size 10)) 1 2)

I just don't have the magic skills to get it to actually work :-(

Sam

P.S. Thanks everyone for your help so far. My brain is overheating but I am 
learning a lot.

---
http://sam.aaron.name

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to