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