help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Real-life examples of lexical binding in Emacs Lisp


From: Pascal J. Bourguignon
Subject: Re: Real-life examples of lexical binding in Emacs Lisp
Date: Wed, 17 Jun 2015 12:49:47 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]