Re: is PG's imperative outside-in advice any good?

2013-10-17 Thread Benny Tsai
For those who use clojure.tools.logging, there's also the handy spy 
function.

On Tuesday, October 15, 2013 6:41:38 PM UTC-7, dgrnbrg wrote:

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

Re: is PG's imperative outside-in advice any good?

2013-10-17 Thread Mars0i
In CL, `let*` works like Clojure's `let`, in that both allow you to bind 
later variables to valued calculated from earlier ones.  (CL's `let` only 
allows references to things defined before entering the `let`.)  A couple 
of years ago I was hacking on some CL code originally written by someone 
else, with a lot of `let*`s in it.  I started adding bindings, and them 
more, and after a while I just could not make it work.  The order of 
bindings was crucial, and the right hand sides were referring to multiple 
variables bound elsewhere in the `let*`.  It was driving me crazy.  I 
realized that the whole thing I'd created was an instance of bad coding 
style.I just pulled things apart and put the code into separate 
functions that called each other.   And I replaced all of my `do*`s (loops 
with bindings that can refer to each other) with `mapcar` or `mapc` (like 
Clojure's `map`).  Much clearer.  

I now try to avoid `let*` as much as possible in CL, and when I use it, I 
make sure that I keep things simple.  I'm just learning Clojure.  I'm not 
going to avoid `let`, but I will try to make sure that I use it carefully.  
I agree with other posters here that sometimes code is clearer and easier 
to understand if it's broken into sequential bindings, but it depends.  I 
think that often it's better to use a series of separate function calls 
instead of a big `let`.  I would say that for me, a good rule of thumb is 
that a `let` should bind no more than four or five variables, maximum, and 
that if there are more variables, their rhs's should usually refer only to 
the variable defined on the previous line.  Otherwise it's too hard to keep 
track of the dependencies.

Maybe the right thing to say is: Follow PG's rule, except when it's better 
to break it.  And then keep it simple.

Those aren't rules that anyone else has to follow, of course.  Do what 
works for you.  This is how I think about it.

On Tuesday, October 15, 2013 7:29:29 AM UTC-5, 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 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.


is PG's imperative outside-in advice any good?

2013-10-15 Thread Daniel Higginbotham
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 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.


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Brian Hurt
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.anderson...@gmail.comwrote:

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


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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Raoul Duke
if a programming language doesn't have something like 'where', then i
am sad. http://stackoverflow.com/questions/4362328/haskell-where-vs-let

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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Alex Baranosky
I and some of my coworkers do tend to avoid `let` unless in this particular
case you especially want to emphasize the name of something unobvious.
OFten I'd prefer to pull out a new function over using let, or inline the
binding for readability *improvement*.


On Tue, Oct 15, 2013 at 8:18 AM, Raoul Duke rao...@gmail.com wrote:

 if a programming language doesn't have something like 'where', then i
 am sad. http://stackoverflow.com/questions/4362328/haskell-where-vs-let

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


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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Sean Corfield
Yeah, I found when I first got started with Clojure I tended to use
let for intermediate named results but over time I've moved to using
small, private top-level functions instead because I want to focus on
the names of the _functionality_ rather than the names of intermediate
_data_. I still use let for some things but nowhere near as much as I
used to.

One construct using let that I see in my code quite a bit that I
haven't figured out a cleaner way to express:

(let [x (some-expression)]
  (if (p x)
(f x)
(g x)))

I get tempted to write a utility function for it but I haven't come up
with a good name for it :)

Sean

On Tue, Oct 15, 2013 at 9:00 AM, Alex Baranosky
alexander.barano...@gmail.com wrote:
 I and some of my coworkers do tend to avoid `let` unless in this particular
 case you especially want to emphasize the name of something unobvious. OFten
 I'd prefer to pull out a new function over using let, or inline the binding
 for readability *improvement*.


 On Tue, Oct 15, 2013 at 8:18 AM, Raoul Duke rao...@gmail.com wrote:

 if a programming language doesn't have something like 'where', then i
 am sad. http://stackoverflow.com/questions/4362328/haskell-where-vs-let

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


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



-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Perfection is the enemy of the good.
-- Gustave Flaubert, French realist novelist (1821-1880)

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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Marcus Lindner

How looks this?

(defn conditional [x condition consequent alternative]
  (if (condition x)
(consequent x)
(alternative x

(conditional (some-expression) p f g)



Am 15.10.2013 19:02, schrieb Sean Corfield:


Yeah, I found when I first got started with Clojure I tended to use
let for intermediate named results but over time I've moved to using
small, private top-level functions instead because I want to focus on
the names of the _functionality_ rather than the names of intermediate
_data_. I still use let for some things but nowhere near as much as I
used to.

One construct using let that I see in my code quite a bit that I
haven't figured out a cleaner way to express:

(let [x (some-expression)]
   (if (p x)
 (f x)
 (g x)))

I get tempted to write a utility function for it but I haven't come up
with a good name for it :)

Sean

On Tue, Oct 15, 2013 at 9:00 AM, Alex Baranosky
alexander.barano...@gmail.com wrote:

I and some of my coworkers do tend to avoid `let` unless in this particular
case you especially want to emphasize the name of something unobvious. OFten
I'd prefer to pull out a new function over using let, or inline the binding
for readability *improvement*.


On Tue, Oct 15, 2013 at 8:18 AM, Raoul Duke rao...@gmail.com wrote:

if a programming language doesn't have something like 'where', then i
am sad. http://stackoverflow.com/questions/4362328/haskell-where-vs-let

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


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





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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Guru Devanla
Sean,

The case you listed is where let binding becomes important so as to not
perform duplicate evaluation. That is one place the utility of let stands
out along with its scope.

For example

Without let bindings:

  (if (p (some-expression))
(f (some-expression))
(g (some-expression))

introduces duplicate evaluation.  I see the utility of let more in such
scenarios.  Whereas in the original PGs example that is not the case, and
debate on that stands.


On Tue, Oct 15, 2013 at 10:02 AM, Sean Corfield seancorfi...@gmail.comwrote:

 Yeah, I found when I first got started with Clojure I tended to use
 let for intermediate named results but over time I've moved to using
 small, private top-level functions instead because I want to focus on
 the names of the _functionality_ rather than the names of intermediate
 _data_. I still use let for some things but nowhere near as much as I
 used to.

 One construct using let that I see in my code quite a bit that I
 haven't figured out a cleaner way to express:

 (let [x (some-expression)]
   (if (p x)
 (f x)
 (g x)))

 I get tempted to write a utility function for it but I haven't come up
 with a good name for it :)

 Sean

 On Tue, Oct 15, 2013 at 9:00 AM, Alex Baranosky
 alexander.barano...@gmail.com wrote:
  I and some of my coworkers do tend to avoid `let` unless in this
 particular
  case you especially want to emphasize the name of something unobvious.
 OFten
  I'd prefer to pull out a new function over using let, or inline the
 binding
  for readability *improvement*.
 
 
  On Tue, Oct 15, 2013 at 8:18 AM, Raoul Duke rao...@gmail.com wrote:
 
  if a programming language doesn't have something like 'where', then i
  am sad. http://stackoverflow.com/questions/4362328/haskell-where-vs-let
 
  --
  --
  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.
 
 
  --
  --
  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.



 --
 Sean A Corfield -- (904) 302-SEAN
 An Architect's View -- http://corfield.org/
 World Singles, LLC. -- http://worldsingles.com/

 Perfection is the enemy of the good.
 -- Gustave Flaubert, French realist novelist (1821-1880)

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


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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Sean Corfield
I know how to write it but I just don't like that name (or any other
I've come up with yet). And I'd probably put the `x` as the last
argument and provide a curried version.

On Tue, Oct 15, 2013 at 10:13 AM, Marcus Lindner
marcus.goldritter.lind...@gmail.com wrote:
 How looks this?

 (defn conditional [x condition consequent alternative]
   (if (condition x)
 (consequent x)
 (alternative x

 (conditional (some-expression) p f g)



 Am 15.10.2013 19:02, schrieb Sean Corfield:


 Yeah, I found when I first got started with Clojure I tended to use
 let for intermediate named results but over time I've moved to using
 small, private top-level functions instead because I want to focus on
 the names of the _functionality_ rather than the names of intermediate
 _data_. I still use let for some things but nowhere near as much as I
 used to.

 One construct using let that I see in my code quite a bit that I
 haven't figured out a cleaner way to express:

 (let [x (some-expression)]
(if (p x)
  (f x)
  (g x)))

 I get tempted to write a utility function for it but I haven't come up
 with a good name for it :)

 Sean

 On Tue, Oct 15, 2013 at 9:00 AM, Alex Baranosky
 alexander.barano...@gmail.com wrote:

 I and some of my coworkers do tend to avoid `let` unless in this
 particular
 case you especially want to emphasize the name of something unobvious.
 OFten
 I'd prefer to pull out a new function over using let, or inline the
 binding
 for readability *improvement*.


 On Tue, Oct 15, 2013 at 8:18 AM, Raoul Duke rao...@gmail.com wrote:

 if a programming language doesn't have something like 'where', then i
 am sad. http://stackoverflow.com/questions/4362328/haskell-where-vs-let

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


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




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



-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Perfection is the enemy of the good.
-- Gustave Flaubert, French realist novelist (1821-1880)

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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Sean Corfield
On Tue, Oct 15, 2013 at 10:15 AM, Guru Devanla grd...@gmail.com wrote:
 The case you listed is where let binding becomes important so as to not
 perform duplicate evaluation. That is one place the utility of let stands
 out along with its scope.

Yup, exactly. I just see it often enough that I feel that it should be
codified somehow...
-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Perfection is the enemy of the good.
-- Gustave Flaubert, French realist novelist (1821-1880)

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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Jim - FooBar();

On 15/10/13 18:02, Sean Corfield wrote:

One construct using let that I see in my code quite a bit that I
haven't figured out a cleaner way to express:

(let [x (some-expression)]
   (if (p x)
 (f x)
 (g x)))



wasn't cond- designed exactly for that?

(let [x (some-expression)]
(cond- x
(p x) f
((comlpement p) x) g)))

Jim

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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Sean Corfield
On Tue, Oct 15, 2013 at 10:19 AM, Jim - FooBar(); jimpil1...@gmail.com wrote:
 wasn't cond- designed exactly for that?

 (let [x (some-expression)]
 (cond- x
 (p x) f
 ((comlpement p) x) g)))

That's uglier than the if :)

Sometimes I wish there was a variant of cond- that took functions
instead of boolean expressions and threaded the expression thru those
(just to wander further off-topic)...
-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Perfection is the enemy of the good.
-- Gustave Flaubert, French realist novelist (1821-1880)

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


RE: is PG's imperative outside-in advice any good?

2013-10-15 Thread Phillip Lord

What about  let-some-expression-if-then-else?



From: clojure@googlegroups.com [clojure@googlegroups.com] on behalf of Sean 
Corfield [seancorfi...@gmail.com]
Sent: 15 October 2013 18:02
To: clojure@googlegroups.com
Subject: Re: is PG's imperative outside-in advice any good?

Yeah, I found when I first got started with Clojure I tended to use
let for intermediate named results but over time I've moved to using
small, private top-level functions instead because I want to focus on
the names of the _functionality_ rather than the names of intermediate
_data_. I still use let for some things but nowhere near as much as I
used to.

One construct using let that I see in my code quite a bit that I
haven't figured out a cleaner way to express:

(let [x (some-expression)]
  (if (p x)
(f x)
(g x)))

I get tempted to write a utility function for it but I haven't come up
with a good name for it :)

Sean

On Tue, Oct 15, 2013 at 9:00 AM, Alex Baranosky
alexander.barano...@gmail.com wrote:
 I and some of my coworkers do tend to avoid `let` unless in this particular
 case you especially want to emphasize the name of something unobvious. OFten
 I'd prefer to pull out a new function over using let, or inline the binding
 for readability *improvement*.


 On Tue, Oct 15, 2013 at 8:18 AM, Raoul Duke rao...@gmail.com wrote:

 if a programming language doesn't have something like 'where', then i
 am sad. http://stackoverflow.com/questions/4362328/haskell-where-vs-let

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


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



--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Perfection is the enemy of the good.
-- Gustave Flaubert, French realist novelist (1821-1880)

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

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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Ben Wolfson
On Tue, Oct 15, 2013 at 10:48 AM, Sean Corfield seancorfi...@gmail.comwrote:

 On Tue, Oct 15, 2013 at 10:19 AM, Jim - FooBar(); jimpil1...@gmail.com
 wrote:
  wasn't cond- designed exactly for that?
 
  (let [x (some-expression)]
  (cond- x
  (p x) f
  ((comlpement p) x) g)))

 That's uglier than the if :)


Also less efficient, since it may require evaluating (p x) twice.

If it were me, I'd use something like this:

(defn either
   Return a function that takes one argument, x, and returns (f x) if (p
x) is truthy and (g x) otherwise.
   [p f g]
   (fn [x] (if (p x) (f x) (g x

-- 
Ben Wolfson
Human kind has used its intelligence to vary the flavour of drinks, which
may be sweet, aromatic, fermented or spirit-based. ... Family and social
life also offer numerous other occasions to consume drinks for pleasure.
[Larousse, Drink entry]

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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Bob Hutchison

On 2013-10-15, at 8:29 AM, Daniel Higginbotham nonrecurs...@gmail.com 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)))

The closest I can think of to the bad CL code in Clojure would be something 
like:

(defn bad-clojure [x]
  (let [v (first x)
v (Math/pow v 2)
v (list 'a v)]
v))   

I don't think anyone at all would find either the bad CL or Clojure code okay. 
This is more of an admonition to not be an idiot :-)

Your Clojure code is equivalent to the following CL code:

(defun good2 (x)
  (let* ((y (car x))
 (sqr (expt y 2)))
(list 'a sqr)))

There's nothing wrong with writing code that way, it's functional and clear. 
What you're doing with this style of writing is introducing intermediate named 
values. Sometimes those just clutter up the code, sometimes they clarify. Use 
your own good taste. You'd do the same thing in Haskell, but I'd use a where 
clause.

 
 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.

Yes, in the bad CL code you don't know where the value of sqr comes from and 
the problem gets much worse as the code gets longer. This is the problem with 
imperative code in general.

You don't have that problem in either Clojure or the 'good2' CL program.

 
 In clojure you can't do setq of course but I find myself going against this 
 advice all the time

He's not talking about intermediate names for values, he's talking about 
imperative assignments using setq, setf, and friends. Clojure's nearest 
equivalent, that I can think of, is shadowing in a let statement, and I think 
you'll find this is frowned upon.

 So, is PG's advice any good?

Yup.

Cheers,
Bob

 
 Thanks!
 Daniel
 
 -- 
 -- 
 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.

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


Re: is PG's imperative outside-in advice any good?

2013-10-15 Thread Daniel Higginbotham
Thanks for all the responses! 

This discussion will definitely help me write better code. This was 
especially helpful:

over time I've moved to using 
 small, private top-level functions instead because I want to focus on 
 the names of the _functionality_ rather than the names of intermediate 
 _data_


As was this:

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)


Thanks!
Daniel

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