If this is something you do often, spyscope is a library I wrote to simplify this sort of investigation. You can print an expression by writing #spy/d in front of it. For more information, you can read at https://github.com/dgrnbrg/spyscope
On Tuesday, October 15, 2013 10:13:58 AM UTC-4, Brian Hurt wrote: > > Lifting subexpressions up into lets is actually something I do a lot- for > one very important reason: it lets me insert print statements (or logging > statements) showing the value of the subexpression. So I'll do; > (let [ x (subexpression) ] > (main-expression)) > > because it lets me do: > (let [ x (subexpression) ] > (println "The value of x is" x) > (main-expression)) > > If fact, a lot of times I'll do; > (let [ x (subexpression) > res (main-expression) ] > res) > > because it lets me do: > (let [ x (subexpression) > _ (println "The value of x is" x) > res (main-expression) ] > (println "The value of the whole expression is" res) > res) > > This is of great value in debugging. > > Brian > > > > On Tue, Oct 15, 2013 at 9:56 AM, Mikera <mike.r.an...@gmail.com<javascript:> > > wrote: > >> I certainly prefer giving names to intermediate results with a "let" >> block: having good names and breaking the computation up into logical >> chunks makes the code much easier to understand and maintain when you come >> back to it later. >> >> PG's example though is bad for different reasons - this is actually >> mutating variables in an imperative style, which is definitely "bad style" >> - both in Lisp and Clojure I think. The Clojure equivalent would be to use >> atoms (or vars) and mutating them. >> >> "let" on its own is purely functional, and doesn't have this problem. >> >> >> On Tuesday, 15 October 2013 20:29:29 UTC+8, Daniel Higginbotham wrote: >>> >>> I've been going through On Lisp by Paul Graham and on page 33 he >>> recommends against performing "intermediate" bindings. Does this advice >>> hold for Clojure? Here are a couple examples: >>> >>> ;; Common Lisp (from the book) >>> (defun bad (x) >>> (let (y sqr) >>> (setq y (car x)) >>> (setq sqr (expt y 2)) >>> (list 'a sqr))) >>> >>> (defun good (x) >>> (list 'a (expt (car x) 2))) >>> >>> ;; Clojure >>> (defn bad [x] >>> (let [y (first x) >>> sqr (expt y 2)] >>> (list 'a sqr))) >>> >>> (defn good [x] >>> (list 'a (expt (first x) 2))) >>> >>> Paul Graham explains: >>> >>> "The final result is shorter than what we began with, and easier to >>> understand. In the original code, we’re faced with the final expression >>> (list 'a sqr), and it’s not immediately clear where the value of sqr comes >>> from. Now the source of the return value is laid out for us like a road >>> map. >>> >>> The example in this section was a short one, but the technique scales >>> up. Indeed, it becomes more valuable as it is applied to larger functions." >>> >>> In clojure you can't do setq of course but I find myself going against >>> this advice all the time, and I find that it's more important to do so when >>> working with larger functions. I think introducing names makes code >>> clearer. Here's an example from my own code: >>> >>> (defn create-topic >>> [params] >>> (let [params (merge params (db/tempids :topic-id :post-id :watch-id)) >>> topic (remove-nils-from-map (c/mapify params mr/topic->txdata)) >>> watch (c/mapify params mr/watch->txdata) >>> post (c/mapify params mr/post->txdata)] >>> {:result (db/t [topic post watch]) >>> :tempid (:topic-id params)})) >>> >>> To my mind, creating bindings for "topic", "watch", and "post" makes the >>> code easier to understand. When you get to "(db/t [topic post watch])" you >>> don't have to deal with as much visual noise to understand exactly what's >>> going into the transaction. >>> >>> So, is PG's advice any good? >>> >>> Thanks! >>> Daniel >> >> -- >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clo...@googlegroups.com<javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+u...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/groups/opt_out. >> > > -- -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.