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 <[email protected]>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 [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.