On Fri, Jul 29, 2011 at 7:35 AM, Sam Aaron <[email protected]> wrote:
>
> On 29 Jul 2011, at 12:11, Ken Wesson wrote:
>>
>> Why not just (vec (interleave names (take (count names) (repeat
>> `(count ~foos)))))?
>>
>
> That seems to blow up
How so?
> The actual end goal is to be able to define a macro (or whatever) passing in
> a body containing symbols which are yet to be defined. The macro will then
> return me function which has variable arity. When I call this function I'd
> like the values of the args be bound to a specified list of symbols (which
> happen to be the arg names) so that the original body can execute correctly.
> The interesting part is that I'd like to be able to specify defaults
> interleaved with the arg names.
>
> For example:
>
> (def yo (with-arg-params [foo 0 bar 1 baz 2]
> (+ foo bar baz)
>
> a would now be bound to a fn which I could call:
>
> (yo 1 2 3) ;=> 6
>
> I could also call it with fewer args than expected:
>
> (yo 1 2) ;=> 5
>
> this works because bad has a default of 2.
(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
=> (macroexpand-1 '(with-arg-params [foo 1 bar 2 baz 3] (+ foo bar baz)))
(clojure.core/fn ([] (clojure.core/let [foo 1 bar 2 baz 3] (+ foo bar
baz))) ([foo] (clojure.core/let [bar 2 baz 3] (+ foo bar baz))) ([foo
bar] (clojure.core/let [baz 3] (+ foo bar baz))) ([foo bar baz]
(clojure.core/let [] (+ foo bar baz))))
=
(fn
([] (let [foo 1 bar 2 baz 3] (+ foo bar baz)))
([foo] (let [bar 2 baz 3] (+ foo bar baz)))
([foo bar] (let [baz 3] (+ foo bar baz)))
([foo bar baz] (let [] (+ foo bar baz))))
Note that array-map cannot be changed to hash-map here because the
order must be preserved.
--
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.
--
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