I've been learning Clojure.  I just wrote a macro to be used like so:
(i-let [x nil 4
         y 2 6
         z nil 10]
  (+ x y z))
=> 16

I.E. if the first value in the triple is nil, bind it to the second
value in the triple.  This is useful when you want to let something
that might be nil and has a sensible default.  (In practice I only see
the need to do this \once, but I wrote it for multiple bindings for
generality.  And yes, I'm too lazy to type an if statement every
time.)
   Here's the code:

(defmacro i-let [bindings body]
  (assert-args i-let
    (vector? bindings) "a vector for its bindings"
    (= 0 (mod (count bindings) 3)) "forms by three in binding vector")
  (if (empty? bindings)
    `(let ~bindings ~body)
  (let [nom (bindings 0)
         attempted-val (bindings 1)
         nil-val (bindings 2)]
    (if (nil? attempted-val)
    `(let [~nom ~nil-val] (i-let ~(vec (drop 3 bindings)) ~body))
    `(let [~nom ~attempted-val] (i-let ~(vec (drop 3 bindings))
~body))))))

Note that I've stolen the private code for assert-args----why, by the
way, is this private?
   Anyway I'd appreciate any critiques of the implementation; whether
it's a useful thing or not; if there are more idiomatic ways of doing
the same thing; and, if yes-no to the aforetwo, where's the best place
to add this functionality?
   I've really been enjoying this language (I come from a Scheme
background).  One stumbling block for me is the seq functions.  I'd
really like versions of them that preserve the underlying type (so
that, for instance, in the above macro I could just write "(drop 3
bindings)" instead of "(vec (drop 3 bindings))".  What is the reason
for them only returning a common type?

Thanks,

Nick Chubrich.

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