Re: Why can't :let be first in a for
Dear all, I've got a re-implementation of the for-macro sitting around here that removes this limitation (and others, the vector can't be empty either, if I remember correctly). The implementation also adds the sorting and grouping functionality described in Wadler and Jones' paper comprehensive comprehensions (http://research.microsoft.com/~simonpj/ papers/list-comp/list-comp.pdf). I'd be happy to post the code if anyone's interested, however: - it's based on an old version of Clojure (Dec '08, pre lazier seqs), so it might need some work. - I implemented a complete parser (Hutton's monadic parser combinators, http://www.cs.nott.ac.uk/~gmh/bib.html#monparsing) to parse the binding vector and I'm not sure if that would make sense in clojure.core (Although I think so, since `for` isn't the only macro in core with a custom mini-parser). Regards, --Chris On 23 Okt., 21:18, Chouser chou...@gmail.com wrote: On Fri, Oct 23, 2009 at 3:16 PM, Howard Lewis Ship hls...@gmail.com wrote: I like to try and keep my level of nesting under control, and this often involves hiding or re-structuring the let macro. The for macro can implicitly assemble a let macro for you, but with a limitation that the :let clause can't be first: 1:5 user= (for [:let [z [:foo :bar]] x z] (name x)) java.lang.IllegalStateException: Can't pop empty vector (repl-1:5) 1:6 user= (for [x [:foo :bar] :let [z (name x)]] z) (foo bar) 1:7 user= Is this limitation intentional? Could the error message be improved? It's not an intentional limitation. One hint of this is that :let, :while, and :when all work perfectly fine at the beginning of a doseq. Improving the error message would be easy. On the other hand, a patch to support them at the beginning of a 'for' should be possible. I think it might be worthwhile, particulary for macros that generate 'for' forms. The machinery inside a 'for' expansion is hard to do yourself. Rich, would you consider a patch to support this? --Chouser --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Re: Why can't :let be first in a for
From my perspective, having the forms be flatter (less nested) and having the call to the extend-dom function be at the outermost level is the most readable. On Fri, Oct 23, 2009 at 1:20 PM, Meikel Brandmeyer m...@kotka.de wrote: Hi, Am 23.10.2009 um 21:16 schrieb Howard Lewis Ship: Here's what I wanted to write: (defn add-script-links-for-imported-javascript-libraries [env dom-nodes] (extend-dom dom-nodes [:html :head] :top (template-for [:let [aggregation (- env :cascade :resource- aggregation) libraries (@aggregation :libraries)] asset-map libraries :let [path (to-asset-path env asset-map)]] :script { :type text/javascript :src path } [ linebreak ]))) Why don't you just go one step further? (defn add-script-links-for-imported-javascript-libraries [env dom-nodes] (extend-dom dom-nodes [:html :head] :top (template-for [asset-map (- env :cascade :resource-aggregation deref :libraries) :let [path (to-asset-path env asset-map)]] :script { :type text/javascript :src path } [ linebreak ]))) But I had to juggle it to this: (defn add-script-links-for-imported-javascript-libraries [env dom-nodes] (let [aggregation (- env :cascade :resource-aggregation) libraries (@aggregation :libraries)] (extend-dom dom-nodes [:html :head] :top (template-for [asset-map libraries :let [path (to-asset-path env asset-map)]] :script { :type text/javascript :src path } [ linebreak ] Of course there are any number of ways to write this, but I prefer the first option, as it does less of a job of obscuring what the main point of the function is: a call to extend-dom. I don't see any obfuscation. Especially if you add a docstring Extend DOM with ... to the function. Sincerely Meikel -- 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 -~--~~~~--~~--~--~---
Why can't :let be first in a for
I like to try and keep my level of nesting under control, and this often involves hiding or re-structuring the let macro. The for macro can implicitly assemble a let macro for you, but with a limitation that the :let clause can't be first: 1:5 user= (for [:let [z [:foo :bar]] x z] (name x)) java.lang.IllegalStateException: Can't pop empty vector (repl-1:5) 1:6 user= (for [x [:foo :bar] :let [z (name x)]] z) (foo bar) 1:7 user= Is this limitation intentional? Could the error message be improved? Here's what I wanted to write: (defn add-script-links-for-imported-javascript-libraries [env dom-nodes] (extend-dom dom-nodes [:html :head] :top (template-for [:let [aggregation (- env :cascade :resource-aggregation) libraries (@aggregation :libraries)] asset-map libraries :let [path (to-asset-path env asset-map)]] :script { :type text/javascript :src path } [ linebreak ]))) (the formatting is probably scrambled) But I had to juggle it to this: (defn add-script-links-for-imported-javascript-libraries [env dom-nodes] (let [aggregation (- env :cascade :resource-aggregation) libraries (@aggregation :libraries)] (extend-dom dom-nodes [:html :head] :top (template-for [asset-map libraries :let [path (to-asset-path env asset-map)]] :script { :type text/javascript :src path } [ linebreak ] Of course there are any number of ways to write this, but I prefer the first option, as it does less of a job of obscuring what the main point of the function is: a call to extend-dom. -- 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 -~--~~~~--~~--~--~---
Re: Why can't :let be first in a for
On Fri, Oct 23, 2009 at 3:16 PM, Howard Lewis Ship hls...@gmail.com wrote: I like to try and keep my level of nesting under control, and this often involves hiding or re-structuring the let macro. The for macro can implicitly assemble a let macro for you, but with a limitation that the :let clause can't be first: 1:5 user= (for [:let [z [:foo :bar]] x z] (name x)) java.lang.IllegalStateException: Can't pop empty vector (repl-1:5) 1:6 user= (for [x [:foo :bar] :let [z (name x)]] z) (foo bar) 1:7 user= Is this limitation intentional? Could the error message be improved? It's not an intentional limitation. One hint of this is that :let, :while, and :when all work perfectly fine at the beginning of a doseq. Improving the error message would be easy. On the other hand, a patch to support them at the beginning of a 'for' should be possible. I think it might be worthwhile, particulary for macros that generate 'for' forms. The machinery inside a 'for' expansion is hard to do yourself. Rich, would you consider a patch to support this? --Chouser --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Re: Why can't :let be first in a for
Hi, Am 23.10.2009 um 21:16 schrieb Howard Lewis Ship: Here's what I wanted to write: (defn add-script-links-for-imported-javascript-libraries [env dom-nodes] (extend-dom dom-nodes [:html :head] :top (template-for [:let [aggregation (- env :cascade :resource- aggregation) libraries (@aggregation :libraries)] asset-map libraries :let [path (to-asset-path env asset-map)]] :script { :type text/javascript :src path } [ linebreak ]))) Why don't you just go one step further? (defn add-script-links-for-imported-javascript-libraries [env dom-nodes] (extend-dom dom-nodes [:html :head] :top (template-for [asset-map (- env :cascade :resource-aggregation deref :libraries) :let [path (to-asset-path env asset-map)]] :script { :type text/javascript :src path } [ linebreak ]))) But I had to juggle it to this: (defn add-script-links-for-imported-javascript-libraries [env dom-nodes] (let [aggregation (- env :cascade :resource-aggregation) libraries (@aggregation :libraries)] (extend-dom dom-nodes [:html :head] :top (template-for [asset-map libraries :let [path (to-asset-path env asset-map)]] :script { :type text/javascript :src path } [ linebreak ] Of course there are any number of ways to write this, but I prefer the first option, as it does less of a job of obscuring what the main point of the function is: a call to extend-dom. I don't see any obfuscation. Especially if you add a docstring Extend DOM with ... to the function. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature