Seem to be hitting a problem. (defmacro cond "Takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical true, cond evaluates and returns the value of the corresponding expr and doesn't evaluate any of the other tests or exprs. As a special case, a test of :let injects an implicit let (the expression should be a vector of binding forms). The new bindings may be referenced in later tests and expressions. (cond) returns nil." [& clauses] (when clauses ; Jumping through many hoops, as cond is fundamental to many ; other basic forms such as let. (if-not (next clauses) (throw (IllegalArgumentException. "cond requires an even number of forms")))
`(~@(if (= (first clauses) :let) (list 'clojure.core/let (second clauses)) (list 'if (first clauses) (second clauses))) (clojure.core/cond ~@(next (next clauses)))))) This works for normal uses of cond (I had to move it after (defn =) though). However, when I try to use :let, I get a StackOverflowException: at clojure.lang.PersistentList$1.doInvoke(PersistentList.java:32) at clojure.lang.RestFn.applyTo(RestFn.java:142) at clojure.core$apply__4293.invoke(core.clj:395) at clojure.walk$walk__7846.invoke(walk.clj:54) at clojure.walk$prewalk__7852.invoke(walk.clj:74) at clojure.lang.AFn.applyToHelper(AFn.java:175) at clojure.lang.AFn.applyTo(AFn.java:164) at clojure.core$apply__4293.invoke(core.clj:397) at clojure.core$partial__4968$fn__4970.doInvoke(core.clj:1639) at clojure.lang.RestFn.invoke(RestFn.java:413) at clojure.core$map__5005$fn__5007.invoke(core.clj:1724) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:56) at clojure.lang.RT.seq(RT.java:440) at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31) at clojure.core$vec__4219.invoke(core.clj:256) at clojure.walk$walk__7846.invoke(walk.clj:56) at clojure.walk$prewalk__7852.invoke(walk.clj:74) at clojure.lang.AFn.applyToHelper(AFn.java:175) at clojure.lang.AFn.applyTo(AFn.java:164) at clojure.core$apply__4293.invoke(core.clj:397) at clojure.core$partial__4968$fn__4970.doInvoke(core.clj:1639) at clojure.lang.RestFn.invoke(RestFn.java:413) at clojure.core$map__5005$fn__5007.invoke(core.clj:1726) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:56) at clojure.lang.Cons.next(Cons.java:37) at clojure.lang.PersistentList$1.doInvoke(PersistentList.java:32) I suspect this is to do with the fact that the let macro destructures the bindings, and the function for that uses cond. I can't quite wrap my head around the cause-and-effect however. I just don't see why it expands infinitely, because the uses of cond inside destructure-bindings will not be using the :let option, so any uses of cond will be the simple working case (expanding into deeply nested ifs). I'm considering an alternative approach, where the cond macro is redefined at the end of the core.clj, but that seems pretty crude and may also not work. On Sat, Oct 17, 2009 at 6:07 PM, Howard Lewis Ship <hls...@gmail.com> wrote: > Here's my implementation. Seems to be working fine. I like it. > > http://github.com/hlship/cascade/blob/master/src/main/clojure/cascade/utils.clj > http://github.com/hlship/cascade/blob/master/src/test/clojure/cascade/test_utils.clj > > On Sat, Oct 17, 2009 at 5:06 PM, Howard Lewis Ship <hls...@gmail.com> wrote: >> Coming right up! >> >> On Sat, Oct 17, 2009 at 9:14 AM, Sean Devlin <francoisdev...@gmail.com> >> wrote: >>> >>> So you have a working version of this macro, as well as some use cases >>> in actual code? This would help the discussion a lot. >>> >>> Thanks! >>> >>> On Oct 17, 10:43 am, Howard Lewis Ship <hls...@gmail.com> wrote: >>>> I keep coming into situations where I'd like a let in the middle of my >>>> cond. I often do a couple of tests, then would like to lock down some >>>> symbols that I'll use frequently in the remaining cases. >>>> >>>> There's a precedent for this, in that the for macro allows a :let as >>>> an alternative to a list interpolation term. >>>> >>>> I'm working on my own implementation of cond to support this and would >>>> like to see it in core. >>>> >>>> Thoughts? >>>> >>>> -- >>>> Howard M. Lewis Ship >>>> >>>> Creator of Apache Tapestry >>>> >>>> The source for Tapestry training, mentoring and support. Contact me to >>>> learn how I can get you up and productive in Tapestry fast! >>>> >>>> (971) 678-5210http://howardlewisship.com >>> >>> >>> >> >> >> >> -- >> Howard M. Lewis Ship >> >> Creator of Apache Tapestry >> >> The source for Tapestry training, mentoring and support. Contact me to >> learn how I can get you up and productive in Tapestry fast! >> >> (971) 678-5210 >> http://howardlewisship.com >> > > > > -- > Howard M. Lewis Ship > > Creator of Apache Tapestry > > The source for Tapestry training, mentoring and support. Contact me to > learn how I can get you up and productive in Tapestry fast! > > (971) 678-5210 > http://howardlewisship.com > -- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! (971) 678-5210 http://howardlewisship.com --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---