* Always using let* @ 2014-09-14 19:46 Cecil Westerhof 2014-09-14 21:25 ` Drew Adams ` (2 more replies) 0 siblings, 3 replies; 32+ messages in thread From: Cecil Westerhof @ 2014-09-14 19:46 UTC (permalink / raw) To: help-gnu-emacs Would it be OK to always use let*? I was just bitten by the fact that with let you can not previous variables from the let statement, as is possible with setq. So I am thinking about always using let*, so I do not have to think about it. Or are there good reasons to use let when you do not need let*? -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: Always using let* 2014-09-14 19:46 Always using let* Cecil Westerhof @ 2014-09-14 21:25 ` Drew Adams 2014-09-15 16:15 ` Drew Adams [not found] ` <mailman.8924.1410797740.1147.help-gnu-emacs@gnu.org> 2014-09-14 21:40 ` Joe Fineman [not found] ` <mailman.8868.1410729956.1147.help-gnu-emacs@gnu.org> 2 siblings, 2 replies; 32+ messages in thread From: Drew Adams @ 2014-09-14 21:25 UTC (permalink / raw) To: Cecil Westerhof, help-gnu-emacs > Would it be OK to always use let*? I was just bitten by the fact > that with let you can not previous variables from the let statement, > as is possible with setq. So I am thinking about always using let*, > so I do not have to think about it. Or are there good reasons to use > let when you do not need let*? The most common reason is when you want to use a variable value in the cadr of a binding and you do *not* want to pick up the variable's newly bound value. IOW, precisely the opposite use case of what you wanted when you were bit. (setq c 3) (let ((c (+ c 4)) (b (* c 42))) ; Use original C value: 3 ...) (The other reason is that for some Lisps the bindings of `let' can be done in parallel, which can be quicker.) ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: Always using let* 2014-09-14 21:25 ` Drew Adams @ 2014-09-15 16:15 ` Drew Adams [not found] ` <mailman.8924.1410797740.1147.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 32+ messages in thread From: Drew Adams @ 2014-09-15 16:15 UTC (permalink / raw) To: Cecil Westerhof, help-gnu-emacs > > Would it be OK to always use let*? I was just bitten by the fact > > that with let you can not previous variables from the let > > statement, as is possible with setq. So I am thinking about always > > using let*, so I do not have to think about it. Or are there good > > reasons to use let when you do not need let*? > > The most common reason is when you want to use a variable value > in the cadr of a binding and you do *not* want to pick up the > variable's newly bound value. IOW, precisely the opposite use > case of what you wanted when you were bit. > > (setq c 3) > (let ((c (+ c 4)) (b (* c 42))) ; Use original C value: 3 ...) I should point out another reason why some people, including me, might use one or the other: To help humans read the code. When I use `let' I communicate that none of the bindings depend on earlier bindings. (The bindings are independent, which does not imply that their values are.) In particular, when a variable appears in the right side of a binding expression it is not a variable that is bound by that `let' (it may be the same symbol, but it is a different variable). In sum: If I use `let*' then look for a binding dependency. If I use `let' then don't bother to look for one. If the actual behavior of the code does not correspond to that message then the code is bugged. The point of such a convention is that a reader can more easily and quickly understand the code wrt my intention. And yes, this does mean that I end up editing the code, changing some `let's to `let*'s later, and vice versa, as it evolves. I am *not* trying to minimize my effort when writing code ("so I do not have to think about it" is misguided, IMHO). I am instead trying to minimize (human) reader effort - my code is not just about me. And yet I benefit from this more than anyone else, as I am the main reader. (And if others can more easily read it then I benefit from their better bug reports.) It's easy to write code. It's harder to understand code you have not written (just now) and to modify it without screwing things up. Yes, it's a minor consideration, but it is one that affects how I code, at least. YMMV. ^ permalink raw reply [flat|nested] 32+ messages in thread
[parent not found: <mailman.8924.1410797740.1147.help-gnu-emacs@gnu.org>]
* Re: Always using let* [not found] ` <mailman.8924.1410797740.1147.help-gnu-emacs@gnu.org> @ 2014-09-15 18:01 ` Cecil Westerhof 2014-09-15 22:20 ` Emanuel Berg 2014-09-16 14:23 ` sokobania.01 1 sibling, 1 reply; 32+ messages in thread From: Cecil Westerhof @ 2014-09-15 18:01 UTC (permalink / raw) To: help-gnu-emacs Op Monday 15 Sep 2014 18:15 CEST schreef Drew Adams: > I am *not* trying to minimize my effort when writing code ("so I > do not have to think about it" is misguided, IMHO). I am instead > trying to minimize (human) reader effort - my code is not just > about me. And yet I benefit from this more than anyone else, as > I am the main reader. (And if others can more easily read it > then I benefit from their better bug reports.) > > It's easy to write code. It's harder to understand code you have > not written (just now) and to modify it without screwing things up. > > Yes, it's a minor consideration, but it is one that affects how > I code, at least. YMMV. A good point. Writing code is 20% of the time and reading 80%. (Or so I am told.) But most of the time there is emphasis on speed of writing, not on easy maintenance. You made me think again and changed my mind. :-D -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-15 18:01 ` Cecil Westerhof @ 2014-09-15 22:20 ` Emanuel Berg 2014-09-16 12:05 ` Cecil Westerhof 0 siblings, 1 reply; 32+ messages in thread From: Emanuel Berg @ 2014-09-15 22:20 UTC (permalink / raw) To: help-gnu-emacs Cecil Westerhof <Cecil@decebal.nl> writes: > A good point. Writing code is 20% of the time and > reading 80%. (Or so I am told.) No, that all depends. For a small or medium-size project with one developer, he will know his code so well even maintaining it will basically be "writing time", as he will know exactly where to change the code the moment an error occur. > But most of the time there is emphasis on speed of > writing, not on easy maintenance. You mean with silly books? "Write powerful programs with C++ fast!" I don't think there is an emphasis on speed but if there were I would support it because contrary to what many people think doing things fast almost always means doing them better. When you do things fast you trigger your brain to perform the most. The people who run the best, are the people who run the fastest! There is no contradiction between typing code fast and having maintainable code. -- underground experts united ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-15 22:20 ` Emanuel Berg @ 2014-09-16 12:05 ` Cecil Westerhof 2014-09-16 22:40 ` Emanuel Berg 0 siblings, 1 reply; 32+ messages in thread From: Cecil Westerhof @ 2014-09-16 12:05 UTC (permalink / raw) To: help-gnu-emacs Op Tuesday 16 Sep 2014 00:20 CEST schreef Emanuel Berg: >> But most of the time there is emphasis on speed of >> writing, not on easy maintenance. > > You mean with silly books? "Write powerful programs > with C++ fast!" No, I mean in the development of software. My experience is that almost always the deadlines are to tight and there is only regard for delivering as soon as possible, to keep the run-over as short as possible. Taking some time to make it easier for someone else (but also yourself) to maintain the program later on, would be in my opinion a very wise investment. Something I also often heard (but to be honest less often, so there is improvement): we never have time to do it correctly, but we always have time to mend the bugs. I would think that delivering software with less bugs (no bugs is impossible) would be more time efficient. > I don't think there is an emphasis on speed but if > there were I would support it because contrary to what > many people think doing things fast almost always means > doing them better. When you do things fast you trigger > your brain to perform the most. The people who run the > best, are the people who run the fastest! > > There is no contradiction between typing code fast and > having maintainable code. Typing code fast is no problem, writing code fast could. To quote Abraham Lincoln: If I had eight hours to chop down a tree, I would spend six sharpening my axe. Three quarters is maybe a bit much, but I agree with the gist. -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-16 12:05 ` Cecil Westerhof @ 2014-09-16 22:40 ` Emanuel Berg 2014-09-18 17:02 ` Cecil Westerhof 0 siblings, 1 reply; 32+ messages in thread From: Emanuel Berg @ 2014-09-16 22:40 UTC (permalink / raw) To: help-gnu-emacs Cecil Westerhof <Cecil@decebal.nl> writes: > No, I mean in the development of software. My > experience is that almost always the deadlines are to > tight and there is only regard for delivering as soon > as possible, to keep the run-over as short as > possible. Taking some time to make it easier for > someone else (but also yourself) to maintain the > program later on, would be in my opinion a very wise > investment. > > Something I also often heard (but to be honest less > often, so there is improvement): we never have time > to do it correctly, but we always have time to mend > the bugs. I would think that delivering software with > less bugs (no bugs is impossible) would be more time > efficient. Indeed, deadlines are a joke and they are often setup by people who have no understanding of the work itself. Things get done when they get done. Simple as that. Example: Windows 95 was intended to be ship as "Windows 93" :) > Typing code fast is no problem, writing code fast > could. What is the difference between typing code fast and writing code fast? > To quote Abraham Lincoln: If I had eight hours to > chop down a tree, I would spend six sharpening my > axe. What's wrong with that? What would you do? Chop it down instantly and then sit idle for seven hours? Better bring a book and a deck of cards in that case. -- underground experts united ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-16 22:40 ` Emanuel Berg @ 2014-09-18 17:02 ` Cecil Westerhof 2014-09-18 21:05 ` Emanuel Berg 0 siblings, 1 reply; 32+ messages in thread From: Cecil Westerhof @ 2014-09-18 17:02 UTC (permalink / raw) To: help-gnu-emacs Op Wednesday 17 Sep 2014 00:40 CEST schreef Emanuel Berg: >> Typing code fast is no problem, writing code fast >> could. > > What is the difference between typing code fast and > writing code fast? With writing code I mean the intellectual/creative part. With typing code I mean entering the code. >> To quote Abraham Lincoln: If I had eight hours to >> chop down a tree, I would spend six sharpening my >> axe. > > What's wrong with that? What would you do? Chop it down > instantly and then sit idle for seven hours? Better > bring a book and a deck of cards in that case. Nothing wrong with that: I tried to use it to underwrite my point. But probably not in a clear enough way. -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-18 17:02 ` Cecil Westerhof @ 2014-09-18 21:05 ` Emanuel Berg 0 siblings, 0 replies; 32+ messages in thread From: Emanuel Berg @ 2014-09-18 21:05 UTC (permalink / raw) To: help-gnu-emacs Cecil Westerhof <Cecil@decebal.nl> writes: > With writing code I mean the intellectual/creative > part. With typing code I mean entering the code. Those are the same: the body is a brain and the brain is part of the body. -- underground experts united ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* [not found] ` <mailman.8924.1410797740.1147.help-gnu-emacs@gnu.org> 2014-09-15 18:01 ` Cecil Westerhof @ 2014-09-16 14:23 ` sokobania.01 2014-09-16 16:41 ` Drew Adams ` (3 more replies) 1 sibling, 4 replies; 32+ messages in thread From: sokobania.01 @ 2014-09-16 14:23 UTC (permalink / raw) To: help-gnu-emacs Le lundi 15 septembre 2014 18:15:14 UTC+2, Drew Adams a écrit : > In sum: If I use `let*' then look for a binding dependency. > If I use `let' then don't bother to look for one. I agree. Some cases are intermediate. If I have several variables with "enough" binding dependency, I use "let*". But, quite often, I have several independent variable, except one or two. So, I would use "let" rather than "let*", but don't bind these variables and then use "setq" in the body of the let: (let ((a (val-for-a)) (b (val-for-b)) ... x y) ; depend on a b (setq x (val-for-x a b)) (setq y (val-for-y a b)) ... ) ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: Always using let* 2014-09-16 14:23 ` sokobania.01 @ 2014-09-16 16:41 ` Drew Adams 2014-09-16 20:49 ` Stefan Monnier ` (2 subsequent siblings) 3 siblings, 0 replies; 32+ messages in thread From: Drew Adams @ 2014-09-16 16:41 UTC (permalink / raw) To: sokobania.01, help-gnu-emacs > > In sum: If I use `let*' then look for a binding dependency. > > If I use `let' then don't bother to look for one. > > I agree. > > Some cases are intermediate. If I have several variables with "enough" > binding dependency, I use "let*". > > But, quite often, I have several independent variable, except one or > two. So, I would use "let" rather than "let*", but don't bind these > variables and then use "setq" in the body of the let: > > (let ((a (val-for-a)) > (b (val-for-b)) > ... > x y) ; depend on a b > (setq x (val-for-x a b)) > (setq y (val-for-y a b)) > ...) Yup. Me too. Especially if any processing needs to be done after the bindings and before the assignments (setq). ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-16 14:23 ` sokobania.01 2014-09-16 16:41 ` Drew Adams @ 2014-09-16 20:49 ` Stefan Monnier 2014-09-16 22:45 ` Emanuel Berg [not found] ` <mailman.8998.1410901776.1147.help-gnu-emacs@gnu.org> 3 siblings, 0 replies; 32+ messages in thread From: Stefan Monnier @ 2014-09-16 20:49 UTC (permalink / raw) To: help-gnu-emacs > But, quite often, I have several independent variable, except one or two. > So, I would use "let" rather than "let*", but don't bind these variables > and then use "setq" in the body of the let: > (let ((a (val-for-a)) > (b (val-for-b)) > ... > x y) ; depend on a b > (setq x (val-for-x a b)) > (setq y (val-for-y a b)) > ... In some cases, `setq' can't be easily avoided, but otherwise, I strongly recommend let* over let+setq. If it depended on me, I'd swap the two since in most cases you could use let*, it's very rare to really need `let'. Stefan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-16 14:23 ` sokobania.01 2014-09-16 16:41 ` Drew Adams 2014-09-16 20:49 ` Stefan Monnier @ 2014-09-16 22:45 ` Emanuel Berg [not found] ` <mailman.8998.1410901776.1147.help-gnu-emacs@gnu.org> 3 siblings, 0 replies; 32+ messages in thread From: Emanuel Berg @ 2014-09-16 22:45 UTC (permalink / raw) To: help-gnu-emacs sokobania.01@gmail.com writes: > If I have several variables with "enough" binding > dependency, I use "let*". > > But, quite often, I have several independent > variable, except one or two. So, I would use "let" > rather than "let*", but don't bind these variables > and then use "setq" in the body of the let: (let ((a > (val-for-a)) (b (val-for-b)) ... x y) ; depend on a b > (setq x (val-for-x a b)) (setq y (val-for-y a b)) ... > ) Why not use the let* for everything? Or nest a the let* and let - perhaps overkill... Because I don't see anything wrong with "independent variables" in let* (?). As long as there is one data item that is dependant - otherwise people reading the code will be confused why the asterisk is there, and start to look for it... -- underground experts united ^ permalink raw reply [flat|nested] 32+ messages in thread
[parent not found: <mailman.8998.1410901776.1147.help-gnu-emacs@gnu.org>]
* Re: Always using let* [not found] ` <mailman.8998.1410901776.1147.help-gnu-emacs@gnu.org> @ 2014-09-16 22:48 ` Emanuel Berg 2014-09-17 1:09 ` Stefan Monnier 0 siblings, 1 reply; 32+ messages in thread From: Emanuel Berg @ 2014-09-16 22:48 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier <monnier@iro.umontreal.ca> writes: > In some cases, `setq' can't be easily avoided, but > otherwise, I strongly recommend let* over let+setq. Absolutely, it totally goes against my instinct to use let and then setq! > If it depended on me, I'd swap the two since in most > cases you could use let*, it's very rare to really > need `let'. You mean "let, and not let*?" Because I use let all the time and I don't think that is uncommon. -- underground experts united ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-16 22:48 ` Emanuel Berg @ 2014-09-17 1:09 ` Stefan Monnier 2014-09-17 1:18 ` Emanuel Berg 0 siblings, 1 reply; 32+ messages in thread From: Stefan Monnier @ 2014-09-17 1:09 UTC (permalink / raw) To: help-gnu-emacs > You mean "let, and not let*?" Because I use let all the > time and I don't think that is uncommon. No, I don't think I made a typo: you could remove `let' from Elisp and it would be pretty easy to rewrite all the code to use let* instead. In 99% of the cases it's just a matter of adding a *. Stefan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-17 1:09 ` Stefan Monnier @ 2014-09-17 1:18 ` Emanuel Berg 0 siblings, 0 replies; 32+ messages in thread From: Emanuel Berg @ 2014-09-17 1:18 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier <monnier@iro.umontreal.ca> writes: >> You mean "let, and not let*?" Because I use let all >> the time and I don't think that is uncommon. > > No, I don't think I made a typo: you could remove > `let' from Elisp and it would be pretty easy to > rewrite all the code to use let* instead. In 99% of > the cases it's just a matter of adding a *. Yes, that's what I mean, you mean, let and only let (i.e., not let*), because let's functionality is covered by let* as well. -- underground experts united ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-14 19:46 Always using let* Cecil Westerhof 2014-09-14 21:25 ` Drew Adams @ 2014-09-14 21:40 ` Joe Fineman [not found] ` <mailman.8868.1410729956.1147.help-gnu-emacs@gnu.org> 2 siblings, 0 replies; 32+ messages in thread From: Joe Fineman @ 2014-09-14 21:40 UTC (permalink / raw) To: help-gnu-emacs Cecil Westerhof <Cecil@decebal.nl> writes: > Would it be OK to always use let*? I was just bitten by the fact that > with let you can not previous variables from the let statement, as is ^^^^^^^^^^^^^^^^^^^^^^^^^^ Word missing? > possible with setq. So I am thinking about always using let*, so I do > not have to think about it. Or are there good reasons to use let when > you do not need let*? -- --- Joe Fineman joe_f@verizon.net ||: The way out is the way in. :|| ^ permalink raw reply [flat|nested] 32+ messages in thread
[parent not found: <mailman.8868.1410729956.1147.help-gnu-emacs@gnu.org>]
* Re: Always using let* [not found] ` <mailman.8868.1410729956.1147.help-gnu-emacs@gnu.org> @ 2014-09-14 21:41 ` Emanuel Berg 2014-09-14 22:11 ` Cecil Westerhof 2014-09-14 22:41 ` Stefan Monnier 2 siblings, 0 replies; 32+ messages in thread From: Emanuel Berg @ 2014-09-14 21:41 UTC (permalink / raw) To: help-gnu-emacs Drew Adams <drew.adams@oracle.com> writes: >> Would it be OK to always use let*? I was just bitten >> by the fact that with let you can not previous >> variables from the let statement, as is possible >> with setq. So I am thinking about always using let*, >> so I do not have to think about it. Or are there >> good reasons to use let when you do not need let*? > > The most common reason is when you want to use a > variable value in the cadr of a binding and you do > *not* want to pick up the variable's newly bound > value. IOW, precisely the opposite use case of what > you wanted when you were bit. > > (setq c 3) > > (let ((c (+ c 4)) (b (* c 42))) Correct, but isn't that only confusing style? Isn't it better to call the c in the let something else? The only reason I don't always use let* is that it is slower type, looks awkward, and that other people reading the code will wonder: "why `let*'? there is nothing reoccurring!" > (The other reason is that for some Lisps the bindings > of `let' can be done in parallel, which can be > quicker.) Oh yeah?! Like parallel on a multicore computer? I only have single CPU so I can't test but that would be downright awesome. However let* could also in part run in parallel for the clauses that don't have precedence constraints (i.e., for wich the let* isn't necessary). -- underground experts united ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* [not found] ` <mailman.8868.1410729956.1147.help-gnu-emacs@gnu.org> 2014-09-14 21:41 ` Emanuel Berg @ 2014-09-14 22:11 ` Cecil Westerhof 2014-09-14 22:56 ` Drew Adams 2014-09-14 22:41 ` Stefan Monnier 2 siblings, 1 reply; 32+ messages in thread From: Cecil Westerhof @ 2014-09-14 22:11 UTC (permalink / raw) To: help-gnu-emacs Op Sunday 14 Sep 2014 23:25 CEST schreef Drew Adams: >> Would it be OK to always use let*? I was just bitten by the fact >> that with let you can not previous variables from the let >> statement, as is possible with setq. So I am thinking about always >> using let*, so I do not have to think about it. Or are there good >> reasons to use let when you do not need let*? > > The most common reason is when you want to use a variable value > in the cadr of a binding and you do *not* want to pick up the > variable's newly bound value. IOW, precisely the opposite use > case of what you wanted when you were bit. > > (setq c 3) > > (let ((c (+ c 4)) > (b (* c 42))) ; Use original C value: 3 > ...) That makes my head spin. ;-) > (The other reason is that for some Lisps the bindings of `let' > can be done in parallel, which can be quicker.) Nice to know, but in most cases the ‘let*’ will not be the bottleneck. I think I am going to always use let*. Or maybe I should just engrave the difference in my brain. After I was bitten, I remembered. Better to remember before. :-) -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: Always using let* 2014-09-14 22:11 ` Cecil Westerhof @ 2014-09-14 22:56 ` Drew Adams 0 siblings, 0 replies; 32+ messages in thread From: Drew Adams @ 2014-09-14 22:56 UTC (permalink / raw) To: Cecil Westerhof, help-gnu-emacs > > (let ((c (+ c 4)) > > (b (* c 42))) ; Use original C value: 3 > > ...) > > That makes my head spin. ;-) Does this make it easier for you? (let ((c 5) (b c)) ; Use value of the `c' that is bound outside. ...) And remember that the local binding of `c' to 5 can bind an existing dynamic variable (from, say, `(defvar c 3 "C doc")') for the duration of this `let'. Or it can bind an existing lexically scoped variable `c' from an outer `let' for the scope (or for the duration, if `lexical-binding'=`nil') of this inner `let'. Or it can create and bind a new variable. This answers the question of why you might not use a different name from `c': because you want to bind an existing variable named `c'. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* [not found] ` <mailman.8868.1410729956.1147.help-gnu-emacs@gnu.org> 2014-09-14 21:41 ` Emanuel Berg 2014-09-14 22:11 ` Cecil Westerhof @ 2014-09-14 22:41 ` Stefan Monnier 2014-09-14 23:06 ` Drew Adams [not found] ` <mailman.8871.1410736002.1147.help-gnu-emacs@gnu.org> 2 siblings, 2 replies; 32+ messages in thread From: Stefan Monnier @ 2014-09-14 22:41 UTC (permalink / raw) To: help-gnu-emacs > (The other reason is that for some Lisps the bindings of `let' > can be done in parallel, which can be quicker.) Urban legend! Stefan ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: Always using let* 2014-09-14 22:41 ` Stefan Monnier @ 2014-09-14 23:06 ` Drew Adams [not found] ` <mailman.8871.1410736002.1147.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 32+ messages in thread From: Drew Adams @ 2014-09-14 23:06 UTC (permalink / raw) To: Stefan Monnier, help-gnu-emacs > > (The other reason is that for some Lisps the bindings of `let' > > can be done in parallel, which can be quicker.) ^^^ ^^^ > > Urban legend! Perhaps you would prefer "could" to "can"? Lisps such as Common Lisp were specifically designed with this parallel evaluation in mind. The spec (and CLTL(2)) specifically emphasizes the inherent parallelism (independence) here that implies the *possibility* of parallel evaluation. Whether a given Common Lisp implementation takes advantage of this inherent parallelism is optional. Likewise for the other explicitly parallel constructs in CL. For `psetf', for example, CLTL says that "the assignments of new values are done in parallel. More precisely, all subforms that are to be evaluated are evaluated from left to right; after all evaluations have been performed, all of the assignments are performed in an unpredictable order." ^ permalink raw reply [flat|nested] 32+ messages in thread
[parent not found: <mailman.8871.1410736002.1147.help-gnu-emacs@gnu.org>]
* Re: Always using let* [not found] ` <mailman.8871.1410736002.1147.help-gnu-emacs@gnu.org> @ 2014-09-15 0:47 ` Emanuel Berg 2014-09-15 2:12 ` Pascal J. Bourguignon 2014-09-15 2:22 ` Stefan Monnier 1 sibling, 1 reply; 32+ messages in thread From: Emanuel Berg @ 2014-09-15 0:47 UTC (permalink / raw) To: help-gnu-emacs Drew Adams <drew.adams@oracle.com> writes: > Lisps such as Common Lisp were specifically designed > with this parallel evaluation in mind. The spec (and > CLTL(2)) CLTL(2) = "Common Lisp The Language", 2nd edition, by Guy Steele. Here it is, as a PDF - 1097 pages, according to 'exiftool': http://www.lispmachine.net/books/common_lisp_the_language.pdf > Whether a given Common Lisp implementation takes > advantage of this inherent parallelism is optional. > Likewise for the other explicitly parallel constructs > in CL. > > For `psetf', for example, CLTL says that "the > assignments of new values are done in parallel. ..." Again, what do you mean by "parallel"? Is it parallel (i.e., truly concurrent) computation on different CPUs (cores), or is it some other kind of parallelism or pipelining? -- underground experts united ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-15 0:47 ` Emanuel Berg @ 2014-09-15 2:12 ` Pascal J. Bourguignon 0 siblings, 0 replies; 32+ messages in thread From: Pascal J. Bourguignon @ 2014-09-15 2:12 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg <embe8573@student.uu.se> writes: > Drew Adams <drew.adams@oracle.com> writes: > >> Lisps such as Common Lisp were specifically designed >> with this parallel evaluation in mind. The spec (and >> CLTL(2)) > > CLTL(2) = "Common Lisp The Language", 2nd edition, by > Guy Steele. > > Here it is, as a PDF - 1097 pages, according to > 'exiftool': > > http://www.lispmachine.net/books/common_lisp_the_language.pdf > >> Whether a given Common Lisp implementation takes >> advantage of this inherent parallelism is optional. >> Likewise for the other explicitly parallel constructs >> in CL. >> >> For `psetf', for example, CLTL says that "the >> assignments of new values are done in parallel. ..." > > Again, what do you mean by "parallel"? Is it parallel > (i.e., truly concurrent) computation on different CPUs > (cores), or is it some other kind of parallelism or > pipelining? It means that: (psetf a b b a) exchanges the values of b and a. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* [not found] ` <mailman.8871.1410736002.1147.help-gnu-emacs@gnu.org> 2014-09-15 0:47 ` Emanuel Berg @ 2014-09-15 2:22 ` Stefan Monnier 2014-09-15 2:59 ` Pascal J. Bourguignon 1 sibling, 1 reply; 32+ messages in thread From: Stefan Monnier @ 2014-09-15 2:22 UTC (permalink / raw) To: help-gnu-emacs > Lisps such as Common Lisp were specifically designed with this > parallel evaluation in mind. The spec (and CLTL(2)) specifically > emphasizes the inherent parallelism (independence) here that > implies the *possibility* of parallel evaluation. I simply claim that this is bogus. Only the var-binding is "parallel", not the computation of each value. So it's a "parallel binding" semantics, but it has nothing to do with efficient execution on multiple execution units. Stefan ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-15 2:22 ` Stefan Monnier @ 2014-09-15 2:59 ` Pascal J. Bourguignon 2014-09-15 12:31 ` Stefan Monnier 2014-09-15 13:14 ` Barry Margolin 0 siblings, 2 replies; 32+ messages in thread From: Pascal J. Bourguignon @ 2014-09-15 2:59 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier <monnier@iro.umontreal.ca> writes: >> Lisps such as Common Lisp were specifically designed with this >> parallel evaluation in mind. The spec (and CLTL(2)) specifically >> emphasizes the inherent parallelism (independence) here that >> implies the *possibility* of parallel evaluation. > > I simply claim that this is bogus. Only the var-binding is "parallel", not > the computation of each value. So it's a "parallel binding" semantics, > but it has nothing to do with efficient execution on multiple > execution units. The claim is not bogus. It's just that in general, in presence of side effects, since the expressions must be evaluated from left to right, indeed, only the assignments can be performed in parallel. But if you have side-effect free expressions, (or at least, provably independent ones), then they could be evaluated in parallel despite the left-to-right rule. On the other hand, with setf, this could not be the case. (let ((a 100) (b 200)) (psetf a (loop repeat b finally (return 1)) b (loop repeat a finally (return 2)))) could evaluate both loops in parallel, and therefore finishing by assinging 1 to a and 2 to be after only 200 iterations instead of 300. On the other hand: (let ((a 100) (b 200)) (setf a (loop repeat b finally (return 1)) b (loop repeat a finally (return 2)))) must perform 101 iterations, sequentially 100 followed by 1. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-15 2:59 ` Pascal J. Bourguignon @ 2014-09-15 12:31 ` Stefan Monnier 2014-09-15 16:15 ` Drew Adams 2014-09-15 13:14 ` Barry Margolin 1 sibling, 1 reply; 32+ messages in thread From: Stefan Monnier @ 2014-09-15 12:31 UTC (permalink / raw) To: help-gnu-emacs > But if you have side-effect free expressions, (or at least, provably > independent ones), then they could be evaluated in parallel despite the > left-to-right rule. Same holds for let* or pretty much anything else for that matter: if some analysis can prove that it can be done in parallel, well, then unsurprisingly it can be performed in parallel. But it's not the "parallel binding" semantics of `let' that lets you do that. While some details of language semantics can make analysis of code easier for that (e.g. the non-aliasing constraints on arguments in Fortran), I've never heard of anyone being able to use the parallel-binding of "let" for that. So, I stand by my claim: it's an Urban Legend. Stefan ^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: Always using let* 2014-09-15 12:31 ` Stefan Monnier @ 2014-09-15 16:15 ` Drew Adams 2014-09-15 19:05 ` Stefan Monnier [not found] ` <mailman.8930.1410808006.1147.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 32+ messages in thread From: Drew Adams @ 2014-09-15 16:15 UTC (permalink / raw) To: Stefan Monnier, help-gnu-emacs sm> So, I stand by my claim: it's an Urban Legend. But your claim changes with each post. What you first claimed was an urban legend was my statement that: "for some Lisps the bindings of `let' can be done in parallel" ^^^^^^^^^^^^ Your next message confirmed that that statement is true (though for some reason you put "parallel" in quotes and strengthened the assertion to "is" from "can be done"): sm> Only the var-binding is "parallel", not the computation sm> of each value. The bindings are exactly what my statement claimed, and what your first "Urban legend!" cry denounced. And what your latest message confirms. The myth ("legend") is a myth. `let' (vs `let*') is indeed about the _bindings_ being independent, so making it _possible_ to carry them out in parallel. That is the only thing specified for Common Lisp. And that is the only thing that makes sense for a language such as Lisp that allows side effects during evaluation. That is, it is not possible to arbitrarily parallelize evaluation of the sexps whose values are bound. (And yes, my followup message spoke of "parallel evaluation", but I again meant creation of the bindings. Admittedly, I was not as clear as I should have been there.) As Pascal pointed out, in some concrete cases analysis can reveal independency, which could be exploited for parallel execution. But as others then pointed out, this is also true generally, including for `let*'. The question of possibly parallelizing evaluation of the sexps whose values are to be bound is a side point (red herring). The point of what CLTL(2) has to say about `let', which was my point, is that `let' allows for parallelizing the _bindings_. And on that, you apparently agree now, in spite of the alarmist messages. --- Note: When I mentioned this binding independence/parallelism point in passing, I put it in _parentheses_, pretty much as an afterthought to the main reason I gave for the existence of `let' in addition to `let*' and why/when one might want to use the former. I mentioned it only because it is explicitly part of the design rationale for `let' vs `let*' in Common Lisp. Putting that in parens did not stop people from getting all excited about it, unfortunately, starting with your "Urban legend!" alarm. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-15 16:15 ` Drew Adams @ 2014-09-15 19:05 ` Stefan Monnier [not found] ` <mailman.8930.1410808006.1147.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 32+ messages in thread From: Stefan Monnier @ 2014-09-15 19:05 UTC (permalink / raw) To: Drew Adams; +Cc: help-gnu-emacs > What you first claimed was an urban legend was my statement that: > "for some Lisps the bindings of `let' can be done in parallel" > ^^^^^^^^^^^^ Let's check again: > (The other reason is that for some Lisps the bindings of `let' > can be done in parallel, which can be quicker.) Urban legend! Now, admittedly, you can think that I objected to "the bindings of `let' can be done in parallel", but in reality what I objected to is the idea that this can be quicker, which is usually understood as "use parallel processing", aka "make use of multiple computational units at the same time". If someone writes "parallel" and "quicker" in the same sentence, whether she wants it or not, people are bound to understand it as "make use of multiple computational units at the same time to speed up execution". Stefan ^ permalink raw reply [flat|nested] 32+ messages in thread
[parent not found: <mailman.8930.1410808006.1147.help-gnu-emacs@gnu.org>]
* Re: Always using let* [not found] ` <mailman.8930.1410808006.1147.help-gnu-emacs@gnu.org> @ 2014-09-15 22:28 ` Emanuel Berg 2014-09-16 0:38 ` Pascal J. Bourguignon 0 siblings, 1 reply; 32+ messages in thread From: Emanuel Berg @ 2014-09-15 22:28 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier <monnier@iro.umontreal.ca> writes: > which is usually understood as "use parallel > processing", aka "make use of multiple computational > units at the same time". Yes - this is my definition of parallelism as well: true concurrency, not perceived (as in preemption, context switching, and so on). The question is: does any Lisp do this with `let'? If yes, that Lisp could do it partly with let* as well only that would imply an overhead to sort out where there are precedence constraints. The appeal of doing it for let is that it wouldn't be any fuss - just distribute, compute, and execute the body all set. But if no one did it, some practical obstacle must still have gotten into the way... -- underground experts united ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-15 22:28 ` Emanuel Berg @ 2014-09-16 0:38 ` Pascal J. Bourguignon 0 siblings, 0 replies; 32+ messages in thread From: Pascal J. Bourguignon @ 2014-09-16 0:38 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg <embe8573@student.uu.se> writes: > Stefan Monnier <monnier@iro.umontreal.ca> writes: > >> which is usually understood as "use parallel >> processing", aka "make use of multiple computational >> units at the same time". > > Yes - this is my definition of parallelism as well: > true concurrency, not perceived (as in preemption, > context switching, and so on). > > The question is: does any Lisp do this with `let'? > > If yes, that Lisp could do it partly with let* as well > only that would imply an overhead to sort out where > there are precedence constraints. > > The appeal of doing it for let is that it wouldn't be > any fuss - just distribute, compute, and execute the > body all set. But if no one did it, some practical > obstacle must still have gotten into the way... Well, the actual reason why LET and LET* are the way they are, is purely history. Somebody invented LET first. Then somebody noted that they had sometimes to write (let ((a 1)) (let ((b (+ a 1))) (let ((c (+ a b))) …))) so they wrote the LET* macro to do that, and it stayed that way since then. Perhaps one LISP had it reversed, but since it was in the minority, when they documented the common lisp language, it was LET/LET* we know that won. Notice that emacs lisp is in the majority here. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Always using let* 2014-09-15 2:59 ` Pascal J. Bourguignon 2014-09-15 12:31 ` Stefan Monnier @ 2014-09-15 13:14 ` Barry Margolin 1 sibling, 0 replies; 32+ messages in thread From: Barry Margolin @ 2014-09-15 13:14 UTC (permalink / raw) To: help-gnu-emacs In article <87mwa1lhb1.fsf@kuiper.lan.informatimago.com>, "Pascal J. Bourguignon" <pjb@informatimago.com> wrote: > Stefan Monnier <monnier@iro.umontreal.ca> writes: > > >> Lisps such as Common Lisp were specifically designed with this > >> parallel evaluation in mind. The spec (and CLTL(2)) specifically > >> emphasizes the inherent parallelism (independence) here that > >> implies the *possibility* of parallel evaluation. > > > > I simply claim that this is bogus. Only the var-binding is "parallel", not > > the computation of each value. So it's a "parallel binding" semantics, > > but it has nothing to do with efficient execution on multiple > > execution units. > > The claim is not bogus. It's just that in general, in presence of side > effects, since the expressions must be evaluated from left to right, > indeed, only the assignments can be performed in parallel. If the LET can be done in parallel, so could LET*. Remember, we're talking about compiled code. The inner and outer variables are not the same memory location, even if they have the same name. The difference between LET and LET* just has to do with which scope the compiler looks up the name in. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2014-09-18 21:05 UTC | newest] Thread overview: 32+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-09-14 19:46 Always using let* Cecil Westerhof 2014-09-14 21:25 ` Drew Adams 2014-09-15 16:15 ` Drew Adams [not found] ` <mailman.8924.1410797740.1147.help-gnu-emacs@gnu.org> 2014-09-15 18:01 ` Cecil Westerhof 2014-09-15 22:20 ` Emanuel Berg 2014-09-16 12:05 ` Cecil Westerhof 2014-09-16 22:40 ` Emanuel Berg 2014-09-18 17:02 ` Cecil Westerhof 2014-09-18 21:05 ` Emanuel Berg 2014-09-16 14:23 ` sokobania.01 2014-09-16 16:41 ` Drew Adams 2014-09-16 20:49 ` Stefan Monnier 2014-09-16 22:45 ` Emanuel Berg [not found] ` <mailman.8998.1410901776.1147.help-gnu-emacs@gnu.org> 2014-09-16 22:48 ` Emanuel Berg 2014-09-17 1:09 ` Stefan Monnier 2014-09-17 1:18 ` Emanuel Berg 2014-09-14 21:40 ` Joe Fineman [not found] ` <mailman.8868.1410729956.1147.help-gnu-emacs@gnu.org> 2014-09-14 21:41 ` Emanuel Berg 2014-09-14 22:11 ` Cecil Westerhof 2014-09-14 22:56 ` Drew Adams 2014-09-14 22:41 ` Stefan Monnier 2014-09-14 23:06 ` Drew Adams [not found] ` <mailman.8871.1410736002.1147.help-gnu-emacs@gnu.org> 2014-09-15 0:47 ` Emanuel Berg 2014-09-15 2:12 ` Pascal J. Bourguignon 2014-09-15 2:22 ` Stefan Monnier 2014-09-15 2:59 ` Pascal J. Bourguignon 2014-09-15 12:31 ` Stefan Monnier 2014-09-15 16:15 ` Drew Adams 2014-09-15 19:05 ` Stefan Monnier [not found] ` <mailman.8930.1410808006.1147.help-gnu-emacs@gnu.org> 2014-09-15 22:28 ` Emanuel Berg 2014-09-16 0:38 ` Pascal J. Bourguignon 2014-09-15 13:14 ` Barry Margolin
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.