unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* 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 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

* 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*
       [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: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*
  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

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

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

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

* 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*
       [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 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*
       [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 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 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

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

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

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