On Fri, Jul 29, 2011 at 7:35 AM, Sam Aaron <samaa...@gmail.com> 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 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