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 [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