* What does "lacks a prefix" mean? @ 2015-07-08 16:32 BobD 2015-07-08 16:45 ` Barry Margolin ` (3 more replies) 0 siblings, 4 replies; 40+ messages in thread From: BobD @ 2015-07-08 16:32 UTC (permalink / raw) To: help-gnu-emacs My elisp: (defun blabba () (defvar n 0) ) byte-compile-file yields this: In blabba: test.el:1:8:Warning: global/dynamic var `n' lacks a prefix What does my elisp lack? Other than asking here, where can I learn what "lacks a prefix" means? ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-08 16:32 What does "lacks a prefix" mean? BobD @ 2015-07-08 16:45 ` Barry Margolin 2015-07-08 16:59 ` Vaidheeswaran C ` (2 subsequent siblings) 3 siblings, 0 replies; 40+ messages in thread From: Barry Margolin @ 2015-07-08 16:45 UTC (permalink / raw) To: help-gnu-emacs In article <1e0ad02f-ca3e-495c-bb85-61f77090d31d@googlegroups.com>, BobD <daycandle@gmail.com> wrote: > My elisp: > > (defun blabba () > (defvar n 0) > ) > > byte-compile-file yields this: > > In blabba: > test.el:1:8:Warning: global/dynamic var `n' lacks a prefix > > What does my elisp lack? > Other than asking here, where can I learn what "lacks a prefix" means? The convention in Emacs Lisp is that global variables should have names of the form packagename-variable. Giving a global variable a name without a package prefix is a good way to have collisions between different packages. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-08 16:32 What does "lacks a prefix" mean? BobD 2015-07-08 16:45 ` Barry Margolin @ 2015-07-08 16:59 ` Vaidheeswaran C 2015-07-08 17:10 ` Vaidheeswaran C 2015-07-08 18:17 ` BobD 3 siblings, 0 replies; 40+ messages in thread From: Vaidheeswaran C @ 2015-07-08 16:59 UTC (permalink / raw) To: help-gnu-emacs On Wednesday 08 July 2015 10:02 PM, BobD wrote: > My elisp: > > (defun blabba () > (defvar n 0) > ) > > byte-compile-file yields this: > > In blabba: > test.el:1:8:Warning: global/dynamic var `n' lacks a prefix > > What does my elisp lack? > Other than asking here, where can I learn what "lacks a prefix" means? > > See Second bullet here: http://www.gnu.org/software/emacs/manual/html_node/elisp/Coding-Conventions.html ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-08 16:32 What does "lacks a prefix" mean? BobD 2015-07-08 16:45 ` Barry Margolin 2015-07-08 16:59 ` Vaidheeswaran C @ 2015-07-08 17:10 ` Vaidheeswaran C 2015-07-08 18:17 ` BobD 3 siblings, 0 replies; 40+ messages in thread From: Vaidheeswaran C @ 2015-07-08 17:10 UTC (permalink / raw) To: BobD, help-gnu-emacs On Wednesday 08 July 2015 10:02 PM, BobD wrote: > My elisp: > > (defun blabba () > (defvar n 0) > ) > > byte-compile-file yields this: > > In blabba: > test.el:1:8:Warning: global/dynamic var `n' lacks a prefix > > What does my elisp lack? > Other than asking here, where can I learn what "lacks a prefix" means? > > See bullet 2 under http://www.gnu.org/software/emacs/manual/html_node/elisp/Coding-Conventions.html ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-08 16:32 What does "lacks a prefix" mean? BobD ` (2 preceding siblings ...) 2015-07-08 17:10 ` Vaidheeswaran C @ 2015-07-08 18:17 ` BobD 2015-07-08 18:21 ` Pascal J. Bourguignon 3 siblings, 1 reply; 40+ messages in thread From: BobD @ 2015-07-08 18:17 UTC (permalink / raw) To: help-gnu-emacs Thanks! So the warning calls attention to a good-citizenship rule, not a logic issue. How do I create a variable with local execution scope, i.e. to be known within a function, not to other elisp functions, and regardless of which buffer is local? ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-08 18:17 ` BobD @ 2015-07-08 18:21 ` Pascal J. Bourguignon 2015-07-08 18:45 ` BobD 0 siblings, 1 reply; 40+ messages in thread From: Pascal J. Bourguignon @ 2015-07-08 18:21 UTC (permalink / raw) To: help-gnu-emacs BobD <daycandle@gmail.com> writes: > How do I create a variable with local execution scope, i.e. to be > known within a function, not to other elisp functions, and regardless > of which buffer is local? Using let, of course. (defun f (x) (let ((y (+ 1 x))) (* 2 y))) -- __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] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-08 18:21 ` Pascal J. Bourguignon @ 2015-07-08 18:45 ` BobD 2015-07-08 23:24 ` Emanuel Berg [not found] ` <mailman.6590.1436397914.904.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 40+ messages in thread From: BobD @ 2015-07-08 18:45 UTC (permalink / raw) To: help-gnu-emacs On Wednesday, July 8, 2015 at 2:21:07 PM UTC-4, Pascal J. Bourguignon wrote: > BobD <...> writes: > > > How do I create a variable with local execution scope, i.e. to be > > known within a function, not to other elisp functions, and regardless > > of which buffer is local? > > Using let, of course. > > (defun f (x) > (let ((y (+ 1 x))) > (* 2 y))) > > ... But of course. I'm fooling with old elisp that uses "setq" willy-nilly, defying the notational structuring with which latter day programmers have been (properly) indoctrinated. If I must, I can wedge some let's into the code. ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-08 18:45 ` BobD @ 2015-07-08 23:24 ` Emanuel Berg 2015-07-09 15:23 ` Filipp Gunbin [not found] ` <mailman.6612.1436455429.904.help-gnu-emacs@gnu.org> [not found] ` <mailman.6590.1436397914.904.help-gnu-emacs@gnu.org> 1 sibling, 2 replies; 40+ messages in thread From: Emanuel Berg @ 2015-07-08 23:24 UTC (permalink / raw) To: help-gnu-emacs BobD <daycandle@gmail.com> writes: > But of course. I'm fooling with old elisp that uses > "setq" willy-nilly, defying the notational > structuring with which latter day programmers have > been (properly) indoctrinated. If I must, I can > wedge some let's into the code. And: use `let*' if any variable depend on and uses a previously defined one to do its computation. Actually I see no harm using let* all the time. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-08 23:24 ` Emanuel Berg @ 2015-07-09 15:23 ` Filipp Gunbin 2015-07-09 22:32 ` Emanuel Berg [not found] ` <mailman.6612.1436455429.904.help-gnu-emacs@gnu.org> 1 sibling, 1 reply; 40+ messages in thread From: Filipp Gunbin @ 2015-07-09 15:23 UTC (permalink / raw) To: help-gnu-emacs On 09/07/2015 01:24 +0200, Emanuel Berg wrote: > BobD <daycandle@gmail.com> writes: > >> But of course. I'm fooling with old elisp that uses >> "setq" willy-nilly, defying the notational >> structuring with which latter day programmers have >> been (properly) indoctrinated. If I must, I can >> wedge some let's into the code. > > And: use `let*' if any variable depend on and uses > a previously defined one to do its computation. > > Actually I see no harm using let* all the time. let* says "I need variables which depend on each other" and if they're really not, that look strange. And probably it's a bit slower. And non-parallelizable theoretically :) Filipp ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-09 15:23 ` Filipp Gunbin @ 2015-07-09 22:32 ` Emanuel Berg 2015-07-10 17:04 ` Stefan Monnier [not found] ` <mailman.6685.1436547891.904.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 40+ messages in thread From: Emanuel Berg @ 2015-07-09 22:32 UTC (permalink / raw) To: help-gnu-emacs Filipp Gunbin <fgunbin@fastmail.fm> writes: > let* says "I need variables which depend on each > other" and if they're really not, that look strange. It looks strange to the human Lisp brain because we have trained it is the way it is. I'm doing it that way as well, but only because I want my Lisp to be understood by others I don't start re-training it (the brain) starting right now. > And non-parallelizable theoretically :) Is anyone really going to base parallelism on a bunch of local variables? With let and let*? But yeah, if that was actually so, it would be cool if not (probably) that big a deal... -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-09 22:32 ` Emanuel Berg @ 2015-07-10 17:04 ` Stefan Monnier 2015-07-11 22:42 ` Emanuel Berg ` (2 more replies) [not found] ` <mailman.6685.1436547891.904.help-gnu-emacs@gnu.org> 1 sibling, 3 replies; 40+ messages in thread From: Stefan Monnier @ 2015-07-10 17:04 UTC (permalink / raw) To: help-gnu-emacs >> let* says "I need variables which depend on each >> other" and if they're really not, that look strange. If let behaved like let* it wouldn't look strange to you. Many other functional languages dropped the "simultaneous let" and only kept the equivalent of let* (or even letrec). >> And probably it's a bit slower. Regarding efficiency, there's no clear winner between the two. It's basically irrelevant. >> And non-parallelizable theoretically :) In practice neither is easily parallelizable anyway. And the work needed to auto-convert a "let*" to a "let" when possible is trivial in comparison to what's needed to parallelize the code. So again, it's really irrelevant. Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-10 17:04 ` Stefan Monnier @ 2015-07-11 22:42 ` Emanuel Berg [not found] ` <mailman.6748.1436654668.904.help-gnu-emacs@gnu.org> 2015-07-13 12:26 ` Filipp Gunbin 2 siblings, 0 replies; 40+ messages in thread From: Emanuel Berg @ 2015-07-11 22:42 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier <monnier@iro.umontreal.ca> writes: >> let* says "I need variables which depend on each >> other" and if they're really not, that >> look strange. > > If let behaved like let* it wouldn't look strange to > you. Many other functional languages dropped the > "simultaneous let" and only kept the equivalent of > let* (or even letrec). > >> And probably it's a bit slower. > > Regarding efficiency, there's no clear winner > between the two. It's basically irrelevant. > >> And non-parallelizable theoretically :) > > In practice neither is easily parallelizable anyway. > And the work needed to auto-convert a "let*" to > a "let" when possible is trivial in comparison to > what's needed to parallelize the code. So again, > it's really irrelevant. Hear? I couldn't have said it better myself. Wait... I couldn't! But let me say a couple of other things: 1) "let" looks better and is faster to type, both in terms of the number of chars used and what those chars are (i.e., no "*" in "let" which is only normal letters). 2) With the let/let* distinction, while let* being the oddball, it sends the signal that the "let" style, and not the one of "let*", is the one preferred. But it is actually the "let*" style that should be favored! It is much more clear and easily navigated. Compare: (setq side 3.0) (let ((cube-volume (* side side side))) cube-volume) vs. (let* ((side 3.0) (side-area (* side side)) (cube-volume (* side-area side)) ) cube-volume) "Dependencies" are the most natural things and aren't anything to be afraid of! Only if you are the manager of a Linux distro they can get out of hands sometimes... 3) "let", if let was let*, would be less thinking in advance since then you wouldn't have to think "so, will I have variables now which will depend on each other?" You'd just type "let" in either case! Likewise, when you modify code long after you first wrote it, you often insert a new variable that is "dependent" on another, and then you have to change the `let' to `let*'. But this is very easy to forget and it is always a silly mistake when it happens. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <mailman.6748.1436654668.904.help-gnu-emacs@gnu.org>]
* Re: What does "lacks a prefix" mean? [not found] ` <mailman.6748.1436654668.904.help-gnu-emacs@gnu.org> @ 2015-07-11 23:58 ` Barry Margolin 0 siblings, 0 replies; 40+ messages in thread From: Barry Margolin @ 2015-07-11 23:58 UTC (permalink / raw) To: help-gnu-emacs In article <mailman.6748.1436654668.904.help-gnu-emacs@gnu.org>, Emanuel Berg <embe8573@student.uu.se> wrote: > 3) "let", if let was let*, would be less thinking in > advance since then you wouldn't have to think "so, > will I have variables now which will depend on > each other?" You'd just type "let" in either case! > Likewise, when you modify code long after you > first wrote it, you often insert a new variable > that is "dependent" on another, and then you have > to change the `let' to `let*'. But this is very > easy to forget and it is always a silly mistake > when it happens. This is a reasonable argument. It's not uncommon to start writing a let, realize that the initialization expression has some repetition, so you want to refactor it to use variables for them. Then you need to change it to let*. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-10 17:04 ` Stefan Monnier 2015-07-11 22:42 ` Emanuel Berg [not found] ` <mailman.6748.1436654668.904.help-gnu-emacs@gnu.org> @ 2015-07-13 12:26 ` Filipp Gunbin 2 siblings, 0 replies; 40+ messages in thread From: Filipp Gunbin @ 2015-07-13 12:26 UTC (permalink / raw) To: Stefan Monnier; +Cc: help-gnu-emacs On 10/07/2015 13:04 -0400, Stefan Monnier wrote: >>> let* says "I need variables which depend on each >>> other" and if they're really not, that look strange. > > If let behaved like let* it wouldn't look strange to you. Many other > functional languages dropped the "simultaneous let" and only kept the > equivalent of let* (or even letrec). But if 90% of users make the distinction and 10% of them don't it would cause confusion. If everybody uses the same construct then it does not matter. letrec is nice :-) >>> And probably it's a bit slower. > > Regarding efficiency, there's no clear winner between the two. > It's basically irrelevant. I meant that there could be an extra inner frame for each of the bindings in let*, while only one in let. I don't have enough knowledge of emacs lisp implementation to say for sure, that's why "probably" in my comment. >>> And non-parallelizable theoretically :) > > In practice neither is easily parallelizable anyway. Is it because each of the value expression could modify something in the environment? > And the work needed to auto-convert a "let*" to a "let" when possible > is trivial in comparison to what's needed to parallelize the code. So > again, it's really irrelevant. Ok, thanks. Filipp ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <mailman.6685.1436547891.904.help-gnu-emacs@gnu.org>]
* Re: What does "lacks a prefix" mean? [not found] ` <mailman.6685.1436547891.904.help-gnu-emacs@gnu.org> @ 2015-07-10 18:27 ` Barry Margolin 0 siblings, 0 replies; 40+ messages in thread From: Barry Margolin @ 2015-07-10 18:27 UTC (permalink / raw) To: help-gnu-emacs In article <mailman.6685.1436547891.904.help-gnu-emacs@gnu.org>, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > >> let* says "I need variables which depend on each > >> other" and if they're really not, that look strange. > > If let behaved like let* it wouldn't look strange to you. Many other > functional languages dropped the "simultaneous let" and only kept the > equivalent of let* (or even letrec). It should be noted that the original LET macro in MacLisp was basically a rearranged LAMBDA: (let ((var1 val1) (var2 val2) ...) body...) ==> ((lambda (var1 var2 ...) body...) val1 val2 ...) When written this way, you can see where the order of evaluation of the values, and the parallel binding of the variables came from: arguments to a function have to be evaluated before the function is called (except in "lazy" languages). Most other languages also have function call syntax, and if they have anonymous functions they can express the same parallel binding. E.g. in Javascript you can write an "IIFE": (function(var1, var2, ...) {body...})(val1, val2, ...) This is actually a common idiom (and whenever I see it, I cringe that they somehow discovered the original Lisp syntax, yet didn't adopt the LET-style rewrite that makes it easier to comprehend). What they generally don't have is multiple ways to introduce local variables in the same scope of a function. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <mailman.6612.1436455429.904.help-gnu-emacs@gnu.org>]
* Re: What does "lacks a prefix" mean? [not found] ` <mailman.6612.1436455429.904.help-gnu-emacs@gnu.org> @ 2015-07-09 23:27 ` Barry Margolin [not found] ` <mailman.6643.1436488423.904.help-gnu-emacs@gnu.org> [not found] ` <<barmar-500871.19271109072015@88-209-239-213.giganet.hu> 1 sibling, 1 reply; 40+ messages in thread From: Barry Margolin @ 2015-07-09 23:27 UTC (permalink / raw) To: help-gnu-emacs In article <mailman.6612.1436455429.904.help-gnu-emacs@gnu.org>, Filipp Gunbin <fgunbin@fastmail.fm> wrote: > On 09/07/2015 01:24 +0200, Emanuel Berg wrote: > > > BobD <daycandle@gmail.com> writes: > > > >> But of course. I'm fooling with old elisp that uses > >> "setq" willy-nilly, defying the notational > >> structuring with which latter day programmers have > >> been (properly) indoctrinated. If I must, I can > >> wedge some let's into the code. > > > > And: use `let*' if any variable depend on and uses > > a previously defined one to do its computation. > > > > Actually I see no harm using let* all the time. > > let* says "I need variables which depend on each other" and if they're > really not, that look strange. > > And probably it's a bit slower. If it is, that's a misfeature of the compiler. > And non-parallelizable theoretically :) Regular let isn't parallelizable. It specifies that the value expressions are evaluated in order. The only difference between the two is the environment within which later expressions are evaluated. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <mailman.6643.1436488423.904.help-gnu-emacs@gnu.org>]
* Re: What does "lacks a prefix" mean? [not found] ` <mailman.6643.1436488423.904.help-gnu-emacs@gnu.org> @ 2015-07-10 0:49 ` Pascal J. Bourguignon 2015-07-10 5:04 ` Drew Adams 2015-07-10 14:42 ` Barry Margolin [not found] ` <<barmar-2BC802.10421910072015@88-209-239-213.giganet.hu> 2 siblings, 1 reply; 40+ messages in thread From: Pascal J. Bourguignon @ 2015-07-10 0:49 UTC (permalink / raw) To: help-gnu-emacs Drew Adams <drew.adams@oracle.com> writes: >> > And non-parallelizable theoretically :) >> >> Regular let isn't parallelizable. It specifies that the value >> expressions are evaluated in order. >> >> The only difference between the two is the environment within which >> later expressions are evaluated. > > FWIW, Common Lisp specifies that "let performs the bindings > in parallel and let* does them sequentially." > > That is theoretical, just a restatement that `let' bindings > are independent. But it means that yes, they *could* be > evaluated in parallel (because they are independent). IF they are independent, and notably IF they are side effect free. (let ((i 0)) (cons (let ((i 42) (a (print (incf i))) (b (print (incf i))) (c (print (incf i)))) (list i a b c)) i)) prints: 1 2 3 --> ((42 1 2 3) . 3) Here, there's now way the initialization expressions in the inner let be evaluated in parallel. The left-to-right evaluation order is imperative, because of the side effects. -- __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] 40+ messages in thread
* RE: What does "lacks a prefix" mean? 2015-07-10 0:49 ` Pascal J. Bourguignon @ 2015-07-10 5:04 ` Drew Adams 0 siblings, 0 replies; 40+ messages in thread From: Drew Adams @ 2015-07-10 5:04 UTC (permalink / raw) To: Pascal J. Bourguignon, help-gnu-emacs > IF they are independent, and notably IF they are side effect free. Yes, clearly. That's not really the point here. But it is good to point it out. Code with `let' can need to be examined closely, just like code with `let*'. This is Lisp, not Haskell. ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? [not found] ` <mailman.6643.1436488423.904.help-gnu-emacs@gnu.org> 2015-07-10 0:49 ` Pascal J. Bourguignon @ 2015-07-10 14:42 ` Barry Margolin [not found] ` <<barmar-2BC802.10421910072015@88-209-239-213.giganet.hu> 2 siblings, 0 replies; 40+ messages in thread From: Barry Margolin @ 2015-07-10 14:42 UTC (permalink / raw) To: help-gnu-emacs In article <mailman.6643.1436488423.904.help-gnu-emacs@gnu.org>, Drew Adams <drew.adams@oracle.com> wrote: > > > And non-parallelizable theoretically :) > > > > Regular let isn't parallelizable. It specifies that the value > > expressions are evaluated in order. > > > > The only difference between the two is the environment within which > > later expressions are evaluated. > > FWIW, Common Lisp specifies that "let performs the bindings > in parallel and let* does them sequentially." It specifies that the bindings are done in parallel, but evaluation of the initialization forms is sequential. From http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm#let "LET ... first evaluates the expressions init-form-1, init-form-2, and so on, in that order, saving the resulting values. Then all of the variables varj are bound to the corresponding values" whereas "LET* ... first evaluates the expression init-form-1, then binds the variable var1 to that value; then it evaluates init-form-2 and binds var2, and so on" If the forms have no side effects, LET can indeed execute them in parallel, since there's no way to tell the difference. LET* can also do that for any initialization expressions that don't refer back to earlier variables and have no side effects. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <<barmar-2BC802.10421910072015@88-209-239-213.giganet.hu>]
* RE: What does "lacks a prefix" mean? [not found] ` <<barmar-2BC802.10421910072015@88-209-239-213.giganet.hu> @ 2015-07-10 14:53 ` Drew Adams 0 siblings, 0 replies; 40+ messages in thread From: Drew Adams @ 2015-07-10 14:53 UTC (permalink / raw) To: Barry Margolin, help-gnu-emacs > [Common Lisp] specifies that the bindings are done in parallel, but > evaluation of the initialization forms is sequential. From > http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm#let > > "LET ... first evaluates the expressions init-form-1, init-form-2, > and so on, in that order, saving the resulting values. Then all of > the variables varj are bound to the corresponding values" Good clarification. > If the forms have no side effects, LET can indeed execute them in > parallel, since there's no way to tell the difference. LET* can also > do that for any initialization expressions that don't refer back to > earlier variables and have no side effects. Also well put. ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <<barmar-500871.19271109072015@88-209-239-213.giganet.hu>]
* RE: What does "lacks a prefix" mean? [not found] ` <<barmar-500871.19271109072015@88-209-239-213.giganet.hu> @ 2015-07-10 0:33 ` Drew Adams 0 siblings, 0 replies; 40+ messages in thread From: Drew Adams @ 2015-07-10 0:33 UTC (permalink / raw) To: Barry Margolin, help-gnu-emacs > > And non-parallelizable theoretically :) > > Regular let isn't parallelizable. It specifies that the value > expressions are evaluated in order. > > The only difference between the two is the environment within which > later expressions are evaluated. FWIW, Common Lisp specifies that "let performs the bindings in parallel and let* does them sequentially." That is theoretical, just a restatement that `let' bindings are independent. But it means that yes, they *could* be evaluated in parallel (because they are independent). ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <mailman.6590.1436397914.904.help-gnu-emacs@gnu.org>]
* Re: What does "lacks a prefix" mean? [not found] ` <mailman.6590.1436397914.904.help-gnu-emacs@gnu.org> @ 2015-07-09 14:01 ` Barry Margolin 2015-07-09 14:10 ` Rusi 2015-07-09 22:19 ` Emanuel Berg [not found] ` <<barmar-F23189.10014209072015@88-209-239-213.giganet.hu> 1 sibling, 2 replies; 40+ messages in thread From: Barry Margolin @ 2015-07-09 14:01 UTC (permalink / raw) To: help-gnu-emacs In article <mailman.6590.1436397914.904.help-gnu-emacs@gnu.org>, Emanuel Berg <embe8573@student.uu.se> wrote: > Actually I see no harm using let* all the time. This is a frequent subject of style arguments. As far as the computer is concerned, there should be no problem with using let* all the time. But to human readers, it makes a difference. Some of us view the * as being a red flag, warning the reader that something unusual is being done. We'll then expend more mental energy looking for the dependencies. let is the "normal" method, let* is "special". -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-09 14:01 ` Barry Margolin @ 2015-07-09 14:10 ` Rusi 2015-07-09 22:27 ` Emanuel Berg [not found] ` <mailman.6639.1436481016.904.help-gnu-emacs@gnu.org> 2015-07-09 22:19 ` Emanuel Berg 1 sibling, 2 replies; 40+ messages in thread From: Rusi @ 2015-07-09 14:10 UTC (permalink / raw) To: help-gnu-emacs On Thursday, July 9, 2015 at 7:31:44 PM UTC+5:30, Barry Margolin wrote: > In article > Emanuel Berg wrote: > > > Actually I see no harm using let* all the time. > > This is a frequent subject of style arguments. > > As far as the computer is concerned, there should be no problem with > using let* all the time. But to human readers, it makes a difference. > Some of us view the * as being a red flag, warning the reader that > something unusual is being done. We'll then expend more mental energy > looking for the dependencies. let is the "normal" method, let* is > "special". Ive sometimes wished for a let-variant that does the duty of both let and let* eg. (let (((x 1) (y 2)) ((z (foo x y)))) body...) This kind of let would cost one paren more than the usual let. But could make dependencies explicit without overspecifying ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-09 14:10 ` Rusi @ 2015-07-09 22:27 ` Emanuel Berg [not found] ` <mailman.6639.1436481016.904.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 40+ messages in thread From: Emanuel Berg @ 2015-07-09 22:27 UTC (permalink / raw) To: help-gnu-emacs Rusi <rustompmody@gmail.com> writes: > Ive sometimes wished for a let-variant that does the > duty of both let and let* eg. > (let (((x 1) (y 2)) > ((z (foo x y)))) > body...) > > This kind of let would cost one paren more than the usual let. > But could make dependencies explicit without > overspecifying let* already does what let does. Dependencies aren't explicit anywhere: the only thing let* does is saying there CAN be dependencies. Because this is almost a worthless "red flag" that carries minimal information, I'd say I'd use let all the time if let was "let*". The only reason for the distinction is if computation was made in parallel, then let could allow that and let* wouldn't. However, if that was possible without OH to eat the gain I would like a much more powerful construct than let*, one which exactly identified what is dependent on what. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <mailman.6639.1436481016.904.help-gnu-emacs@gnu.org>]
* Re: What does "lacks a prefix" mean? [not found] ` <mailman.6639.1436481016.904.help-gnu-emacs@gnu.org> @ 2015-07-10 3:10 ` Rusi 2015-07-10 16:00 ` Emanuel Berg 0 siblings, 1 reply; 40+ messages in thread From: Rusi @ 2015-07-10 3:10 UTC (permalink / raw) To: help-gnu-emacs On Friday, July 10, 2015 at 4:00:18 AM UTC+5:30, Emanuel Berg wrote: > Rusi writes: > > > Ive sometimes wished for a let-variant that does the > > duty of both let and let* eg. > > > (let (((x 1) (y 2)) > > ((z (foo x y)))) > > body...) > > > > This kind of let would cost one paren more than the usual let. > > But could make dependencies explicit without > > overspecifying > > let* already does what let does. *** Welcome to IELM *** Type (describe-mode) for help. ELISP> (setq a 'a b 'b) b ELISP> (let ((a b)(b a)) (list a b)) (b a) ELISP> (let* ((a b)(b a)) (list a b)) (b b) ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-10 3:10 ` Rusi @ 2015-07-10 16:00 ` Emanuel Berg 0 siblings, 0 replies; 40+ messages in thread From: Emanuel Berg @ 2015-07-10 16:00 UTC (permalink / raw) To: help-gnu-emacs Rusi <rustompmody@gmail.com> writes: >> let* already does what let does. > > *** Welcome to IELM *** Type (describe-mode) for help. > ELISP> (setq a 'a b 'b) > ELISP> (let ((a b)(b a)) (list a b)) > (b a) > > ELISP> (let* ((a b)(b a)) (list a b)) > (b b) I have 178 "let"s in my Elisp and I'm confident I could replace all of them with `let*' without braking a single defun. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-09 14:01 ` Barry Margolin 2015-07-09 14:10 ` Rusi @ 2015-07-09 22:19 ` Emanuel Berg 1 sibling, 0 replies; 40+ messages in thread From: Emanuel Berg @ 2015-07-09 22:19 UTC (permalink / raw) To: help-gnu-emacs Barry Margolin <barmar@alum.mit.edu> writes: >> Actually I see no harm using let* all the time. > > This is a frequent subject of style arguments. > > As far as the computer is concerned, there should be > no problem with using let* all the time. But to > human readers, it makes a difference. Some of us > view the * as being a red flag, warning the reader > that something unusual is being done. We'll then > expend more mental energy looking for the > dependencies. let is the "normal" method, let* is > "special". That's exactly right! Myself I use both (let and let*) for this exact reason. Still I don't see any harm always using let*, and if let* was "let" and the other way around, I think (?) I'd always use "let". -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <<barmar-F23189.10014209072015@88-209-239-213.giganet.hu>]
* RE: What does "lacks a prefix" mean? [not found] ` <<barmar-F23189.10014209072015@88-209-239-213.giganet.hu> @ 2015-07-09 15:33 ` Drew Adams 2015-07-12 1:47 ` Emanuel Berg 0 siblings, 1 reply; 40+ messages in thread From: Drew Adams @ 2015-07-09 15:33 UTC (permalink / raw) To: Barry Margolin, help-gnu-emacs > > Actually I see no harm using let* all the time. Harm? Why would *harm* be the only useful or the most useful criterion? There's no harm in writing Lisp with no whitespace at all, except for that needed to distinguish tokens such as symbols and numbers. And in fact I once had a colleague (an expert Lisper, BTW) who wrote Lisp that way, always - no newline chars, no indentation, no spaces or tabs at all, except what was needed by the interpreter or byte-compiler to disambiguate the code. No one else wanted to read, let alone modify his code, but hey, no "harm" done, right? He wrote his code at lightning speed, hardly looking at it. And his code was *good* code - for the applications and the machine. It just wasn't very good for humans (other than himself, arguably, and I'm not sure he didn't shoot himself in the foot sometimes). > This is a frequent subject of style arguments. > > As far as the computer is concerned, there should be no problem > with using let* all the time. But to human readers, it makes a > difference. Indeed, that is the point. (Though I don't entirely agree with your description of the difference it makes to human readers, quoted next.) > Some of us view the * as being a red flag, warning the reader that > something unusual is being done. We'll then expend more mental > energy looking for the dependencies. let is the "normal" method, > let* is "special". I would say this about using `let' vs `let*' wrt what they indicate to human readers: `let' indicates that the bindings are independent; `let*' signals that they might be dependent. I don't see a red flag from `let*', but yes, it does make me pay attention and look for dependencies. That "might be" is where I agree with Barry: `let*' makes you look for whether each binding after the first might in fact be dependent on a previous one from the same `let*'. It's a huge load off one's mind knowing that the bindings of a `let' are independent. Similarly, it is a great help to know, from `let*', to look for how the bindings are actually related. The problem with using `let*' all the time ("harm", actually) is the problem of affixing the same **WARNING** label to absolutely everything - it loses all power to draw attention to anything. If everwhere might involve binding dependencies then you have no signal to watch for them. You need to always be on the alert - or never. I start with `let', and I change to `let*' only when the logic dictates it, i.e., when I introduce a dependent binding. That way I know that if I see `let*' there is a dependency. Does writing this way, privileging `let' when possible, mean more work for the writer? Of course. When things change in the code logic, it can happen that you need to change whether you are using one or the other, or you might even need to add another `let' or `let*' - or you might be able and want to remove one. But saving the writer some maintenance burden is not my priority. Saving the reader some interpretation burden is more important. Why? Because the reader, even when s?he is the same human as the writer, is reading something inherently foreign - s?he is coming at the code from a distance, and is a priori less familiar with it. Even for the same person, time and change of context can provide enough distance that it is no longer immediately clear what is going on or why things were written as they are. (And yes, I even update the code even when it is not absolutely necessary: if there is no longer any dependency then I change a `let*' back to `let'. IOW, I try to keep the code telling me what I want to know about the actual dependencies.) To me, the discovery that, hey, I can write everything using just `let*' and never bother with `let', and following up that discovery with the practice of just using `let*', is the sign of a novice - someone who hasn't yet learned that you don't just write code once and for all. Even "throwaway" code can have a longer life than you might expect. It's about the code long term; it's not about you just now. In sum, to me the problem with such an approach is *not* that it is lazy. The problem is in fact that it is *not lazy enough*. Such an approach shows misguided, short-sighted laziness. True, enlightened laziness takes the longer view: minimize effort and strain (whether manual or mental) over time and across multiple maintainers and other readers. YMMV. ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-09 15:33 ` Drew Adams @ 2015-07-12 1:47 ` Emanuel Berg 2015-07-12 16:59 ` Drew Adams 0 siblings, 1 reply; 40+ messages in thread From: Emanuel Berg @ 2015-07-12 1:47 UTC (permalink / raw) To: help-gnu-emacs Drew Adams <drew.adams@oracle.com> writes: > Harm? Why would *harm* be the only useful or the > most useful criterion? > > There's no harm in writing Lisp with no whitespace > at all, except for that needed to distinguish tokens > such as symbols and numbers. > > And in fact I once had a colleague (an expert Lisper, > BTW) who wrote Lisp that way, always - no newline > chars, no indentation, no spaces or tabs at all, > except what was needed by the interpreter or > byte-compiler to disambiguate the code. > > No one else wanted to read, let alone modify his > code, but hey, no "harm" done, right? > > He wrote his code at lightning speed, hardly looking > at it. And his code was *good* code - for the > applications and the machine. It just wasn't very > good for humans (other than himself, arguably, and > I'm not sure he didn't shoot himself in the foot > sometimes). I do see the harm in doing as your former colleague but I don't see the harm in using `let*' instead of `let'. Apart from convention which can be reprogrammed in the minds of programmers, even. And, as it stands, apart from me not liking the syntax (spelling) of "let*" compared to "let". > I would say this about using `let' vs `let*' wrt > what they indicate to human readers: `let' indicates > that the bindings are independent; `let*' signals > that they might be dependent. > > I don't see a red flag from `let*', but yes, it does > make me pay attention and look for dependencies. > That "might be" is where I agree with Barry: `let*' > makes you look for whether each binding after the > first might in fact be dependent on a previous one > from the same `let*'. > > It's a huge load off one's mind knowing that the > bindings of a `let' are independent. Similarly, it > is a great help to know, from `let*', to look for > how the bindings are actually related. > > The problem with using `let*' all the time ("harm", > actually) is the problem of affixing the same > **WARNING** label to absolutely everything - it > loses all power to draw attention to anything. > If everwhere might involve binding dependencies then > you have no signal to watch for them. You need to > always be on the alert - or never. This all makes sense if the premise is that dependencies are anything to look for, be aware of, be "on the alert", as you say. But - why do you want to look for them at all? What does it matter? On the contrary, I consider them completely natural and a good thing. It is *good* for humans to see that computation is done in steps, and for machines, that is the way it happens anyway - it doesn't matter if you have one all but neverending line: (let ((value (computation_1 ( ... (computation_n ...)))))) or the same procedure on a vertical line with names to illustrate the process. But, to humans, it is more clear and less error prone, and it is easier to modify and debug. If we turn the discussion upside down, if dependencies indeed were a reason to be on the alert - then I'd like a much better and more specific construct than `let*'! If dependencies were something to look for, I wouldn't want a construct that says "here, there *might* be dependencies", instead I'd like a construct that said "here, there *is* a dependency, namely X depends on Y in terms of Z!" -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
* RE: What does "lacks a prefix" mean? 2015-07-12 1:47 ` Emanuel Berg @ 2015-07-12 16:59 ` Drew Adams 2015-07-13 0:46 ` Emanuel Berg 0 siblings, 1 reply; 40+ messages in thread From: Drew Adams @ 2015-07-12 16:59 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs > > The problem with using `let*' all the time ("harm", > > actually) is the problem of affixing the same > > **WARNING** label to absolutely everything - it > > loses all power to draw attention to anything. > > If everwhere might involve binding dependencies then > > you have no signal to watch for them. You need to > > always be on the alert - or never. > ... > I wouldn't want a construct that says "here, there > *might* be dependencies", instead I'd like a construct > that said "here, there *is* a dependency, namely > X depends on Y in terms of Z!" That's precisely the point. I want the latter, not the former. In your text that I elided you seem to have missed the point. It's not about dependencies being somehow bad or dangerous or abnormal. It's about recognizing and understanding them. Precisely, I imagine, why you wrote that you'd appreciate a construct that identifies them for you. So would I. In the absence of that, I identify them for myself, explicitly. When I read code later I often understand it less well than I did when I wrote it (not always, but often enough). So I as writer try to help poor me as reader. `let*' tells you nothing about dependencies, which means more time examining code to understand it. That's the answer to your question, "What does it matter?". To understand code we sometimes need to understand what various parts of it depend on. Believe it or not, you do want (or will someday appreciate) the advantage of knowing - just by looking - where there are binding dependencies, especially if you have many bindings at the same level (and perhaps especially if there are dynamic bindings). If you use only `let*' all the time then you in fact maximize what you claim you "wouldn't want" - something that tells you nothing about where there might be, let alone where there actually are, dependencies. Working code that uses `let', on the other hand, does tell you something useful. Lacking an automatic indication of dependencies (that would be nice), my preference is to do the work myself when writing code, to signal to myself (and any other reader) what my understanding of the code is at that time: * These particular bindings, with `let', are not themselves, as bindings, interdependent. The code would not work if they were (typically you'd get an unbound variable error). * These other bindings, with `let*', _do_ involve at least one dependency - not "might", but "do". The code would not work if `let*' were changed to `let' here (e.g., unbound variable error). It's the "the code would not work" part that makes this convention a bit more useful than, say, comments about the writer's understanding of what's going on. The stricter the use of the convention, the more surely does `let*' indicate real dependencies. If adhered to strictly then _every_ `let*' binding expresses a real, not just a might-be, dependency. (If you think that `let*' makes every binding depend on those that precede it, think again. `(let* ((a 1) (b 2))...)' does not make b's value depend on a's.) I use `let*' where I know (or think I know) there is a binding dependency, and `let' where I know (or think) there are none. It's about expressing my coding-time understanding, so that a reader has that extra bit of info - info about my thinking, and maybe about the code. Whether my understanding is correct when writing is not the question. At least a reader has the advantage of knowing what I was thinking. That's the point and, yes, it can really help. It helps me, as writer and reader of my code. Separating the two this way lets me know that when I see `let*' I can rely on there being binding dependency, rather than knowing only that there might be. Can `let' also involve dependencies? Of course, especially with dynamic binding. The point is not that the use of this convention makes understanding trivial, cut-and-dried. The point is that understanding what the writer was thinking can help a reader. Throwing everything into one giant `let*' is easy, and things might seem to just work (no pesky unbound variable errors), but it obscures rather than clarifies what is going on. A coder knows more about the code than what an all-inclusive `let*' can tell a reader, so I express it, to help out. In the absence of language support that does such analysis and proclaims the outcome in the code, I do it manually. YMMV. You don't have to write your code the way I write mine. And I don't have to read and maintain your code. ;-) I do what I do because it helps me. I describe it here because I think it could help others, even you. ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-12 16:59 ` Drew Adams @ 2015-07-13 0:46 ` Emanuel Berg 2015-07-13 7:26 ` Yuri Khan 0 siblings, 1 reply; 40+ messages in thread From: Emanuel Berg @ 2015-07-13 0:46 UTC (permalink / raw) To: help-gnu-emacs Drew Adams <drew.adams@oracle.com> writes: > That's precisely the point. I want the latter, not > the former. > > In your text that I elided you seem to have missed > the point. It's not about dependencies being somehow > bad or dangerous or abnormal. ... "Dependency" is when one program needs another program to execute. Or whenever a library needs some other library to do its taks. When a variable uses another variable to compute its value, this is perhaps formally a "dependency" but mostly it is normal programming that happens every day, all the time. You mention when you come back to edit code. Then you want to know if there are (might be) dependencies by looking at the let or let*. Why? I never do that, but look at the variables, instead. I don't think about variable "dependencies" ever, because I assume they are there because that is the normal state. I don't need anything to "warn" me the code is normal. As said, I think code written in the "let* style", with tons of variables that incrementally show the computation stepwise, is *much more* clear/easy to read and edit/less error prone than code where everything is done in one binding to keep it "dependency" free. Why would anyone do that? We can take an example from a C++ project I once did. I just brought up a file, and immediately I see: char* const program_name = const_cast<char*>(program.c_str()); int arg_array_size = argc + 1; char* program_argv[arg_array_size]; program_argv[0] = program_name; You see that everything depends on everything. Do you think this makes any difference? /* WARNING - DEPENDENCIES AHEAD */ char* const program_name = const_cast<char*>(program.c_str()); int arg_array_size = argc + 1; char* program_argv[arg_array_size]; program_argv[0] = program_name; /* Relax - when evil returns, so shall we! */ -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-13 0:46 ` Emanuel Berg @ 2015-07-13 7:26 ` Yuri Khan 2015-07-13 23:47 ` Emanuel Berg 0 siblings, 1 reply; 40+ messages in thread From: Yuri Khan @ 2015-07-13 7:26 UTC (permalink / raw) To: help-gnu-emacs@gnu.org On Mon, Jul 13, 2015 at 6:46 AM, Emanuel Berg <embe8573@student.uu.se> wrote: > You mention when you come back to edit code. Then you > want to know if there are (might be) dependencies by > looking at the let or let*. Why? I never do that, but > look at the variables, instead. I don't think about > variable "dependencies" ever, because I assume they > are there because that is the normal state. I don't > need anything to "warn" me the code is normal. Variable dependencies start to matter a lot when you’re trying to refactor code — e.g. to extract part of a function into a new function of its own. In this case, variables shared by the code that stays and the code that moves out are a source of complexity, and their number may be a factor in deciding which refactoring the code actually wants. ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-13 7:26 ` Yuri Khan @ 2015-07-13 23:47 ` Emanuel Berg 2015-07-14 6:23 ` Yuri Khan 0 siblings, 1 reply; 40+ messages in thread From: Emanuel Berg @ 2015-07-13 23:47 UTC (permalink / raw) To: help-gnu-emacs Yuri Khan <yuri.v.khan@gmail.com> writes: > Variable dependencies start to matter a lot when > you’re trying to refactor code — e.g. to extract > part of a function into a new function of its own. > In this case, variables shared by the code that > stays and the code that moves out are a source of > complexity, and their number may be a factor in > deciding which refactoring the code actually wants. If you are to muck around with old code, which seldom is a good idea but sometimes necessary (?), then doing so will be helped to an unfathomable degree if the "let* style" has been applied when the code was originally written, as computation is stepwise performed and each step is named and put neatly into a nice looking column! It is, on the contrary, the "let style" with (let ((entity (computation_1 (computation_2 ( ... ))))) ... ) which is much more difficult to write, not to mention read, debug, and later maintain and modify. "Variable dependencies" is all schoolbook stuff - forget about it, the sooner the better, because it doesn't work like that. It doesn't increase "complexity", whatever that is. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-13 23:47 ` Emanuel Berg @ 2015-07-14 6:23 ` Yuri Khan 2015-07-14 21:58 ` Emanuel Berg 2015-07-19 0:59 ` Robert Thorpe 0 siblings, 2 replies; 40+ messages in thread From: Yuri Khan @ 2015-07-14 6:23 UTC (permalink / raw) To: help-gnu-emacs@gnu.org On Tue, Jul 14, 2015 at 5:47 AM, Emanuel Berg <embe8573@student.uu.se> wrote: > If you are to muck around with old code, which seldom > is a good idea but sometimes necessary (?), Why the (?)? Mucking around with old code is necessary every time you want to add a feature or debug a failure. > then doing > so will be helped to an unfathomable degree if the > "let* style" has been applied when the code was > originally written, as computation is stepwise > performed and each step is named and put neatly into > a nice looking column! > > It is, on the contrary, the "let style" with > > (let ((entity (computation_1 (computation_2 ( ... ))))) > ... ) > > which is much more difficult to write, not to mention > read, debug, and later maintain and modify. You’re putting out a strawman by comparing a “let* style” where small expressions are given names and arranged in a total order with a “let style” where few names are bound to independent but huge expressions. The ultimate degree of the “let*” style you describe is code compiled to assembly. (For the sake of argument, let’s assume a machine with ten thousand registers, so that we don’t have to argue about register reuse.) Expressions are very simple but it becomes hard to give them meaningful names. Additionally, evey modern compiler worth its bits will interleave independent evaluations if it will help saturate the CPU pipelines. The resulting code is very complicated — the code is doing several things at once and one has to unscramble it in order to reason about it. The ultimate degree of the “let style” you describe is the UNIX shell pipeline. Its two main problems are: (1) lack of names for intermediate values, (2) each unnamed intermediate value can only be used once. As soon as you want to reuse the result of a subexpression, you need to give it a name. As in most things, there is a golden middle where the expressions are not too complex, names are meaningful enough, and related computations are clustered together. When structured like this, code is a pleasure to work with. > "Variable dependencies" is all schoolbook stuff - > forget about it, the sooner the better, because it > doesn't work like that. It doesn't increase > "complexity", whatever that is. Schoolbook stuff? No, we were not taught about dependencies at school. We were taught recipes. Here is how you add, subtract, multiply and divide; this is how you use standard library functions; this is how you define your own functions. Oh actually in <this particular language> you can’t define your own functions; too bad, you’ll have to make do with subroutines and instead of returning a result assign it into a global variable. This is where complexity comes from: people knowing recipes and applying them out of scale until the code is too complicated to fit in one head. Especially, code written by a person with an exceptionally big head will not fit in an average head. Maybe you can keep 15 named variables and 60 unnamed intermediate values in your head and reason about them freely. I cannot. I need devices that help me in that. These devices can be embedded in the code (meaningful names, auxiliary functions, and/or an occasional comment) or I can work it out on a sheet of paper, throw it away when done and have to redo it again the next time. ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-14 6:23 ` Yuri Khan @ 2015-07-14 21:58 ` Emanuel Berg 2015-07-19 0:59 ` Robert Thorpe 1 sibling, 0 replies; 40+ messages in thread From: Emanuel Berg @ 2015-07-14 21:58 UTC (permalink / raw) To: help-gnu-emacs Yuri Khan <yuri.v.khan@gmail.com> writes: >> If you are to muck around with old code, which >> seldom is a good idea but sometimes necessary (?), > > Why the (?)? Mucking around with old code is > necessary every time you want to add a feature or > debug a failure. It depends what you mean. Adding a particular feature or fixing a particular bug is one thing. The "let* style" simplifies this. Another thing altogether is "refactoring code", "optimizing", etc. *in general*. That is a bad idea and a bad entry point. If the program is poorly written, why not re-write it from scratch? OTOH, if the program is written in a good style, there is no reason to do any overall changes. There are very likely improvements to be made, and bugs to fix, and again, using let* makes this easy work because everything is clearly organized and you can easily spot the part you need to change/fix. > You’re putting out a strawman by comparing a “let* > style” where small expressions are given names and > arranged in a total order with a “let style” where > few names are bound to independent but > huge expressions. > > The ultimate degree of the “let*” style you describe > is code compiled to assembly. (For the sake of > argument There is always an extreme example that will make the most sound attitude bizarre. It is a dead end to argue like that. > Schoolbook stuff? No, we were not taught about > dependencies at school. We were taught recipes. I was taught, or "told" I should say, a lot about dependencies at school, and I read about them in many textbooks. There are many systems how to properly draw them with boxes and arrows. I believed then, and now, that this made-up, good-for-nothing "science" is a very sad routine, rather than comical, and to me it is a mystery that people do it. 99% of my school time wasn't like that, so it is fine, but yeah, I get angry just by thinking about that pompous BS that takes the fun and creativity out of everything, being told to kids that are ten or twenty times the hackers as the teachers "spreading the word". It is a very sad state. > Maybe you can keep 15 named variables and 60 unnamed > intermediate values in your head and reason about > them freely. ... what? *I'm* the one who want stuff named! -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-14 6:23 ` Yuri Khan 2015-07-14 21:58 ` Emanuel Berg @ 2015-07-19 0:59 ` Robert Thorpe 2015-07-28 0:24 ` Emanuel Berg 1 sibling, 1 reply; 40+ messages in thread From: Robert Thorpe @ 2015-07-19 0:59 UTC (permalink / raw) To: help-gnu-emacs; +Cc: Yuri Khan Yuri Khan <yuri.v.khan@gmail.com> writes: > On Tue, Jul 14, 2015 at 5:47 AM, Emanuel Berg <embe8573@student.uu.se> wrote: > >> If you are to muck around with old code, which seldom >> is a good idea but sometimes necessary (?), > > Why the (?)? Mucking around with old code is necessary every time you > want to add a feature or debug a failure. For what it's worth, this is my opinion on let vs let*. When there's a dependency between two of the variables I use let*. If there's no dependency at all I use let. So, if the code defining y depends on the code defining x then I use let*. I don't like the style where let* is used for everything. Here's an example of the problem. Suppose you're reading through a function. You have a local variable z and you want to understand what values it could have. To begin with you want to understand what could happen at the beginning of the body of the let statement z is defined in. I.e.:- (defun foo () "blah blah" (let* ((a (something)) (b (something-else ...)) (z (something-more))) ... here... ...rest of the code...) Now, let's say the programmer has used let. In that case I know by looking that I don't have to read the definitions of a & b. Alternatively, suppose the programmer has used let* even though z isn't dependent on a or b. In that case let* indicates to me the reader that they should read the definitions of a & b. But, doing that isn't immediately necessary, I may not need to understand the details of a & b to understand the problem. It's easy to be critical of the process of restructuring or refactoring code. It's inevitable in large codebases though. The cost and time of rewriting them is simply too large. Even if the original is badly written it generally contains undocumented features that people rely on. If a large program is well written that doesn't mean it won't need modifications regularly. BR, Robert Thorpe ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-19 0:59 ` Robert Thorpe @ 2015-07-28 0:24 ` Emanuel Berg 2015-07-30 1:40 ` Robert Thorpe [not found] ` <mailman.7638.1438220428.904.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 40+ messages in thread From: Emanuel Berg @ 2015-07-28 0:24 UTC (permalink / raw) To: help-gnu-emacs Robert Thorpe <rt@robertthorpeconsulting.com> writes: > For what it's worth, this is my opinion on let vs > let*. > > When there's a dependency between two of the > variables I use let*. If there's no dependency at > all I use let. So, if the code defining y depends on > the code defining x then I use let*. > > I don't like the style where let* is used for > everything. Here's an example of the problem. > Suppose you're reading through a function. You have > a local variable z and you want to understand what > values it could have. To begin with you want to > understand what could happen at the beginning of the > body of the let statement z is defined in. > > I.e.:- (defun foo () "blah blah" (let* ((a > (something)) (b (something-else ...)) (z > (something-more))) ... here... ...rest of the code...) > > Now, let's say the programmer has used let. In that > case I know by looking that I don't have to read the > definitions of a & b. Alternatively, suppose the > programmer has used let* even though z isn't > dependent on a or b. In that case let* indicates to > me the reader that they should read the definitions > of a & b. But, doing that isn't immediately > necessary, I may not need to understand the details > of a & b to understand the problem. This is the exact same tiresome argument that has been put forward several times by now and the argument is still only logical within the framework that is "this is the way people do it". Yes: I know! In the other framework, where it is natural and *desired* that things depend on each other and happen stepwise - nothing to be afraid of and nothing that must be marked specifically as it is the natural order of things - in that framework it doesn't make sense (surprise, surprise!). There is a framework of convention but beneath that there is technology. On top of that we can create any framework of our minds as we desire. If we create one that doesn't make sense in terms of technology, if we use it enough, we'll even start to like it! It is sly! > It's easy to be critical of the process of > restructuring or refactoring code. It's inevitable > in large codebases though. OK, so how many lines of zsh, C, C++ and Lisp do you have to write before it gets inevitable to "refactor" it? I ask because I did my biggest projects in those languages but apparently they weren't big enough because I never did any "refactoring", whatever that is, if it isn't the very normal and everyday thing that is writing, improving, and fixing bugs in code, in what case I have done it every day for many years! What is all this talk?! I don't understand this whole defaitiste "we know the drill" mentality. "It is just the way it is." It isn't - what it is is an empty buffer and it doesn't have to be anything and it can be whatever you want it to be! "Do it today, in a different way!" (Scooter 2010) > The cost and time of rewriting them is simply too > large. Even if the original is badly written it > generally contains undocumented features that people > rely on. If a large program is well written that > doesn't mean it won't need modifications regularly. So, everything is so bad, we have to have let/let* - it is inevitable! -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-28 0:24 ` Emanuel Berg @ 2015-07-30 1:40 ` Robert Thorpe [not found] ` <mailman.7638.1438220428.904.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 40+ messages in thread From: Robert Thorpe @ 2015-07-30 1:40 UTC (permalink / raw) To: Emanuel Berg; +Cc: help-gnu-emacs I won't talk about this much more because I think it's getting off-topic for this list. Emanuel Berg <embe8573@student.uu.se> writes: > This is the exact same tiresome argument that has been > put forward several times by now and the argument is > still only logical within the framework that is "this > is the way people do it". Yes: I know! I think that new languages should be written to do this the same way. I think the convention for let and let* used in lisp is useful and I wish it were more widespread. I'm not advocating it just because it's used in old code. My comments about refactoring were separate. > In the other framework, where it is natural and > *desired* that things depend on each other and happen > stepwise - nothing to be afraid of and nothing that > must be marked specifically as it is the natural order > of things - in that framework it doesn't make > sense (surprise, surprise!). Certainly there is no point in avoiding dependencies. They always occur in programming. But, there's no need to make it look as through there are dependencies where there aren't. There's no point removing tools that allow use to differentiate one situation from the other easily. That's the problem with the approach you're advocating. As I said earlier, let's suppose you're reading through function foo looking for what happens to variable bar. Suppose you have:- (let (..... (foo (code ...))) body) In this case there's no need to read through any of the other variables defined in the let. Suppose instead you have: (let* (..... (foo (code ...))) body) In that case the part I've labeled "code ..." could depend on the other local variables. In the "let" case it's often possible to eval the "code ..." part with C-x C-e. That's often not possible in the let* case. In the let* case you have to read through the rest of the local variable definitions. In elisp we have the following meanings: * let - there aren't dependencies between these variables. * let* - there are dependencies between these variables. In other languages that only support something like let* it means "there may be dependencies between these variables, you have to read all the code". >> It's easy to be critical of the process of >> restructuring or refactoring code. It's inevitable >> in large codebases though. > > OK, so how many lines of zsh, C, C++ and Lisp do you > have to write before it gets inevitable to "refactor" > it? I ask because I did my biggest projects in those > languages but apparently they weren't big enough > because I never did any "refactoring", whatever that > is, if it isn't the very normal and everyday thing > that is writing, improving, and fixing bugs in code, > in what case I have done it every day for many years! Of course, refactoring is often exactly what you say. It's improving code. Some people define it more rigourously. For example, making local improvements to code without changing the overall design is called "refactoring". Changing the overall design is called "rearchitecting". Remember the original reason we discussed this though. You wrote this: > Why the (?)? Mucking around with old code is necessary every time you > want to add a feature or debug a failure. Now, you're advocating "mucking around with old code". Well, that inevitably requires reading it and understanding it. New features must always be inserted somewhere. The original designers of a program can never envisage all of the ways that it might be extended. Look at Emacs, it's existed for decades and for all that time it's maintainers have tried to expand configurability. Yet, every few weeks somebody comes up with a practical case were a default behaviour can't be changed. >> The cost and time of rewriting them is simply too >> large. Even if the original is badly written it >> generally contains undocumented features that people >> rely on. If a large program is well written that >> doesn't mean it won't need modifications regularly. > > So, everything is so bad, we have to have let/let* - > it is inevitable! Of course I don't think there's any particular threshold in terms of lines-of-code of the type you describe. What more important is the overall effort of rewriting vs fixing. For example, is the existing program merely messy? If so then it's often better to tidy it up than re-write it even if it's small. If the program has a few modules that are badly written then those can be replaced. Is the original full of undocumented features everyone relies on? If so then re-writing it can be very tricky. Programs that are badly designed are a difficult case. If they're badly designed but the design is well executed (i.e. the code is generally well written) then it can be best to keep them around. If a program is really bad (i.e. buggy, badly written and difficult to modify) then it may be worth replacing it even if it's millions of lines long. Redesigning is one of the most useful and interesting programming skills to develop. It's about knowing how to re-use what you have to build a more general program without throwing too much away. BR, Robert Thorpe ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <mailman.7638.1438220428.904.help-gnu-emacs@gnu.org>]
* Re: What does "lacks a prefix" mean? [not found] ` <mailman.7638.1438220428.904.help-gnu-emacs@gnu.org> @ 2015-07-30 2:49 ` Rusi 2015-07-30 2:53 ` Rusi 0 siblings, 1 reply; 40+ messages in thread From: Rusi @ 2015-07-30 2:49 UTC (permalink / raw) To: help-gnu-emacs On Thursday, July 30, 2015 at 7:10:31 AM UTC+5:30, Robert Thorpe wrote: > I won't talk about this much more because I think it's getting off-topic > for this list. > > Emanuel Berg writes: > > This is the exact same tiresome argument that has been > > put forward several times by now and the argument is > > still only logical within the framework that is "this > > is the way people do it". Yes: I know! > > I think that new languages should be written to do this the same way. I > think the convention for let and let* used in lisp is useful and I wish > it were more widespread. I'm not advocating it just because it's used > in old code. My comments about refactoring were separate. > > > In the other framework, where it is natural and > > *desired* that things depend on each other and happen > > stepwise - nothing to be afraid of and nothing that > > must be marked specifically as it is the natural order > > of things - in that framework it doesn't make > > sense (surprise, surprise!). > > Certainly there is no point in avoiding dependencies. They always occur > in programming. But, there's no need to make it look as through there > are dependencies where there aren't. There's no point removing tools > that allow use to differentiate one situation from the other easily. > That's the problem with the approach you're advocating. > > As I said earlier, let's suppose you're reading through function foo > looking for what happens to variable bar. > > Suppose you have:- > (let (..... > (foo (code ...))) > body) > > In this case there's no need to read through any of the other variables > defined in the let. > > Suppose instead you have: > (let* (..... > (foo (code ...))) > body) > > In that case the part I've labeled "code ..." could depend on the other > local variables. In the "let" case it's often possible to eval the > "code ..." part with C-x C-e. That's often not possible in the let* > case. In the let* case you have to read through the rest of the local > variable definitions. > > In elisp we have the following meanings: > * let - there aren't dependencies between these variables. > * let* - there are dependencies between these variables. > > In other languages that only support something like let* it means "there > may be dependencies between these variables, you have to read all the > code". Strongly concur! Dijkstra made a statement that is as alarming as it is true, viz. "It takes 100 years for an idea to go from inception to general acceptance" [dont have exact quote handy...] Some examples: Cantor-1880 to New-math-1970 (set theory) 200 years for Leibniz calculus notation to replace the clumsier Newton fluxion notation 600 years for Hindu-Arabic (decimal) numerals to replace roman 30 years between Wright brothers flight and first commercial flight In the same way Lisp was invented in 1960 For the next 40 years something vague and acdaemic called 'functional programming' was talked of but everyone only really had lisp as an example/exemplar. Finally it is only this century -- Haskell, Clojure, Scala -- that its become mainstream And finally its become abc of programming ACM curriculum 2013 pg 158 lists what EVERY programmer should know of FP. Seeing this discussion, I am coming to the conclusion that dependencies (and their minimization) is something that should be added there. To be fair the one thing I agree with Emanuel is that let* is a clumsy name. I'd like best a single let with a 'dependency-fence' So Say {e,f} depends on {c,d} depends on {a,b} (no inra-set dependency) The least-dependency way of writing would be (let ((a ..) (b ..)) (let ((c ..) (d ..)) (let ((e ..) (f ..)) body))) The sloppy way would be just one let* Neither is quite satisfactory -- one is over-dependent; the other is over-nested What I'd like (newlet ((a ..) (b ..) :fence (c ..) (d ..) :fence (e ..) (f ..)) body))) The keyword ":fence" can be improved :-) ^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: What does "lacks a prefix" mean? 2015-07-30 2:49 ` Rusi @ 2015-07-30 2:53 ` Rusi 0 siblings, 0 replies; 40+ messages in thread From: Rusi @ 2015-07-30 2:53 UTC (permalink / raw) To: help-gnu-emacs On Thursday, July 30, 2015 at 8:19:42 AM UTC+5:30, Rusi wrote: > And finally its become abc of programming > ACM curriculum 2013 pg 158 lists what EVERY programmer should know of FP. > Seeing this discussion, I am coming to the conclusion that dependencies (and > their minimization) is something that should be added there. > Link to ACM curriculum: https://www.acm.org/education/CS2013-final-report.pdf My take on it: http://blog.languager.org/2015/06/functional-programming-moving-target.html ^ permalink raw reply [flat|nested] 40+ messages in thread
end of thread, other threads:[~2015-07-30 2:53 UTC | newest] Thread overview: 40+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-07-08 16:32 What does "lacks a prefix" mean? BobD 2015-07-08 16:45 ` Barry Margolin 2015-07-08 16:59 ` Vaidheeswaran C 2015-07-08 17:10 ` Vaidheeswaran C 2015-07-08 18:17 ` BobD 2015-07-08 18:21 ` Pascal J. Bourguignon 2015-07-08 18:45 ` BobD 2015-07-08 23:24 ` Emanuel Berg 2015-07-09 15:23 ` Filipp Gunbin 2015-07-09 22:32 ` Emanuel Berg 2015-07-10 17:04 ` Stefan Monnier 2015-07-11 22:42 ` Emanuel Berg [not found] ` <mailman.6748.1436654668.904.help-gnu-emacs@gnu.org> 2015-07-11 23:58 ` Barry Margolin 2015-07-13 12:26 ` Filipp Gunbin [not found] ` <mailman.6685.1436547891.904.help-gnu-emacs@gnu.org> 2015-07-10 18:27 ` Barry Margolin [not found] ` <mailman.6612.1436455429.904.help-gnu-emacs@gnu.org> 2015-07-09 23:27 ` Barry Margolin [not found] ` <mailman.6643.1436488423.904.help-gnu-emacs@gnu.org> 2015-07-10 0:49 ` Pascal J. Bourguignon 2015-07-10 5:04 ` Drew Adams 2015-07-10 14:42 ` Barry Margolin [not found] ` <<barmar-2BC802.10421910072015@88-209-239-213.giganet.hu> 2015-07-10 14:53 ` Drew Adams [not found] ` <<barmar-500871.19271109072015@88-209-239-213.giganet.hu> 2015-07-10 0:33 ` Drew Adams [not found] ` <mailman.6590.1436397914.904.help-gnu-emacs@gnu.org> 2015-07-09 14:01 ` Barry Margolin 2015-07-09 14:10 ` Rusi 2015-07-09 22:27 ` Emanuel Berg [not found] ` <mailman.6639.1436481016.904.help-gnu-emacs@gnu.org> 2015-07-10 3:10 ` Rusi 2015-07-10 16:00 ` Emanuel Berg 2015-07-09 22:19 ` Emanuel Berg [not found] ` <<barmar-F23189.10014209072015@88-209-239-213.giganet.hu> 2015-07-09 15:33 ` Drew Adams 2015-07-12 1:47 ` Emanuel Berg 2015-07-12 16:59 ` Drew Adams 2015-07-13 0:46 ` Emanuel Berg 2015-07-13 7:26 ` Yuri Khan 2015-07-13 23:47 ` Emanuel Berg 2015-07-14 6:23 ` Yuri Khan 2015-07-14 21:58 ` Emanuel Berg 2015-07-19 0:59 ` Robert Thorpe 2015-07-28 0:24 ` Emanuel Berg 2015-07-30 1:40 ` Robert Thorpe [not found] ` <mailman.7638.1438220428.904.help-gnu-emacs@gnu.org> 2015-07-30 2:49 ` Rusi 2015-07-30 2:53 ` Rusi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).