all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Real-life examples of lexical binding in Emacs Lisp
@ 2015-05-29  8:28 Marcin Borkowski
  2015-05-30  8:28 ` Tassilo Horn
       [not found] ` <mailman.3950.1432974543.904.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 32+ messages in thread
From: Marcin Borkowski @ 2015-05-29  8:28 UTC (permalink / raw)
  To: Help Gnu Emacs mailing list

Hi all,

I googled a bit, and could not find /real-world/ examples of using
lexical binding and its advantages /in Emacs Lisp/.  I understand that
it's a nice thing to be able to create closures, and that lexical
binding is in general faster than dynamic binding (which is a bonus in
itself), but could anyone show me a real /text editing/ problem that
lexical binding solves, like something that is easier done with
l.b. than with d.b.?  (Examples of general-purpose programming problems
made easier with l.b. are more or less obvious/easy to find, but Emacs
is a text editor, after all, and this is its primary area.)

TIA,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-05-29  8:28 Real-life examples of lexical binding in Emacs Lisp Marcin Borkowski
@ 2015-05-30  8:28 ` Tassilo Horn
  2015-06-14 10:52   ` Marcin Borkowski
       [not found]   ` <mailman.4976.1434279182.904.help-gnu-emacs@gnu.org>
       [not found] ` <mailman.3950.1432974543.904.help-gnu-emacs@gnu.org>
  1 sibling, 2 replies; 32+ messages in thread
From: Tassilo Horn @ 2015-05-30  8:28 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: Help Gnu Emacs mailing list

Marcin Borkowski <mbork@mbork.pl> writes:

Hi Marcin,

> I googled a bit, and could not find /real-world/ examples of using
> lexical binding and its advantages /in Emacs Lisp/.  I understand that
> it's a nice thing to be able to create closures, and that lexical
> binding is in general faster than dynamic binding (which is a bonus in
> itself), but could anyone show me a real /text editing/ problem that
> lexical binding solves, like something that is easier done with
> l.b. than with d.b.?  (Examples of general-purpose programming
> problems made easier with l.b. are more or less obvious/easy to find,
> but Emacs is a text editor, after all, and this is its primary area.)

The emacs paper has a section explaining why emacs used dynamic binding
from the start: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17

However, to me the two example use-cases only motivate why you want to
be able to use dynamic scoping for special variables (defvar), not
really for local variables (let) or function parameters, although the
first Edit Picture example explicitly speaks of binding command
arguments but I don't understand it.

To me, having lexical scoping in general plus special, dynamically bound
variables is the ideal model.  If there wouldn't be special variables
anymore, the examples from the paper would need to be implemented by
setq-ing the variables and later re-setting them to their old value
which would be error-prone and wouldn't work if we ever get concurrency.
You can make special variables thread-local like in Clojure thus hiding
this additional complexity from programmers.

But there are good use-cases for dynamic variables also in "normal"
programs.  One example is to be able to bind some *error-handler*
dynamically in order to customize how to cope with errors that happen
far below the call stack.

I'm not able to come up with benefits of lexical scoping which are
especially important for editing text.  The general benefits of being
safer, faster, and having closures are still valid of course.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
       [not found] ` <mailman.3950.1432974543.904.help-gnu-emacs@gnu.org>
@ 2015-05-30 12:59   ` Pascal J. Bourguignon
  2015-06-14 10:55     ` Marcin Borkowski
       [not found]     ` <mailman.4977.1434279342.904.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 32+ messages in thread
From: Pascal J. Bourguignon @ 2015-05-30 12:59 UTC (permalink / raw)
  To: help-gnu-emacs

Tassilo Horn <tsdh@gnu.org> writes:

> The emacs paper has a section explaining why emacs used dynamic binding
> from the start: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17
>
> However, to me the two example use-cases only motivate why you want to
> be able to use dynamic scoping for special variables (defvar), not
> really for local variables (let) or function parameters, although the
> first Edit Picture example explicitly speaks of binding command
> arguments but I don't understand it.

Indeed, in general, you want lexical binding for local variables.

However, I would argue that for global variables, lexical binding would
be useful too, even by default.

In Common Lisp, we can implement global lexical variables, using
eg. symbol macros, but in emacs lisp, we're missing operators for the
global lexical case:

            dynamic   lexical
  global    defvar    -
  local     let(1)    let(2)

  (1) when lexical-binding is nil or the variable has been defvar'ed.
  (2) when lexical-binding is t and the variable has not been defvar'ed.


> But there are good use-cases for dynamic variables also in "normal"
> programs.  One example is to be able to bind some *error-handler*
> dynamically in order to customize how to cope with errors that happen
> far below the call stack.

Definitely.

https://groups.google.com/forum/#!original/comp.lang.lisp/oC5gDvn42pM/IudCXzCtxowJ

-- 
__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: Real-life examples of lexical binding in Emacs Lisp
  2015-05-30  8:28 ` Tassilo Horn
@ 2015-06-14 10:52   ` Marcin Borkowski
       [not found]   ` <mailman.4976.1434279182.904.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 32+ messages in thread
From: Marcin Borkowski @ 2015-06-14 10:52 UTC (permalink / raw)
  To: Help Gnu Emacs mailing list

OK, so I finally got to study this discussion.  (It seems I have kind of
a talent for inadvertently starting long discussions...)

On 2015-05-30, at 10:28, Tassilo Horn <tsdh@gnu.org> wrote:

> Marcin Borkowski <mbork@mbork.pl> writes:
>
> Hi Marcin,
>
>> I googled a bit, and could not find /real-world/ examples of using
>> lexical binding and its advantages /in Emacs Lisp/.  I understand that
>> it's a nice thing to be able to create closures, and that lexical
>> binding is in general faster than dynamic binding (which is a bonus in
>> itself), but could anyone show me a real /text editing/ problem that
>> lexical binding solves, like something that is easier done with
>> l.b. than with d.b.?  (Examples of general-purpose programming
>> problems made easier with l.b. are more or less obvious/easy to find,
>> but Emacs is a text editor, after all, and this is its primary area.)
>
> The emacs paper has a section explaining why emacs used dynamic binding
> from the start: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17

Yes, I'm aware of that, and I read this paper some time ago (even before
asking my question).

> However, to me the two example use-cases only motivate why you want to
> be able to use dynamic scoping for special variables (defvar), not
> really for local variables (let) or function parameters, although the
> first Edit Picture example explicitly speaks of binding command
> arguments but I don't understand it.
>
> To me, having lexical scoping in general plus special, dynamically bound
> variables is the ideal model.  If there wouldn't be special variables
> anymore, the examples from the paper would need to be implemented by
> setq-ing the variables and later re-setting them to their old value
> which would be error-prone and wouldn't work if we ever get concurrency.
> You can make special variables thread-local like in Clojure thus hiding
> this additional complexity from programmers.
>
> But there are good use-cases for dynamic variables also in "normal"
> programs.  One example is to be able to bind some *error-handler*
> dynamically in order to customize how to cope with errors that happen
> far below the call stack.
>
> I'm not able to come up with benefits of lexical scoping which are
> especially important for editing text.  The general benefits of being
> safer, faster, and having closures are still valid of course.

Exactly.  What I'm curious is how lexical scoping might make some tasks
*connected to editing* easier/more natural.

> Bye,
> Tassilo

Thanks,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-05-30 12:59   ` Pascal J. Bourguignon
@ 2015-06-14 10:55     ` Marcin Borkowski
       [not found]     ` <mailman.4977.1434279342.904.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 32+ messages in thread
From: Marcin Borkowski @ 2015-06-14 10:55 UTC (permalink / raw)
  To: help-gnu-emacs


On 2015-05-30, at 14:59, Pascal J. Bourguignon <pjb@informatimago.com> wrote:

> Tassilo Horn <tsdh@gnu.org> writes:
>
>> The emacs paper has a section explaining why emacs used dynamic binding
>> from the start: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17
>>
>> However, to me the two example use-cases only motivate why you want to
>> be able to use dynamic scoping for special variables (defvar), not
>> really for local variables (let) or function parameters, although the
>> first Edit Picture example explicitly speaks of binding command
>> arguments but I don't understand it.
>
> Indeed, in general, you want lexical binding for local variables.
>
> However, I would argue that for global variables, lexical binding would
> be useful too, even by default.
>
> In Common Lisp, we can implement global lexical variables, using
> eg. symbol macros, but in emacs lisp, we're missing operators for the
> global lexical case:
>
>             dynamic   lexical
>   global    defvar    -
>   local     let(1)    let(2)
>
>   (1) when lexical-binding is nil or the variable has been defvar'ed.
>   (2) when lexical-binding is t and the variable has not been defvar'ed.
>
>
>> But there are good use-cases for dynamic variables also in "normal"
>> programs.  One example is to be able to bind some *error-handler*
>> dynamically in order to customize how to cope with errors that happen
>> far below the call stack.
>
> Definitely.
>
> https://groups.google.com/forum/#!original/comp.lang.lisp/oC5gDvn42pM/IudCXzCtxowJ

I'm sorry to say that I didn't understand that post.  (Though I admit
that I didn't try /very/ hard.  I'll try harder again later.)

Thanks anyway,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
       [not found]   ` <mailman.4976.1434279182.904.help-gnu-emacs@gnu.org>
@ 2015-06-14 11:31     ` Pascal J. Bourguignon
  2015-06-16 23:48       ` Jim Diamond
  0 siblings, 1 reply; 32+ messages in thread
From: Pascal J. Bourguignon @ 2015-06-14 11:31 UTC (permalink / raw)
  To: help-gnu-emacs

Marcin Borkowski <mbork@mbork.pl> writes:

> Exactly.  What I'm curious is how lexical scoping might make some tasks
> *connected to editing* easier/more natural.


It depends what you mean by "editing".

Until a few decades ago, editing was performed using red pens, paper, 
scissors, glue.  Then, lexical scoping was totally useless.


Nowdays, editing is performed by software programs.

Writing programs is easier and more natural with lexical scoping, IN
GENERAL!

Therefore, it is easier and mode natural IN PARTICULAR, to write editing
programs.

Writing programs in general is not *connected to editing*.
But writing editor programs in particular is particularly *connected to
editing*, even if programming has nothing to do with editing at all,
ever.

Actually, the programming activity has never anything to do with the
application domain!



When programming a four legged robot running across fields and parkings,
the programmer DOES NOT run across fields and parkings, on his four. 

I repeat, this is very important: when programming a four legged robot
running across fields and parkings, the programmer DOES NOT run across
fields and parkings, on his four. 

No, what the programmer does, is sit on his ass, think, and type a
program into a computer, using a keyboard. 



Now with editing, there may be some understandable confusion, since the
programmer will actually use an editor to edit his program, notably when
writing an editing program.  But you must distinguish the editor being
used to write the program from the editor program being written!

For example, you could use ed to edit the emacs editor program.  The
fact that you will be happier and write a better emacs editor program
using lexical scoping has NOTHING to do with how the ed editor edits
your editor program!  Just like you don't run in the fields when you
write a robot that runs in the fields.

-- 
__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: Real-life examples of lexical binding in Emacs Lisp
       [not found]     ` <mailman.4977.1434279342.904.help-gnu-emacs@gnu.org>
@ 2015-06-14 20:04       ` Stefan Monnier
  2015-06-14 21:44         ` Pascal J. Bourguignon
  0 siblings, 1 reply; 32+ messages in thread
From: Stefan Monnier @ 2015-06-14 20:04 UTC (permalink / raw)
  To: help-gnu-emacs

>> However, I would argue that for global variables, lexical binding would
>> be useful too, even by default.

I'm not sure what that means.  But you can set a global value to
a variable without declaring it as dynamically scoped:

    (setq my-lex-var 3)

Inside Emacs we also have a few global vars (e.g. `pi' and `argv') which
we would want to declare with something like defvar for various reasons
(providing a docstring, recording where is the declaration, etc...) yet
we don't want them to be dynamically scoped.

For `pi' we just used `setq', and for `argv' we used defvar followed by
an ugly hack called internal-make-var-non-special.


        Stefan


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-14 20:04       ` Stefan Monnier
@ 2015-06-14 21:44         ` Pascal J. Bourguignon
  2015-06-14 21:49           ` Pascal J. Bourguignon
  0 siblings, 1 reply; 32+ messages in thread
From: Pascal J. Bourguignon @ 2015-06-14 21:44 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>> However, I would argue that for global variables, lexical binding would
>>> be useful too, even by default.
>
> I'm not sure what that means.  But you can set a global value to
> a variable without declaring it as dynamically scoped:
>
>     (setq my-lex-var 3)

Wrong.

Having a file lex.el:
------------------------------------------------------------------------
;; -*- mode:emacs-lisp; lexical-binding:nil -*-

(setq lexical? 33)
(defun f ()
  lexical?)
(defun g ()
  (let ((lexical? 42))
    (f)))

(print (g))
------------------------------------------------------------------------

Then M-x load-file RET lex.el RET writes 42 in *Message* which shows
that lexical? IS a dynamic variable!  If it was lexical, we would get
33, because the lexical scope of the closure f is the global scope,
where lexical? as been bound to 33, not the local dynamic scope of the
function g when the variable lexical? is bound to 42.


> Inside Emacs we also have a few global vars (e.g. `pi' and `argv') which
> we would want to declare with something like defvar for various reasons
> (providing a docstring, recording where is the declaration, etc...) yet
> we don't want them to be dynamically scoped.
>
> For `pi' we just used `setq', and for `argv' we used defvar followed by
> an ugly hack called internal-make-var-non-special.
>
>
>         Stefan

-- 
__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: Real-life examples of lexical binding in Emacs Lisp
  2015-06-14 21:44         ` Pascal J. Bourguignon
@ 2015-06-14 21:49           ` Pascal J. Bourguignon
  0 siblings, 0 replies; 32+ messages in thread
From: Pascal J. Bourguignon @ 2015-06-14 21:49 UTC (permalink / raw)
  To: help-gnu-emacs

"Pascal J. Bourguignon" <pjb@informatimago.com> writes:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>>>> However, I would argue that for global variables, lexical binding would
>>>> be useful too, even by default.
>>
>> I'm not sure what that means.  But you can set a global value to
>> a variable without declaring it as dynamically scoped:
>>
>>     (setq my-lex-var 3)
>
> Wrong.

Not.

> Having a file lex.el:
> ------------------------------------------------------------------------
> ;; -*- mode:emacs-lisp; lexical-binding:nil -*-
>
> (setq lexical? 33)
> (defun f ()
>   lexical?)
> (defun g ()
>   (let ((lexical? 42))
>     (f)))
>
> (print (g))
> ------------------------------------------------------------------------
>
> Then M-x load-file RET lex.el RET writes 42 in *Message* which shows
> that lexical? IS a dynamic variable!  If it was lexical, we would get
> 33, because the lexical scope of the closure f is the global scope,
> where lexical? as been bound to 33, not the local dynamic scope of the
> function g when the variable lexical? is bound to 42.

Oops, sorry, I intended to run two tests.  With lexical-binding:t
indeed, setq defines the global variable and leaves it lexical.

Reloading the file with lexical-binding:t even suppresses the dynamic
aspect of a previously defined (with defvar) dynamic variable.


-- 
__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: Real-life examples of lexical binding in Emacs Lisp
  2015-06-14 11:31     ` Pascal J. Bourguignon
@ 2015-06-16 23:48       ` Jim Diamond
  2015-06-17  0:06         ` Emanuel Berg
                           ` (3 more replies)
  0 siblings, 4 replies; 32+ messages in thread
From: Jim Diamond @ 2015-06-16 23:48 UTC (permalink / raw)
  To: help-gnu-emacs

On 2015-06-14 at 08:31 ADT, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Marcin Borkowski <mbork@mbork.pl> writes:
>
>> Exactly.  What I'm curious is how lexical scoping might make some tasks
>> *connected to editing* easier/more natural.

<snip>

> Writing programs is easier and more natural with lexical scoping, IN
> GENERAL!

<snip>

Really?  Are there well-agreed-upon studies showing those things?
Or are they your opinion?

It strikes me that lexical scoping is easier to implement for compiled
languages (that is an "off the cuff" comment from someone (me) with
basic knowledge of compiler construction).  But if lexical scoping is
"more natural", is that because more people were "brought up" with
lexically-scoped languages than dynamically-scoped languages?

The first language I "learned" was lexically scoped.  But the first
language I used a lot was dynamically scoped.  It seemed quite
reasonable and natural to me at the time.

A few versions of emacs ago something I was using went from dynamic
scoping to lexical scoping.  Working around that change was not
trivial, casting suspicion on the universality of "easier".

Cheers.
                                Jim


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-16 23:48       ` Jim Diamond
@ 2015-06-17  0:06         ` Emanuel Berg
  2015-06-17  6:23           ` Andreas Röhler
       [not found]           ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org>
  2015-06-17  0:43         ` Pascal J. Bourguignon
                           ` (2 subsequent siblings)
  3 siblings, 2 replies; 32+ messages in thread
From: Emanuel Berg @ 2015-06-17  0:06 UTC (permalink / raw)
  To: help-gnu-emacs

Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca>
writes:

> Really? Are there well-agreed-upon studies showing
> those things? Or are they your opinion?
>
> It strikes me that lexical scoping is easier to
> implement for compiled languages (that is an "off
> the cuff" comment from someone (me) with basic
> knowledge of compiler construction). But if lexical
> scoping is "more natural", is that because more
> people were "brought up" with lexically-scoped
> languages than dynamically-scoped languages?

This discussion is much easier to have if that
confusing terminology is dropped for a second and we
instead study the simple example of a `let' form:

    (let ((scratch-buffer "*scratch*"))
      (when (bufferp scratch-buffer)
        (kill-buffer scratch-buffer) ))

Here we have one piece of data which is used twice, so
that data is named and when it is used it is
indirectly refered to.

In this example, what is natural to me? Answer:
I don't expect `let' to affect any other code than the
code in the `let' itself! And this is "lexical
scoping".

Is it really so, that you expect it to be in another
way? If so - OK. I don't think most people feel like
that and I certainly don't, because I don't program
that way and the impression is made even stronger with
the LISP syntax of enclosed lists.

-- 
underground experts united
http://user.it.uu.se/~embe8573


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-16 23:48       ` Jim Diamond
  2015-06-17  0:06         ` Emanuel Berg
@ 2015-06-17  0:43         ` Pascal J. Bourguignon
  2015-06-17 16:02         ` Phillip Lord
       [not found]         ` <mailman.5167.1434556959.904.help-gnu-emacs@gnu.org>
  3 siblings, 0 replies; 32+ messages in thread
From: Pascal J. Bourguignon @ 2015-06-17  0:43 UTC (permalink / raw)
  To: help-gnu-emacs

Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca> writes:

> On 2015-06-14 at 08:31 ADT, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>> Marcin Borkowski <mbork@mbork.pl> writes:
>>
>>> Exactly.  What I'm curious is how lexical scoping might make some tasks
>>> *connected to editing* easier/more natural.
>
> <snip>
>
>> Writing programs is easier and more natural with lexical scoping, IN
>> GENERAL!
>
> <snip>
>
> Really?  Are there well-agreed-upon studies showing those things?
> Or are they your opinion?

Yes, there are well-agreed-upon studies showing this.  This is the
reason ALL programming languages created since 1970, use lexical binding
exclusively.


> It strikes me that lexical scoping is easier to implement for compiled
> languages (that is an "off the cuff" comment from someone (me) with
> basic knowledge of compiler construction).  But if lexical scoping is
> "more natural", is that because more people were "brought up" with
> lexically-scoped languages than dynamically-scoped languages?

No, this is for theorical reasons, and in practice, because lexical
scoping allows to understand the semantics of programs by just looking
at the source, without executing it, and therefore make it easier on the
programmers, and ease debugging and maintainance.


> A few versions of emacs ago something I was using went from dynamic
> scoping to lexical scoping.  Working around that change was not
> trivial, casting suspicion on the universality of "easier".

The not trivial comes from the fact that it was wanted to perform the
transition without rewriting all the existing elisp code, not only in
the GNU emacs distribution, but also all the unpublished elisp code on
the disks of all the users.  Therefore, in emacs:

1- dynamic binding is still the default,

2- lexical binding is optional (you have to mark a file specially to get
   it).

There may also be some technicalities with respect to the buffer-local
variables which is an emacs specific complexity; I've not looked into it
yet.



Also, I would say that in emacs, given the number of hooks there are,
lexical binding should demonstrate definite and overwhelming advantages
over dynamic binding, since there is no closure with dynamic binding.

For example, compare:

    (setq lexical-binding nil)
    (let ((message (read-from-minibuffer "Message: ")))
      (push (lambda () (insert message)) text-mode-hook))
    [enter some text, type RET,  then switch to *scratch* and:]
    M-x text-mode RET
    (pop text-mode-hook)

with:

    (setq lexical-binding t)
    (let ((message (read-from-minibuffer "Message: ")))
      (push (lambda () (insert message)) text-mode-hook))
    [enter some text, type RET,  then switch to *scratch* and:]
    M-x text-mode RET
    (pop text-mode-hook)

 
-- 
__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: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17  0:06         ` Emanuel Berg
@ 2015-06-17  6:23           ` Andreas Röhler
       [not found]           ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 32+ messages in thread
From: Andreas Röhler @ 2015-06-17  6:23 UTC (permalink / raw)
  To: help-gnu-emacs


Am 17.06.2015 um 02:06 schrieb Emanuel Berg:
> Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca>
> writes:
>
>> Really? Are there well-agreed-upon studies showing
>> those things? Or are they your opinion?
>>
>> It strikes me that lexical scoping is easier to
>> implement for compiled languages (that is an "off
>> the cuff" comment from someone (me) with basic
>> knowledge of compiler construction). But if lexical
>> scoping is "more natural", is that because more
>> people were "brought up" with lexically-scoped
>> languages than dynamically-scoped languages?
> This discussion is much easier to have if that
> confusing terminology is dropped for a second and we
> instead study the simple example of a `let' form:
>
>      (let ((scratch-buffer "*scratch*"))
>        (when (bufferp scratch-buffer)
>          (kill-buffer scratch-buffer) ))
>
> Here we have one piece of data which is used twice, so
> that data is named and when it is used it is
> indirectly refered to.
>
> In this example, what is natural to me? Answer:
> I don't expect `let' to affect any other code than the
> code in the `let' itself! And this is "lexical
> scoping".

Nonetheless, that's the way Emacs acted all the time, while called 
"dynamically" scoped.

Now with "lexical" we have instead an injection, if a function with same 
arguments' symbol is called inside let.

Seems neither "lexical" nor "dynamic" express the real thing.






^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
       [not found]           ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org>
@ 2015-06-17 10:49             ` Pascal J. Bourguignon
  2015-06-17 10:53               ` Pascal J. Bourguignon
  2015-06-17 20:33             ` Real-life examples of lexical binding in Emacs Lisp Emanuel Berg
  1 sibling, 1 reply; 32+ messages in thread
From: Pascal J. Bourguignon @ 2015-06-17 10:49 UTC (permalink / raw)
  To: help-gnu-emacs

Andreas Röhler <andreas.roehler@easy-emacs.de> writes:

> Am 17.06.2015 um 02:06 schrieb Emanuel Berg:
>> Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca>
>> writes:
>>
>>> Really? Are there well-agreed-upon studies showing
>>> those things? Or are they your opinion?
>>>
>>> It strikes me that lexical scoping is easier to
>>> implement for compiled languages (that is an "off
>>> the cuff" comment from someone (me) with basic
>>> knowledge of compiler construction). But if lexical
>>> scoping is "more natural", is that because more
>>> people were "brought up" with lexically-scoped
>>> languages than dynamically-scoped languages?
>> This discussion is much easier to have if that
>> confusing terminology is dropped for a second and we
>> instead study the simple example of a `let' form:
>>
>>      (let ((scratch-buffer "*scratch*"))
>>        (when (bufferp scratch-buffer)
>>          (kill-buffer scratch-buffer) ))
>>
>> Here we have one piece of data which is used twice, so
>> that data is named and when it is used it is
>> indirectly refered to.
>>
>> In this example, what is natural to me? Answer:
>> I don't expect `let' to affect any other code than the
>> code in the `let' itself! And this is "lexical
>> scoping".
>
> Nonetheless, that's the way Emacs acted all the time, while called
> "dynamically" scoped.
>
> Now with "lexical" we have instead an injection, if a function with
> same arguments' symbol is called inside let.
>
> Seems neither "lexical" nor "dynamic" express the real thing.

To be more concrete, here is a case where something wrong happens:

     (setf lexical-binding nil)

     (defun do-something (arg) (format "\n%S\n" arg))

     (defun some-function (arg)
        (setf scratch-buffer (get-buffer-create " *some-function scratch buffer*"))
        (with-current-buffer scratch-buffer (insert (do-something arg))))

     (defun some-other-function ()
        (with-current-buffer scratch-buffer
           (buffer-substring (point-min) (point-max))))

     ;; and then in some unrelated code in a different file:

     (setq lexical-binding nil)
     (let ((scratch-buffer (get-buffer-create "*scratch*")))
        (with-current-buffer scratch-buffer (insert "hello"))
        (some-function "Howdy?")
        (with-current-buffer scratch-buffer
          (buffer-substring (point-min) (point-max))))
    -->
    "
    \"Howdy?\"

    \"Howdy?\"
    "

    ; instead of "hello" !!!

On the other hand, if you use lexical binding:

     (setq lexical-binding t)
     (let ((scratch-buffer (get-buffer-create "*scratch*")))
        (with-current-buffer scratch-buffer (insert "hello"))
        (some-function "Howdy?")
        (with-current-buffer scratch-buffer
          (buffer-substring-no-properties (point-min) (point-max))))
    -->
    ";; This buffer is for notes you don't want to save, and for Lisp evaluation.
    ;; If you want to create a file, visit that file with C-x C-f,
    ;; then enter the text in that file's own buffer.
    hello"

then this independent code stays independent and clean, and no other
function may fuck it.

-- 
__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: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 10:49             ` Pascal J. Bourguignon
@ 2015-06-17 10:53               ` Pascal J. Bourguignon
  2015-06-17 14:42                 ` Stefan Monnier
  0 siblings, 1 reply; 32+ messages in thread
From: Pascal J. Bourguignon @ 2015-06-17 10:53 UTC (permalink / raw)
  To: help-gnu-emacs

"Pascal J. Bourguignon" <pjb@informatimago.com> writes:

>      ;; and then in some unrelated code in a different file:
>
>      (setq lexical-binding nil)
>      (let ((scratch-buffer (get-buffer-create "*scratch*")))
>         (with-current-buffer scratch-buffer (insert "hello"))
>         (some-function "Howdy?")
>         (with-current-buffer scratch-buffer
>           (buffer-substring (point-min) (point-max))))

Without lexical binding, to try to get some independence from other
functions, you would have to PREFIX ALL THE LOCAL VARIABLES WITH
FUNCTION SPECIFIC PREFIXES!
 

    (defun pjb-package--pjb-example-function ()
      (let ((pjb-package--pjb-example-function--scratch-buffer (get-buffer-create "*scratch*")))
         (with-current-buffer pjb-package--pjb-example-function--scratch-buffer
            (insert "hello"))
         (some-function "Howdy?")
         (with-current-buffer pjb-package--pjb-example-function--scratch-buffer
           (buffer-substring (point-min) (point-max)))))

And this is only a convention that wouldn't prevent
another-package--evil-function to modify
pjb-package--pjb-example-function--scratch-buffer anyways.


Now look at all the el code arround, and count how many local variables
are named like this!!!  


-- 
__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: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 10:53               ` Pascal J. Bourguignon
@ 2015-06-17 14:42                 ` Stefan Monnier
  2015-06-17 16:19                   ` Andreas Röhler
                                     ` (2 more replies)
  0 siblings, 3 replies; 32+ messages in thread
From: Stefan Monnier @ 2015-06-17 14:42 UTC (permalink / raw)
  To: help-gnu-emacs

> Without lexical binding, to try to get some independence from other
> functions, you would have to PREFIX ALL THE LOCAL VARIABLES WITH
> FUNCTION SPECIFIC PREFIXES!

Actually, not really.  The Elisp convention to only use prefixes for
global variables is 99% sufficient.  In your example, the problem is
that `some-function' modifies the (presumably global) variable
`scratch-buffer' and that this variable does not have an
appropriate prefix.

The only case where non-prefixed local variables cause problem is when
you introduce higher-order functions, as in:

   (defun my-map (f l)
     (if l (cons (funcall f (car l)) (my-map f (cdr l)))))

   (defun my-function (input)
     (let ((l ...))
       (my-map (lambda (x) (unless (memq x l) (error "invalid mapping")))
               input)))

Suddenly the `l' used inside the lambda will not refer to the `l' nearby
but to the `l' argument of `my-map'.  For this reason, some higher-order
functions used to use weird argument names to try and avoid such
name capture.  Nowadays they can use lexical scoping and hence choose
their variable names sanely and without fear.


        Stefan


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-16 23:48       ` Jim Diamond
  2015-06-17  0:06         ` Emanuel Berg
  2015-06-17  0:43         ` Pascal J. Bourguignon
@ 2015-06-17 16:02         ` Phillip Lord
       [not found]         ` <mailman.5167.1434556959.904.help-gnu-emacs@gnu.org>
  3 siblings, 0 replies; 32+ messages in thread
From: Phillip Lord @ 2015-06-17 16:02 UTC (permalink / raw)
  To: Jim Diamond; +Cc: help-gnu-emacs

Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca> writes:
> The first language I "learned" was lexically scoped.  But the first
> language I used a lot was dynamically scoped.  It seemed quite
> reasonable and natural to me at the time.
>
> A few versions of emacs ago something I was using went from dynamic
> scoping to lexical scoping.  Working around that change was not
> trivial, casting suspicion on the universality of "easier".


You should write these problems up, with your solutions. Potentially
useful to someone else, iff they have the same problems.

Phil



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 14:42                 ` Stefan Monnier
@ 2015-06-17 16:19                   ` Andreas Röhler
  2015-06-17 19:30                     ` Tassilo Horn
       [not found]                   ` <mailman.5171.1434557990.904.help-gnu-emacs@gnu.org>
  2015-06-17 20:22                   ` Emanuel Berg
  2 siblings, 1 reply; 32+ messages in thread
From: Andreas Röhler @ 2015-06-17 16:19 UTC (permalink / raw)
  To: help-gnu-emacs


Am 17.06.2015 um 16:42 schrieb Stefan Monnier:
>> Without lexical binding, to try to get some independence from other
>> functions, you would have to PREFIX ALL THE LOCAL VARIABLES WITH
>> FUNCTION SPECIFIC PREFIXES!
> Actually, not really.  The Elisp convention to only use prefixes for
> global variables is 99% sufficient.  In your example, the problem is
> that `some-function' modifies the (presumably global) variable
> `scratch-buffer' and that this variable does not have an
> appropriate prefix.
>
> The only case where non-prefixed local variables cause problem is when
> you introduce higher-order functions, as in:
>
>     (defun my-map (f l)
>       (if l (cons (funcall f (car l)) (my-map f (cdr l)))))
>
>     (defun my-function (input)
>       (let ((l ...))
>         (my-map (lambda (x) (unless (memq x l) (error "invalid mapping")))
>                 input)))
>
> Suddenly the `l' used inside the lambda will not refer to the `l' nearby
> but to the `l' argument of `my-map'.  For this reason, some higher-order
> functions used to use weird argument names to try and avoid such
> name capture.  Nowadays they can use lexical scoping and hence choose
> their variable names sanely and without fear.
>
>

Checked this with

;;; -*- lexical-binding: t; -*-

(defun my-map (f l)
   (if l (cons (funcall f (car l)) (my-map f (cdr l)))))

(defun my-function (input)
   (let ((l ()))
     (my-map (lambda (x) (unless (memq x l) (error "invalid mapping")))
         input)))

(my-function '(4 5))

Got identic results also without lexical-binding seen here. l is taken 
from inside lambda in both modes.






^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
       [not found]                   ` <mailman.5171.1434557990.904.help-gnu-emacs@gnu.org>
@ 2015-06-17 17:12                     ` Stefan Monnier
  0 siblings, 0 replies; 32+ messages in thread
From: Stefan Monnier @ 2015-06-17 17:12 UTC (permalink / raw)
  To: help-gnu-emacs

> Got identical results also without lexical-binding seen here.

You obviously botched the test for when lexical-binding is nil.
My crystal ball tells me you just changed the ":t" to ":nil" without
making sure this directive is re-evaluated (which happens when the file
is opened).

> l is taken from inside lambda in both modes.

This doesn't make any sense: there is no `l' bound inside the lambda.


        Stefan


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 16:19                   ` Andreas Röhler
@ 2015-06-17 19:30                     ` Tassilo Horn
  0 siblings, 0 replies; 32+ messages in thread
From: Tassilo Horn @ 2015-06-17 19:30 UTC (permalink / raw)
  To: Andreas Röhler; +Cc: help-gnu-emacs

Andreas Röhler <andreas.roehler@easy-emacs.de> writes:

> ;;; -*- lexical-binding: t; -*-
>
> (defun my-map (f l)
>   (if l (cons (funcall f (car l)) (my-map f (cdr l)))))
>
> (defun my-function (input)
>   (let ((l ()))
>     (my-map (lambda (x) (unless (memq x l) (error "invalid mapping")))
>         input)))
>
> (my-function '(4 5))
>
> Got identic results also without lexical-binding seen here.  l is
> taken from inside lambda in both modes.

You have to byte-compile.  Then you get for the lexical version:

--8<---------------cut here---------------start------------->8---
byte code for my-function:
  doc:   ...
  args: 257
0	constant  nil
1	constant  my-map
2	constant  make-byte-code
3	constant  257
4	constant  "\211\300>?\205\n.\301\302!\207"
5	constant  vconcat
6	constant  vector
7	stack-ref 6
9	call	  1
10	constant  [error "invalid mapping"]
11	call	  2
12	constant  3
13	constant  "\n\n(fn X)"
14	call	  5
15	stack-ref 3
16	call	  2
17	return	  
--8<---------------cut here---------------end--------------->8---

That gives:

  (my-function '(4 5)) => Lisp error: (error "invalid mapping")

For the dynamic version:

--8<---------------cut here---------------start------------->8---
byte code for my-function:
  args: (input)
0	constant  nil
1	varbind	  l
2	constant  my-map
3	constant  <compiled-function>
      args: (x)
    0	    varref    x
    1	    varref    l
    2	    memq      
    3	    not	      
    4	    goto-if-nil-else-pop 1
    7	    constant  error
    8	    constant  "invalid mapping"
    9	    call      1
    10:1    return    

4	varref	  input
5	call	  2
6	unbind	  1
7	return	  
--8<---------------cut here---------------end--------------->8---

Note the varref l.  When the lambda is called in the dynamic version, l
will refer to the l argument from my-map.

That gives:

  (my-function '(4 5)) => (nil nil)

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 14:42                 ` Stefan Monnier
  2015-06-17 16:19                   ` Andreas Röhler
       [not found]                   ` <mailman.5171.1434557990.904.help-gnu-emacs@gnu.org>
@ 2015-06-17 20:22                   ` Emanuel Berg
  2015-06-17 22:13                     ` Pascal J. Bourguignon
  2015-06-18 14:57                     ` Udyant Wig
  2 siblings, 2 replies; 32+ messages in thread
From: Emanuel Berg @ 2015-06-17 20:22 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> independence from other functions, you would have
>> to PREFIX ALL THE LOCAL VARIABLES WITH FUNCTION
>> SPECIFIC PREFIXES!
>
> Actually, not really. The Elisp convention to only
> use prefixes for global variables is 99% sufficient.
> In your example, the problem is that `some-function'
> modifies the (presumably global) variable
> `scratch-buffer' and that this variable does not
> have an appropriate prefix.

I'm curious, the techno-science books always speak of
LISP as a language for "symbolic manipulation".
Sometimes they mention AI. Anyone care to explain
this? Does it somehow relate to the "dynamic scope"?
Or is an implementation-derived situation, i.e.
a practical measure somewhere along the way?

> The only case where non-prefixed local variables
> cause problem is when you introduce higher-order
> functions, as in:
>
>    (defun my-map (f l) (if l (cons (funcall f (car l))
> (my-map f (cdr l)))))
>
>    (defun my-function (input) (let ((l ...)) (my-map
> (lambda (x) (unless (memq x l) (error "invalid
> mapping"))) input)))
>
> Suddenly the `l' used inside the lambda will not
> refer to the `l' nearby but to the `l' argument of
> `my-map'. For this reason, some higher-order
> functions used to use weird argument names to try
> and avoid such name capture. Nowadays they can use
> lexical scoping and hence choose their variable
> names sanely and without fear.

And that is not only desired for that reason but also
for "1-order functions" (? - i.e., a plebeian function
with non-function arguments only) because then you can
just name your variables whatever comes to mind - be
it good or bad, you don't want to worry about the
world outside that cozy form. It is the blue collar
bottom up, contrary to the "top-down" (yuk!) hysteria
of white collar hackers...

I once read that "the programmer has the whole program
in his head" (pseudo-quote). That's not how
I experience it. I have some general knowledge of the
entire program for sure, but the only thing I have
100% in my head is the function or even code block I'm
currently typing. The dynamic scope breaks that zone
of comfort, which here, is where you want to be.

This "dynamic scope" as a method is like programming
on acid with the ant queen communicating to her
minions through telepathy telling them what to do all
the time. "Lexical scope" is layed-back, having the
ants do their work semi-autonomously, now and then
interfering to solve a well-defined and delimited
problem. ... Right?

-- 
underground experts united
http://user.it.uu.se/~embe8573


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
       [not found]           ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org>
  2015-06-17 10:49             ` Pascal J. Bourguignon
@ 2015-06-17 20:33             ` Emanuel Berg
  2015-06-17 22:07               ` Robert Thorpe
  1 sibling, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2015-06-17 20:33 UTC (permalink / raw)
  To: help-gnu-emacs

Andreas Röhler <andreas.roehler@easy-emacs.de> writes:

> Seems neither "lexical" nor "dynamic" express the
> real thing.

I take it "lexical" refers to you can make it out by
looking at the code.

"Dynamic" refers to it depends on the code and the
program state in execution.

I agree those terms are confusing. To me, it sounds
like they refer to call-by-value vs.
call-by-reference, which isn't so.

I'd call it "normal scope" vs.
"stacked scope", perhaps.

> Nonetheless, that's the way Emacs acted all the
> time, while called "dynamically" scoped.

Well yeah, no one said it can't be done that way.
I experience it as unnatural and consider it
unpractical, but I'm not saying it cannot be done that
way. The supreme techno-pope will beat his cardinals
to the punch using anything, however typically he is
using the *best* thing (that's why he is number one)
and then the cardinals better do the same if they can
less they are at an ever worse disadvantage. No one is
telling you you can't use it or that it is inherently
bad and always so. However tho a non-conformist myself
I dare say here my intuition coincides with how most
programmers will see it - be it by genes or upbringing.

-- 
underground experts united
http://user.it.uu.se/~embe8573


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 20:33             ` Real-life examples of lexical binding in Emacs Lisp Emanuel Berg
@ 2015-06-17 22:07               ` Robert Thorpe
  2015-06-17 22:17                 ` Pascal J. Bourguignon
  0 siblings, 1 reply; 32+ messages in thread
From: Robert Thorpe @ 2015-06-17 22:07 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: help-gnu-emacs

Emanuel Berg <embe8573@student.uu.se> writes:
> I take it "lexical" refers to you can make it out by
> looking at the code.

Yes.

> "Dynamic" refers to it depends on the code and the
> program state in execution.

Yes.

> I agree those terms are confusing. To me, it sounds
> like they refer to call-by-value vs.
> call-by-reference, which isn't so.
>
> I'd call it "normal scope" vs.
> "stacked scope", perhaps.

Both cases are usually implemented using stacks.  Thinking about this
helps understanding.

In the lexical scope case we can think of one huge stack.  Each entry in
the stack can contain many elements.  When execution enters a "let" form
a new entry is created on the stack and the variables declared there are
stored in that entry.  They "shadow" other variables with the same name
- they take precedence over them.  When execution exits the let form
that stack entry is deleted.  This is usually how lexical scope is
implement too.

For dynamic scope we can think of each variable name as being associated
with it's own stack.  When execution reaches a let form a new value is
pushed onto the stack for the relevant name.  When the let form exits
it's deleted from the top of the stack.  Code always uses the
top-of-stack value, so earlier let forms are shadowed by later ones.
This is one way of implementing dynamic scope too, it's "shallow
binding".  I think it's how Elisp implements it.

Dynamic scope was an accident of how Lisp was first written.  See:
http://www-formal.stanford.edu/jmc/history/lisp/node4.html

The question of "extent" rather than "scope" brings up more problems.
So does "deep" vs "shallow" binding with dynamic scope.

BR,
Robert Thorpe



^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 20:22                   ` Emanuel Berg
@ 2015-06-17 22:13                     ` Pascal J. Bourguignon
  2015-06-17 23:46                       ` Emanuel Berg
  2015-06-18 14:57                     ` Udyant Wig
  1 sibling, 1 reply; 32+ messages in thread
From: Pascal J. Bourguignon @ 2015-06-17 22:13 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <embe8573@student.uu.se> writes:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>>> independence from other functions, you would have
>>> to PREFIX ALL THE LOCAL VARIABLES WITH FUNCTION
>>> SPECIFIC PREFIXES!
>>
>> Actually, not really. The Elisp convention to only
>> use prefixes for global variables is 99% sufficient.
>> In your example, the problem is that `some-function'
>> modifies the (presumably global) variable
>> `scratch-buffer' and that this variable does not
>> have an appropriate prefix.
>
> I'm curious, the techno-science books always speak of
> LISP as a language for "symbolic manipulation".
> Sometimes they mention AI. Anyone care to explain
> this? 

This is because the stress the language puts on symbols and symbolic
expressions (sexps) and the availability of operators to easily process
them.

Consider a simple function to derivate functions (it's about 100 lines
of lisp code), allowing to do things like:

    (simplify (deriv-expr '(+ (* 3 x x) (* 9 x) 3) 'x))
    --> (+ (* 6 x) 9)

Or consider some natural language processing program, like eliza, or
this expression generator: http://paste.lisp.org/+37QP 

In early eliza, the natural language words were represented using
symbols (nowadays, lisp NLP programs would use strings for the
representation of words, or even CLOS objects, but there would still be
good arguments for the use of symbols with property lists in terms of
simplicity and flexibility).

Anyways, in expressions like:

    (defvar insults
      '(
        ("accapareur" (nm))
        ("aérolithe" (nm))
        ("amiral de bateau­lavoir" (gnm))
        ("anacoluthe" (nf))
        ("analphabète" (n a))
        ("athlète complet" (n))
        ("boit­sans­soif" (ni))
        ("vieux" (a))
        ;; …
        ))

    (defvar nm (remove-if-not (lambda (x) (intersection '(n np nm gnm) (second x))) insults))
    (defvar nf (remove-if-not (lambda (x) (intersection '(nf np) (second x))) insults))
    (defvar ad (remove-if-not (lambda (x) (member 'a (second x))) insults))

the use of symbols to denote the grammatical categories, and their
manipulation to sort out the lexicon is very easy and natural.

In lisp, it's easy to program something like that, because you don't
need to do anything special to encode a symbol like x or nm.

In other programming language, the stress is often on some other data
type, like int in C (if you don't write a type when declaring a
variable, which is possible in C, it is int by default!).  And you will
also have vectors instead of lists, so as soon as you write a collection
of data, you will HAVE to use integers, to index into those vectors (in
lisp when using lists, you don't need integers, just the functions first
and rest).

So in those non-lisp languages, you will have to invent a representation
for these symbolic data, using integers (constants, or enums), or
strings, (or even objects! in OO languages). And naturally you will have
to encode the data using those vectors of integers (and what if you need
to mix integers representing integers and integer representing symbols
as in  (+ (* 3 x x) (* 9 x) 3)? Dang! Now you need some more complex
representtion, perhaps a structure or an object with variants for
integers and symbols.  And soon you're re-implementing a half-assed
buggy lisp: you are greenspunning.


A function to perform symbolic derivation was one of the first lisp
programs written by John McCarthy, this was exactly the kind of
application he had in mind for lisp; nowadays we have maxima :-)
(And mathematica which is to maxima what ruby is to lisp).

For an early symbolic application have a look at Wang's algorithm for
propositional calculus:
http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/wang.html



> Does it somehow relate to the "dynamic scope"?

Not at all.  Dynamic scope was just an implementation accident, because
not enough about language design was know when lisp was invented.

When you don't have theory, programs may just happen to behave a certain
way depending on how they're implemented.  This is what occured for
lisp.  McCarthy wanted to be able to define anonymous functions using
Church's lambda notation, and it was implemented, but since we didn't
have the language design theory about scopes and bindings, it just
happened that dynamic binding as implemented, and then somebody remarked
that this was a problem (the so called funarg problem), and they spent
ten years developing the theory and practical solution with lexical
binding.


> Or is an implementation-derived situation, i.e.
> a practical measure somewhere along the way?

Yes. 

> I once read that "the programmer has the whole program
> in his head" (pseudo-quote). That's not how
> I experience it. I have some general knowledge of the
> entire program for sure, but the only thing I have
> 100% in my head is the function or even code block I'm
> currently typing. The dynamic scope breaks that zone
> of comfort, which here, is where you want to be.

Of course. You could have the whole program in your head, when computers
had 4 Kwords of memory, and the whole program was at most a ten-page
listing.

But nowadays programs are tens of megabytes of sources!

(Firefox sources were more than 50 megabytes last time I checked; there
are more than 50 MB; emacs are 51 MB compressed!
$ ls -lh /usr/local/src/emacs-24.3.tar.gz 
-rw-r--r-- 1 pjb pjb 51M Dec  1  2013 /usr/local/src/emacs-24.3.tar.gz
I've got more than 2.5 GIGA bytes of Common Lisp libraries sources!
$ du -shc ~/quicklisp/dists/
2.6G	/home/pjb/quicklisp/dists/

Granted, this is not a single program, but a given program could use any
subset of those libraries, so it is very important to ensure
encapsulation, data hiding and locality of effects, and only lexical
binding does that, not dynamic binding.


> This "dynamic scope" as a method is like programming
> on acid with the ant queen communicating to her
> minions through telepathy telling them what to do all
> the time. "Lexical scope" is layed-back, having the
> ants do their work semi-autonomously, now and then
> interfering to solve a well-defined and delimited
> problem. ... Right?

Indeed.

A dynamic variable is global for the time of the dynamic scope.
A lexical variable is local, for the space of the lexical scope.

Notice time/space.  This is important.

Lexical means space, something that is statical and easily observable,
eternal, with delimited contours.

Dynamic means time, something that is dynamic, changing with time, and
therefore more difficult to conceptualize and observe.  We cannot
"observe" time, we have to transform it into slowly moving mechanisms,
so that we observe the SPACIAL position of the hands.  Also, it's proven
scientifically, that the brain constructs time perception in a
non monotonous and linear way (check the experience, where we flash
successive dots aligned on a screen at a given rythm, red dots on the left side, and
green dot on the right side.  People will tell you that the dots changed
color right in the middle between the red and green dots, which is not
possible, because they didn't know that the next dot would be green at
the time the imaginary moving dot passed on this middle!  So time is
hard on us, and dynamic is difficult to reason about, and therefore it
leads to more bugs.


-- 
__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: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 22:07               ` Robert Thorpe
@ 2015-06-17 22:17                 ` Pascal J. Bourguignon
  0 siblings, 0 replies; 32+ messages in thread
From: Pascal J. Bourguignon @ 2015-06-17 22:17 UTC (permalink / raw)
  To: help-gnu-emacs

Robert Thorpe <rt@robertthorpeconsulting.com> writes:

> Emanuel Berg <embe8573@student.uu.se> writes:
>> I take it "lexical" refers to you can make it out by
>> looking at the code.
>
> Yes.
>
>> "Dynamic" refers to it depends on the code and the
>> program state in execution.
>
> Yes.
>
>> I agree those terms are confusing. To me, it sounds
>> like they refer to call-by-value vs.
>> call-by-reference, which isn't so.
>>
>> I'd call it "normal scope" vs.
>> "stacked scope", perhaps.
>
> Both cases are usually implemented using stacks.  Thinking about this
> helps understanding.
>
> In the lexical scope case we can think of one huge stack.  Each entry in
> the stack can contain many elements.  When execution enters a "let" form
> a new entry is created on the stack and the variables declared there are
> stored in that entry.  They "shadow" other variables with the same name
> - they take precedence over them.  When execution exits the let form
> that stack entry is deleted.  This is usually how lexical scope is
> implement too.

However, contrarily to dynamic binding, lexical binding requires the use
of the heap to implement non-delimited closures.

This is why it was less obvious.

-- 
__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: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 22:13                     ` Pascal J. Bourguignon
@ 2015-06-17 23:46                       ` Emanuel Berg
  0 siblings, 0 replies; 32+ messages in thread
From: Emanuel Berg @ 2015-06-17 23:46 UTC (permalink / raw)
  To: help-gnu-emacs

"Pascal J. Bourguignon" <pjb@informatimago.com>
writes:

> This is because the stress the language puts on
> symbols and symbolic expressions (sexps) and the
> availability of operators to easily process them ...

Man, you should send this post to a magazine!

-- 
underground experts united
http://user.it.uu.se/~embe8573


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-17 20:22                   ` Emanuel Berg
  2015-06-17 22:13                     ` Pascal J. Bourguignon
@ 2015-06-18 14:57                     ` Udyant Wig
  2015-06-18 15:47                       ` Emanuel Berg
  1 sibling, 1 reply; 32+ messages in thread
From: Udyant Wig @ 2015-06-18 14:57 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <embe8573@student.uu.se> writes:
> I'm curious, the techno-science books always speak of LISP as a
> language for "symbolic manipulation".

  I really wish they'd get on with the times and start speaking of
  "Lisp" instead of "LISP".
  
-- 
Udyant Wig
GitHub:    https://github.com/udyant
Poetry:    http://www.writing.com/main/profile/biography/frosthrone


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-18 14:57                     ` Udyant Wig
@ 2015-06-18 15:47                       ` Emanuel Berg
  2015-06-19 13:49                         ` Udyant Wig
  0 siblings, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2015-06-18 15:47 UTC (permalink / raw)
  To: help-gnu-emacs

Udyant Wig <udyantw@gmail.com> writes:

>> I'm curious, the techno-science books always speak
>> of LISP as a language for "symbolic manipulation".
>
> I really wish they'd get on with the times and start
> speaking of "Lisp" instead of "LISP".

Is there an agreed-upon rule what is what?

I use "LISP" in the context of the history and origin
of the technology but I don't have a defined endpoint
at what time history gives way to your everyday
"Lisp".

-- 
underground experts united
http://user.it.uu.se/~embe8573


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
  2015-06-18 15:47                       ` Emanuel Berg
@ 2015-06-19 13:49                         ` Udyant Wig
  2015-06-19 17:41                           ` acronymania (was: Re: Real-life examples of lexical binding in Emacs Lisp) Emanuel Berg
  0 siblings, 1 reply; 32+ messages in thread
From: Udyant Wig @ 2015-06-19 13:49 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg <embe8573@student.uu.se> writes:

> I use "LISP" in the context of the history and origin
> of the technology but I don't have a defined endpoint
> at what time history gives way to your everyday
> "Lisp".

  It seems to have been a byproduct of the general attitude that also
  made "UNIX" "Unix", "COBOL" "Cobol", "FORTH" "Forth", "EMACS" "Emacs",
  etc.
  
-- 
Udyant Wig
GitHub:    https://github.com/udyant
Poetry:    http://www.writing.com/main/profile/biography/frosthrone


^ permalink raw reply	[flat|nested] 32+ messages in thread

* acronymania (was: Re: Real-life examples of lexical binding in Emacs Lisp)
  2015-06-19 13:49                         ` Udyant Wig
@ 2015-06-19 17:41                           ` Emanuel Berg
  2015-06-19 17:53                             ` Rusi
  0 siblings, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2015-06-19 17:41 UTC (permalink / raw)
  To: help-gnu-emacs

Udyant Wig <udyantw@gmail.com> writes:

>> I use "LISP" in the context of the history and
>> origin of the technology but I don't have a defined
>> endpoint at what time history gives way to your
>> everyday "Lisp".
>
> It seems to have been a byproduct of the general
> attitude that also made "UNIX" "Unix", "COBOL"
> "Cobol", "FORTH" "Forth", "EMACS" "Emacs", etc.

UNIX, despite being uppercased, isn't an acronym but
a pun/poke on Multics - which by the was *is* an
acronym:

    Multiplexed Information and Computing Service

Only "Multi" should be put within quotation marks as
that part never worked out, which is where the
fun begins.

With UNIX/Unix the distinction is clearer (?) than
with LISP/Lisp as UNIX is the trademark that is
awarded/sold to (at that point) official
implementations - and Unix is everything else.

I consider GNU/Linux to be Unix tho some people insist
it is UN*X, *nix, Unix-like, and so on. Hey, GNU is
not Unix but that's exactly what it is. The "x" in
Linux is a UNIX "x". The instigation to do Linux was
in order to be able to use the university SunOS UNIX,
only at home. It is Unix!

COBOL is an acronym: Common Business-Oriented Language
and like EMACS (acronym/abbreviation of
"Editor MACroS") they have turned into names by now -
simple as that, I suppose.

FORTH isn't an acronym so one might as well make it
a name with no regrets. All of those I would use as
capitalized names, except for perhaps in some
historical contexts - and to be sure, I never speak of
Cobol and so Forth.

-- 
underground experts united
http://user.it.uu.se/~embe8573


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: acronymania (was: Re: Real-life examples of lexical binding in Emacs Lisp)
  2015-06-19 17:41                           ` acronymania (was: Re: Real-life examples of lexical binding in Emacs Lisp) Emanuel Berg
@ 2015-06-19 17:53                             ` Rusi
  0 siblings, 0 replies; 32+ messages in thread
From: Rusi @ 2015-06-19 17:53 UTC (permalink / raw)
  To: help-gnu-emacs

On Friday, June 19, 2015 at 11:04:53 PM UTC+5:30, Emanuel Berg wrote:
> Udyant Wig  writes:
> 
> >> I use "LISP" in the context of the history and
> >> origin of the technology but I don't have a defined
> >> endpoint at what time history gives way to your
> >> everyday "Lisp".
> >
> > It seems to have been a byproduct of the general
> > attitude that also made "UNIX" "Unix", "COBOL"
> > "Cobol", "FORTH" "Forth", "EMACS" "Emacs", etc.
> 
> UNIX, despite being uppercased, isn't an acronym but
> a pun/poke on Multics - which by the was *is* an
> acronym:
> 
>     Multiplexed Information and Computing Service
> 
> Only "Multi" should be put within quotation marks as
> that part never worked out, which is where the
> fun begins.
> 
> With UNIX/Unix the distinction is clearer (?) than
> with LISP/Lisp as UNIX is the trademark that is
> awarded/sold to (at that point) official
> implementations - and Unix is everything else.
> 
> I consider GNU/Linux to be Unix tho some people insist
> it is UN*X, *nix, Unix-like, and so on. Hey, GNU is
> not Unix but that's exactly what it is. The "x" in
> Linux is a UNIX "x". The instigation to do Linux was
> in order to be able to use the university SunOS UNIX,
> only at home. It is Unix!
> 
> COBOL is an acronym: Common Business-Oriented Language
> and like EMACS (acronym/abbreviation of
> "Editor MACroS") they have turned into names by now -
> simple as that, I suppose.
> 
> FORTH isn't an acronym so one might as well make it
> a name with no regrets. All of those I would use as
> capitalized names, except for perhaps in some
> historical contexts - and to be sure, I never speak of
> Cobol and so Forth.

Curiously, I wrote a blog-post recently on a functional programming timeline
http://blog.languager.org/2015/04/cs-history-1.html
in which I mentioned tangentially about the culture of lowercase starting with Unix.

Someone felt strongly enough about the inaccuracies in this that he wrote me
some longer-than-my-post emails about this.
Since this has interesting historical titbits itself (and is too long for 
blogger's comments) its here:
http://blog.languager.org/2015/06/richard-okeefes-responses-to-fp-timeline.html


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: Real-life examples of lexical binding in Emacs Lisp
       [not found]         ` <mailman.5167.1434556959.904.help-gnu-emacs@gnu.org>
@ 2015-06-23 23:49           ` Jim Diamond
  0 siblings, 0 replies; 32+ messages in thread
From: Jim Diamond @ 2015-06-23 23:49 UTC (permalink / raw)
  To: help-gnu-emacs

On 2015-06-17 at 13:02 ADT, Phillip Lord <phillip.lord@newcastle.ac.uk> wrote:
> Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca> writes:
>> The first language I "learned" was lexically scoped.  But the first
>> language I used a lot was dynamically scoped.  It seemed quite
>> reasonable and natural to me at the time.
>>
>> A few versions of emacs ago something I was using went from dynamic
>> scoping to lexical scoping.  Working around that change was not
>> trivial, casting suspicion on the universality of "easier".
>
>
> You should write these problems up, with your solutions.  Potentially
> useful to someone else, iff they have the same problems.

Phil,

It is quite a while ago now, and took me a while to dig up the details.
Reviewing the solution, I see that it required a patch to a file which
went from dynamic scoping to lexical scoping.  Stefan Monnier was a
huge help in getting this sorted out.

Anyone interested in the particular issue and the particular solution
can read the messages in the thread found at
        http://lists.gnu.org/archive/html/help-gnu-emacs/2012-06/msg00040.html
It is not all that long.

Cheers.
                                    Jim


^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2015-06-23 23:49 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-29  8:28 Real-life examples of lexical binding in Emacs Lisp Marcin Borkowski
2015-05-30  8:28 ` Tassilo Horn
2015-06-14 10:52   ` Marcin Borkowski
     [not found]   ` <mailman.4976.1434279182.904.help-gnu-emacs@gnu.org>
2015-06-14 11:31     ` Pascal J. Bourguignon
2015-06-16 23:48       ` Jim Diamond
2015-06-17  0:06         ` Emanuel Berg
2015-06-17  6:23           ` Andreas Röhler
     [not found]           ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org>
2015-06-17 10:49             ` Pascal J. Bourguignon
2015-06-17 10:53               ` Pascal J. Bourguignon
2015-06-17 14:42                 ` Stefan Monnier
2015-06-17 16:19                   ` Andreas Röhler
2015-06-17 19:30                     ` Tassilo Horn
     [not found]                   ` <mailman.5171.1434557990.904.help-gnu-emacs@gnu.org>
2015-06-17 17:12                     ` Stefan Monnier
2015-06-17 20:22                   ` Emanuel Berg
2015-06-17 22:13                     ` Pascal J. Bourguignon
2015-06-17 23:46                       ` Emanuel Berg
2015-06-18 14:57                     ` Udyant Wig
2015-06-18 15:47                       ` Emanuel Berg
2015-06-19 13:49                         ` Udyant Wig
2015-06-19 17:41                           ` acronymania (was: Re: Real-life examples of lexical binding in Emacs Lisp) Emanuel Berg
2015-06-19 17:53                             ` Rusi
2015-06-17 20:33             ` Real-life examples of lexical binding in Emacs Lisp Emanuel Berg
2015-06-17 22:07               ` Robert Thorpe
2015-06-17 22:17                 ` Pascal J. Bourguignon
2015-06-17  0:43         ` Pascal J. Bourguignon
2015-06-17 16:02         ` Phillip Lord
     [not found]         ` <mailman.5167.1434556959.904.help-gnu-emacs@gnu.org>
2015-06-23 23:49           ` Jim Diamond
     [not found] ` <mailman.3950.1432974543.904.help-gnu-emacs@gnu.org>
2015-05-30 12:59   ` Pascal J. Bourguignon
2015-06-14 10:55     ` Marcin Borkowski
     [not found]     ` <mailman.4977.1434279342.904.help-gnu-emacs@gnu.org>
2015-06-14 20:04       ` Stefan Monnier
2015-06-14 21:44         ` Pascal J. Bourguignon
2015-06-14 21:49           ` Pascal J. Bourguignon

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.