1. Looks like everyone prefers the let-kw name. Sounds good to me. 2. I tried it with the more let-like form, but I don't like the number of opening braces required. For a full kw-spec, the form would end up (let-kw [[[:kw default supplied?]] kw-args] ...). Clojure tends to err on the side of fewer braces and parentheses, and three opening braces looks excessive to me. That said, I see the point of keeping it consistent with the other binding forms.
3. Unnecessary interleave replaced with zipmap. 4. With regard to the generality of the interface: I put all those features in there because I have wanted to use them. I often find myself writing or wrapping API-like code, and slicing and dicing arguments and passing them through to other functions, as vectors or maps, has been useful. 5. As for putting the macro in clojure-contrib, thanks for the vote of confidence. :) I'll drop a signed Contributor Agreement in the mail today, and get an Assembla ticket and patch out soon. Thanks for all the feedback and suggestions. New version: (defmacro let-kw "Adds flexible keyword handling to any form which has a parameter list: fn, defn, defmethod, letfn, and others. Keywords may be passed to the surrounding form as & rest arguments, lists, or maps. Lists or maps must be used for functions with multiple arities if more than one arity has keyword parameters. Keywords are bound inside let-kw as symbols, with default values either specified in the keyword spec or nil. Keyword specs may consist of just the bare keyword, which defaults to nil, or may have the general form [:keyword-name keyword-default-value* keyword-supplied?*]. keyword-supplied? is an optional symbol bound to true if the keyword was supplied, and to false otherwise." [kw-spec-raw kw-args & body] (let [kw-spec (map #(if (sequential? %) % [%]) kw-spec-raw) keywords (map first kw-spec) symbols (map (comp symbol name) keywords) defaults (map second kw-spec) destrmap {:keys (vec symbols) :or (zipmap symbols defaults)} supplied (reduce (fn [m [k v]] (assoc m k v)) (sorted-map) (remove (fn [[_ val]] (nil? val)) (partition 2 (interleave keywords (map (comp second rest) kw-spec))))) kw-args-map (gensym)] `(let [kw-args# ~kw-args ~kw-args-map (if (map? kw-args#) kw-args# (apply hash-map kw-args#)) ~destrmap ~kw-args-map] ~@(if (empty? supplied) body `((apply (fn [~@(vals supplied)] ~...@body) (map (fn [x#] (contains? ~kw-args-map x#)) [~@(keys supplied)]))))))) -- 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