On Sun, Jan 30, 2011 at 5:36 AM, Shantanu Kumar
<kumar.shant...@gmail.com> wrote:
> On Jan 30, 2:17 pm, Alexander Yakushev <yakushev.a...@gmail.com>
> wrote:
>> Why not use a constraint? It looks much cleaner.
>>
>> (defn hello [& {:keys [a b] :as input}]
>>          {:pre [(= (set (keys input)) #{:a :b})]}
>>          "hello")

Where is this documented?

> This is not the use case I was looking for (I listed it in a post
> above). Constraints are a good place to do this but not sure how to
> report the offending keyword clearly and easily using constraints --
> as in, I need to preempt 'returning false' and throw
> IllegalArgumentException with correct error message instead.

Try this version of my earlier macro:

(defmacro defkfn [name keys & body]
  (let [[docstring keys body]
        (if (string? keys)
          [[keys] (first body) (rest body)]
          [[] keys body])]
     `(defn ~name ~@docstring [& {:keys ~keys :as input#}]
        (doseq [k# (keys input#)]
          (when-not (~(set (map (comp keyword str) keys)) k#)
            (throw (IllegalArgumentException. (str "bad key " k#)))))
        ~@body)))

user=> (defkfn foo [a b] (+ a (* 2 b)))
#'user/foo
user=> (foo :a 2 :b 1)
4
user=> (foo :b 2 :a 1)
5
user=> (foo :b 2 :a 1 :c 3)
#<CompilerException java.lang.IllegalArgumentException: bad key :c
(NO_SOURCE_FILE:519)>
user=>

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