I like to build DSLs when I code, so that at a high level, much of the
logic is readable and consistent.  I'm trying to create a macro that
will verify the uniqueness of a record based on various fields in the
record.  For example, if I have a function that looks up a record by
its name:

    (defn by-name [name] (...some code to look up the record by
name...))

In its create routine, I want to call a macro "unique?" and have the
record check that the name doesn't already exist:

    (defn create
        [name]
        (unique? :name name "The name \"%s\" already exists.")
        ....no exception, we can create the record...
        )

That "unique?" macro would convert :name into a call to the "by-name"
function, pass in the value, check for a result, and if it already
exists, throw an exception with the given message.

I'm having a heck of a time converting that :name to the "by-name"
reference, and I'm trying to avoid eval because I understand it's a
performance hit.  Is there a way to accomplish this in the "unique?"
macro?

Here's my first attempt (obviously it doesn't work, but might help
clarify what I'm getting at):

    (defmacro unique?
      "Is the given value unique to the record?"
      [name value message]
      `(if-not (str/blank? ~value)
         (let [finder# (symbol (str "by-" (name ~name)))
               existing# (finder# ~value)]
           (if existing# (duplicate existing# ~message ~value)))))

(The "duplicate" function raises the exception.)

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