On Nov 16, 4:28 pm, Chouser <chou...@gmail.com> wrote:
> 'let' is also careful to always have the user provide the symbol
> being bound as a symbol.  That is you say {:keys [a b c]} not
> {:keys [:a :b :c]}.  What do you think of having let-kw take
> symbols instead of keywords for the names being bound?

I think that's a good idea.

Updated 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 symbol, 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)
        symbols  (map first kw-spec)
        keywords (map (comp keyword name) symbols)
        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

Reply via email to