all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Lexical vs. dynamic: small examples?
@ 2021-08-14  3:34 Eduardo Ochs
  2021-08-14  3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor
                   ` (3 more replies)
  0 siblings, 4 replies; 61+ messages in thread
From: Eduardo Ochs @ 2021-08-14  3:34 UTC (permalink / raw)
  To: help-gnu-emacs

Hi list,

I am trying to write a section on lexical vs. dynamic binding for a
tutorial on Emacs Lisp, and I am looking for very short demos that
show how things work differently in dynamic and in lexical binding...

Right now what I have is this:

  http://angg.twu.net/eev-intros/find-lexical-intro.html
  (find-lexical-intro)

I have tried really hard to the make its section "0. How to use this",
that is at:

  http://angg.twu.net/eev-intros/find-lexical-intro.html#0
  (find-lexical-intro "0. How to use this")

both clear AND useful to people who do not use eev, and I think that
the big example in section 3,

  http://angg.twu.net/eev-intros/find-lexical-intro.html#3
  (find-lexical-intro "3. `get/set'")

is quite nice - especially because of its last part, that inspects two
different getter-setter pairs, shows that their lexical environments
are the cadrs of their closures, and shows that `geta' and `seta'
share the same lexical environment and that `getb' and `setb' share
another lexical environment...

My current knowledge of lexical binding stops there, though. Any
comments (or help) would be very welcome...

  Cheers,
    Eduardo Ochs
    http://angg.twu.net/#eev



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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14  3:34 Lexical vs. dynamic: small examples? Eduardo Ochs
@ 2021-08-14  3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14  4:12   ` Eduardo Ochs
  2021-08-14  7:35 ` tomas
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14  3:56 UTC (permalink / raw)
  To: help-gnu-emacs

Eduardo Ochs wrote:

> is quite nice - especially because of its last part, that
> inspects two different getter-setter pairs, shows that their
> lexical environments are the cadrs of their closures, and
> shows that `geta' and `seta' share the same lexical
> environment and that `getb' and `setb' share another lexical
> environment...
>
> My current knowledge of lexical binding stops there, though.
> Any comments (or help) would be very welcome...

OK, IIUC with lexical (AKA static) binding the variable's
value is determined by the code and the scope, so you can
always find out what value it is by looking at that and move
within that and only that delimited area.

Move outside of that the variable bindings don't mean
anything. Move from A to B, and you wanna know what goes on in
B, it doesn't matter what happened in A and you look for the
answer in BB (B and only B).

Have a look:

  (let ((a 1))
    (do-something a) ; 1 is here
    (do-something-else) ) ; but if a is referenced here, it isn't 1
                          ; not the same a!

This is more useful and clear to the regular user and perhaps
the advanced one as well and most people should think this
natural from experience but also from what makes sense looking
at that code :) This style seems to make for more independent,
well-defined, more reusable and less vulnerable units of
computation...

With dynamic binding however the variable's value is rather
read from the top of a stack data structure, everyone who sets
the value then pushes it onto the top of the stack - and when
it is unset that value is popped - but even so if it is
thereafter referenced, it is still defined, one just looks for
the plate below.

This style is more like one mastermind keeping track of
everything thru telepathy...

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14  3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-14  4:12   ` Eduardo Ochs
  0 siblings, 0 replies; 61+ messages in thread
From: Eduardo Ochs @ 2021-08-14  4:12 UTC (permalink / raw)
  To: Emanuel Berg, help-gnu-emacs

On Sat, 14 Aug 2021 at 00:56, Emanuel Berg via Users list for the GNU
Emacs text editor <help-gnu-emacs@gnu.org> wrote:
>
> Have a look:
>
>   (let ((a 1))
>     (do-something a) ; 1 is here
>     (do-something-else) ) ; but if a is referenced here, it isn't 1
>                           ; not the same a!

Hi Emanuel,
Thanks! I converted your idea to this...

(setq a 42)
(defun *a10 () (* a 10))

(let ((a 99))
  (list (* a 10) (*a10))
  )

(let ((b 99))
  (list (* b 10) (*a10))
  )

Cheers =),
  Eduardo Ochs



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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14  3:34 Lexical vs. dynamic: small examples? Eduardo Ochs
  2021-08-14  3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-14  7:35 ` tomas
  2021-08-14 16:00   ` Eduardo Ochs
  2021-08-14 19:31   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14 13:35 ` [External] : " Drew Adams
  2021-08-14 19:00 ` Gregory Heytings
  3 siblings, 2 replies; 61+ messages in thread
From: tomas @ 2021-08-14  7:35 UTC (permalink / raw)
  To: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 2122 bytes --]

On Sat, Aug 14, 2021 at 12:34:31AM -0300, Eduardo Ochs wrote:
> Hi list,
> 
> I am trying to write a section on lexical vs. dynamic binding for a
> tutorial on Emacs Lisp, and I am looking for very short demos that
> show how things work differently in dynamic and in lexical binding...
> 
> Right now what I have is this:
> 
>   http://angg.twu.net/eev-intros/find-lexical-intro.html
>   (find-lexical-intro)

Hm. I have the feeling that it'll difficult to appreciate the
differences between lexical and dynamic bindings whithin such
short snippets. You don't have much room to build up a lexical
environment worth its salt :-)

The metaphor which, for me, did "click" was: lexical binding is
a binding along "space", dynamic binding along "time".

Usually you want both (and civilised languages, like CL, Scheme,
Perl [1] and, of course, Emacs Lisp, the most civilised of all)
do offer facilities for both.

The easiest default, though (for compilers and for users alike)
is lexical binding. Especially if you use other people's code
in yours. Imagine that library `setq'-ing xyzzy "down there",
although xyzzy happens to be an important variable in your
missile-control program (to reuse an already tired analogy ;-)

Of course, civilised library providers wouldn't do that, they
would make sure `xyzzy' is let-bound before `setq'-ing anything.
If the dynamic state doesn't do uncommon things and only walks
the stack "up and down", then it's their variable to `setq',
no matter whether dynamically or lexically.

The corollary is that for most civilised code, there is no
difference whether it is interpreted in a lexical or dynamic
scoping regime.

Stefan, who has taken up the Herculean task of going through
the existing Emacs Lisp code to convert it to lexical sure
has a lot of interesting things to say about that :-)

Cheers

[1] Perl originally had only lexical scope, like any decent
   shell always had. It was with Perl5 (about 1994) that it
   acquired lexical scope (called "my" in Perl-land) as the
   recommended variable localisation strategy.

 - t

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

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

* RE: [External] : Lexical vs. dynamic: small examples?
  2021-08-14  3:34 Lexical vs. dynamic: small examples? Eduardo Ochs
  2021-08-14  3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14  7:35 ` tomas
@ 2021-08-14 13:35 ` Drew Adams
  2021-08-14 16:15   ` Eduardo Ochs
  2021-08-14 19:00 ` Gregory Heytings
  3 siblings, 1 reply; 61+ messages in thread
From: Drew Adams @ 2021-08-14 13:35 UTC (permalink / raw)
  To: Eduardo Ochs, help-gnu-emacs

The advantages of lexical binding are easy to find, and all of them are true advantages, for both programming and program analysis. The advantages of dynamic binding are not so easy to find, but they're quite important to an environment such as that of Emacs.

RMS gave good arguments _for Emacs_ (and similar, user-programmer environments) to support dynamic binding, here:

https://www.gnu.org/software/emacs/emacs-paper.html#SEC17

Every Emacs user should, I think, be aware of these advantages - as well as their attendant limitations/drawbacks.

Support of dynamic binding does _not_ require non-support of lexical binding.  

Common Lisp has purposefully had both from the outset (lexical is the default).  Emacs Lisp took a long time to add lexical binding (and it is still not the default), but it too has both now.  And yes, combining both in the same language provides perils as well as advantages.
___

This 1986 MIT video might be of interest here.  It goes over the introduction of side effects into a purely functional Scheme (Lisp-1 dialect).

https://www.youtube.com/watch?v=jl8EHP1WrWY

It talks about the motivation for doing that (and for dynamic binding, though that might not be mentioned explicitly in this session).

This is the 10th session of the Structure and Interpretation of Computer Programs course (presented by the authors), so it builds on top of a pure lambda-calculus model, with its many advantages of simple substitution etc.  You have to imagine that context for this session, i.e., that until then only a purely functional, lexically scoped language was used/presented.

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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14  7:35 ` tomas
@ 2021-08-14 16:00   ` Eduardo Ochs
  2021-08-14 19:41     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14 20:42     ` tomas
  2021-08-14 19:31   ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 2 replies; 61+ messages in thread
From: Eduardo Ochs @ 2021-08-14 16:00 UTC (permalink / raw)
  To: tomas; +Cc: help-gnu-emacs

On Sat, 14 Aug 2021 at 04:35, <tomas@tuxteam.de> wrote:
>
> Hm. I have the feeling that it'll difficult to appreciate the
> differences between lexical and dynamic bindings whithin such
> short snippets. You don't have much room to build up a lexical
> environment worth its salt :-)
>
> The metaphor which, for me, did "click" was: lexical binding is
> a binding along "space", dynamic binding along "time".


Hi Tomas,

I forgot to explain some things about the style of that tutorial... I
thought that they would be obvious, but they're not.

The two programming languages that I use more are Elisp and Lua, and
Lua only has lexical binding... so I know how lexical binding works,
how to use it, and what are its advantages, but its exact semantics in
Lua only became clear to me when I learned 1) how to inspect all the
"local variables" of a running Lua function - in Lua this includes the
arguments that the function received, and 2) how some local variables
are "captured" to become upvales. This is explained in pages 8 and 9
here:

  https://web.tecgraf.puc-rio.br/~lhf/ftp/doc/jucs05.pdf#page=9

My main intent with eev since the beginning (in the mid-90s) has
always been to create my own "executable notes" and share them, and to
make other people create and share their executable notes too... there
seemed to be some kind of taboo against that at that time: people
shared textual explanations happily but hesitated an almost infinite
number of times before sharing runnable snippets, and I was tired of
spending hours every time undoing their translations from snippets to
textual explanations to reconstruct the runnable snippets that they
didn't want to share...

Two days ago someone on IRC told me that the documentation of Common
Lisp has great explanations of how lexical bindings works on CL, and
that lots of it applied to lexical binding in Emacs too. I forgot to
ask for links - when I get them I will add them to my tutorial,
probably just preceding them by a "See:", because I am trying to keep
my own textual explanations very short.

This page

  http://www.gnu.org/software/emacs/manual/html_node/elisp/Closures.html
  (find-elnode "Closures")

says:

  However, the fact that the internal structure of a closure is
  exposed to the rest of the Lisp world is considered an internal
  implementation detail. For this reason, we recommend against
  directly examining or altering the structure of closure objects.

but for me, and for many people that I know, the easiest way to
understand a specification that can be implemented in many ways is to
study the specification AND one implementation of it. Snippets that
show the "internal implementation details" of the current
implementation of lexical binding in Emacs are hard to find, so I'm
writing them myself - and asking for help. Eev has several kinds of
hyperlinks to source code, like this one,

  ;; (find-efunction 'defvar "declared_special")

that finds the definition of defvar - a DEFUN ("defvar", ...) - in the
C source of Emacs and searches for string "declared_special" in it,
and I am using them in my notes and tutorials to point the primary
source of information about the implementation details - the source
code! - instead of writing my own textual explanations.

So, that's why I was so happy when I found the getter/setter example
that is here:

  http://angg.twu.net/eev-intros/find-lexical-intro.html#3
  (find-lexical-intro "3. `get/set'")

                    https://0x0.st/-JRW.bin
  (find-wget-elisp "https://0x0.st/-JRW.bin")

It has some code that was quite mysterious to me until a few days ago
- the (defun get/set0 ...), that buils two closures that share the
same lexical environment - and it shows how that code gets translated
to lower-level elisp code that I could understand.

  Cheers,
    Eduardo Ochs
    http://angg.twu.net/#eev
    http://angg.twu.net/eev-intros/find-elisp-intro.html
    http://angg.twu.net/eev-intros/find-lexical-intro.html



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

* Re: [External] : Lexical vs. dynamic: small examples?
  2021-08-14 13:35 ` [External] : " Drew Adams
@ 2021-08-14 16:15   ` Eduardo Ochs
  0 siblings, 0 replies; 61+ messages in thread
From: Eduardo Ochs @ 2021-08-14 16:15 UTC (permalink / raw)
  To: Drew Adams; +Cc: help-gnu-emacs

On Sat, 14 Aug 2021 at 10:36, Drew Adams <drew.adams@oracle.com> wrote:
>
> The advantages of lexical binding are easy to find, and all of them
> are true advantages, for both programming and program analysis. The
> advantages of dynamic binding are not so easy to find, but they're
> quite important to an environment such as that of Emacs.
>
> RMS gave good arguments _for Emacs_ (and similar, user-programmer
> environments) to support dynamic binding, here:


Hi Drew!
Fantastic! Thanks! =)

By the way, here's a package that installs SICP converted to info
format, for those (not Drew!) who don't know that this exists...

  http://melpa.org/#/sicp
  https://github.com/webframp/sicp-info

Cheers =),
  Eduardo Ochs
  http://angg.twu.net/#eev



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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14  3:34 Lexical vs. dynamic: small examples? Eduardo Ochs
                   ` (2 preceding siblings ...)
  2021-08-14 13:35 ` [External] : " Drew Adams
@ 2021-08-14 19:00 ` Gregory Heytings
  2021-08-14 20:16   ` Emanuel Berg via Users list for the GNU Emacs text editor
                     ` (2 more replies)
  3 siblings, 3 replies; 61+ messages in thread
From: Gregory Heytings @ 2021-08-14 19:00 UTC (permalink / raw)
  To: Eduardo Ochs; +Cc: help-gnu-emacs


>
> I am trying to write a section on lexical vs. dynamic binding for a 
> tutorial on Emacs Lisp, and I am looking for very short demos that show 
> how things work differently in dynamic and in lexical binding...
>

Suppose you write a function to remove unnecessary whitespaces at the end 
of lines:

(defun delete-whitespace-at-eol ()
   (interactive)
   (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))))

Now if you M-x trim-whitespaces-at-eol in a read-only buffer, you'll get a 
"Buffer is read-only" error.  Suppose you want to make that function work 
for read-only buffers.  If Emacs Lisp only had lexical binding, you would 
have to alter the global "buffer-read-only" variable, that is, to do 
something like:

(defvar saved-buffer-read-only)
(defun delete-whitespace-at-eol ()
   (interactive)
   (setq saved-buffer-read-only buffer-read-only)
   (setq buffer-read-only nil)
   (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))
   (setq buffer-read-only saved-buffer-read-only))

This becomes much simpler with dynamic binding:

(defun delete-whitespace-at-eol ()
   (interactive)
   (let ((buffer-read-only nil))
     (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))))

The "let ((buffer-read-only nil))" creates a new "buffer-read-only" 
variable and sets it to nil.  When "replace-regexp", and the functions 
called by "replace-regexp", consult the value of the "buffer-read-only" 
variable, they will see the "buffer-read-only" variable created in 
"delete-whitespace-at-eol", and its value "nil", instead of the global 
"buffer-read-only" variable.

It is easier to think that "let ((buffer-read-only nil))" creates a new 
"buffer-read-only" variable, but technically this is not correct.  What 
happens instead is that the old value of "buffer-read-only" is saved, the 
value of "buffer-read-only" is updated, and upon returning from the "let", 
the saved value is restored.



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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14  7:35 ` tomas
  2021-08-14 16:00   ` Eduardo Ochs
@ 2021-08-14 19:31   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14 20:31     ` tomas
  1 sibling, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 19:31 UTC (permalink / raw)
  To: help-gnu-emacs

tomas wrote:

> The metaphor which, for me, did "click" was: lexical binding
> is a binding along "space", dynamic binding along "time".

Okay, but as for dynamic, isn't that the definition rather
than a metaphor?

"Lexical" refers to how the code is written - in particular
where a variable is defined and how it is scoped in the
source, when the source is compiled.

Lexical binding (or scope) could just as well be called
static scoping.

Dynamic or lexical binding answers the question how a variable
is looked up when it is referenced, i.e. called by its name.

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 16:00   ` Eduardo Ochs
@ 2021-08-14 19:41     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14 20:42     ` tomas
  1 sibling, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 19:41 UTC (permalink / raw)
  To: help-gnu-emacs

Eduardo Ochs wrote:

> The two programming languages that I use more are Elisp and
> Lua, and Lua

They (the Brazilians) did Lua (moon in Portugese) because
Python wasn't around, and Lisp was too cryptic with its
"unfriendly" syntax :) [1]

> the easiest way to understand a specification that can be
> implemented in many ways is to study the specification AND
> one implementation of it.

ikr?

> details [...] of the current implementation of lexical
> binding in Emacs are hard to find, so I'm writing them
> myself

Okay, but how many situations are they?

You already have the example with `let', what other situations
can you think of?

One example per situation should be enough and do them as
short as possible. Because there aren't that many, are there?

[1] https://en.wikipedia.org/wiki/Lua_(programming_language)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 19:00 ` Gregory Heytings
@ 2021-08-14 20:16   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14 20:23     ` Gregory Heytings
  2021-08-14 20:41   ` tomas
  2021-08-15  0:29   ` [External] : " Drew Adams
  2 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 20:16 UTC (permalink / raw)
  To: help-gnu-emacs

Gregory Heytings wrote:

> (defun delete-whitespace-at-eol ()
>   (interactive)
>   (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))))

OK, that's an example, but let's mention there is
`delete-trailing-whitespace'.

(defun untab-all ()
  (unless (member major-mode '(makefile-gmake-mode
                               makefile-mode) ) ; exceptions
    (untabify (point-min) (point-max)))
  nil) ; "did not write buffer to disk"

(defun before-save-hook-f ()
  (untab-all)
  (delete-trailing-whitespace) )
(add-hook 'before-save-hook #'before-save-hook-f)

> Now if you M-x trim-whitespaces-at-eol in a read-only
> buffer, you'll get a "Buffer is read-only" error.
> Suppose you want to make that function work for read-only
> buffers. If Emacs Lisp only had lexical binding, you would
> have to alter the global "buffer-read-only" variable, that
> is, to do something like:
>
> (defvar saved-buffer-read-only)
> (defun delete-whitespace-at-eol ()
>   (interactive)
>   (setq saved-buffer-read-only buffer-read-only)
>   (setq buffer-read-only nil)
>   (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))
>   (setq buffer-read-only saved-buffer-read-only))

OK, but you don't need to store the old value in a global
variable...

> This becomes much simpler with dynamic binding:
>
> (defun delete-whitespace-at-eol ()
>   (interactive)
>   (let ((buffer-read-only nil))
>     (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))))

Can't we have two `let', the old let that is lexical/static
and another let that is dynamic, only we call it something
else, and then everyone can use whatever they like and it is
always clear from the code which it is and we can even have
both from the same file, with no need to say it's this way or
the other?

It doesn't work like that? Why not?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 20:16   ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-14 20:23     ` Gregory Heytings
  2021-08-14 21:05       ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Gregory Heytings @ 2021-08-14 20:23 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: help-gnu-emacs


>> (defvar saved-buffer-read-only)
>> (defun delete-whitespace-at-eol ()
>>   (interactive)
>>   (setq saved-buffer-read-only buffer-read-only)
>>   (setq buffer-read-only nil)
>>   (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))
>>   (setq buffer-read-only saved-buffer-read-only))
>
> OK, but you don't need to store the old value in a global variable...
>

Of course you do, you need to restore the original value, which could be 
either t or nil.  But indeed TIMTOWTDI: for this specific example, another 
way to do it would be to introduce a conditional.  In general however 
variables can hold more than two values, so for didactic purposes the 
above is much clearer.



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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 19:31   ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-14 20:31     ` tomas
  2021-08-14 21:26       ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: tomas @ 2021-08-14 20:31 UTC (permalink / raw)
  To: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 607 bytes --]

On Sat, Aug 14, 2021 at 09:31:20PM +0200, Emanuel Berg via Users list for the GNU Emacs text editor wrote:
> tomas wrote:
> 
> > The metaphor which, for me, did "click" was: lexical binding
> > is a binding along "space", dynamic binding along "time".
> 
> Okay, but as for dynamic, isn't that the definition rather
> than a metaphor?

If you take it too seriously, you end up with a strange time,
which goes back and forth and branches. Calls stacks like to
do funny things :-/

If you add nonlocal exits (exceptions, setjmp/longjmp, continuations),
you are in hot water ;-)

Cheers
 - t

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 19:00 ` Gregory Heytings
  2021-08-14 20:16   ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-14 20:41   ` tomas
  2021-08-15  0:29   ` [External] : " Drew Adams
  2 siblings, 0 replies; 61+ messages in thread
From: tomas @ 2021-08-14 20:41 UTC (permalink / raw)
  To: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 1234 bytes --]

On Sat, Aug 14, 2021 at 07:00:29PM +0000, Gregory Heytings wrote:
> 
> >
> >I am trying to write a section on lexical vs. dynamic binding for
> >a tutorial on Emacs Lisp, and I am looking for very short demos
> >that show how things work differently in dynamic and in lexical
> >binding...
> >
> 
> Suppose you write a function to remove unnecessary whitespaces at
> the end of lines:
> 
> (defun delete-whitespace-at-eol ()
>   (interactive)
>   (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))))

This is a good example. There are other ones. Basically, whenever
you want some "dynamic state" to be in effect for the whole
"call tree" below you. Typically those are well-known things
with an agreed-upon purpose.

My favourite example is some kind of "debug setting" (a function,
a value, whatever).

There's a reason why the convention in CL is to have those
variable named with asterisks around, like *this*.

(I had many arguments whithin Perl. With the arrival of lexical
variables, there was a fraction which tried to convince people
to /never/ use dynamic variables, and I tried to explain that,
yes, use sparingly, but sometimes they can make code clearer.

Cheers
 - t

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 16:00   ` Eduardo Ochs
  2021-08-14 19:41     ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-14 20:42     ` tomas
  1 sibling, 0 replies; 61+ messages in thread
From: tomas @ 2021-08-14 20:42 UTC (permalink / raw)
  To: Eduardo Ochs; +Cc: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 715 bytes --]

On Sat, Aug 14, 2021 at 01:00:34PM -0300, Eduardo Ochs wrote:
> On Sat, 14 Aug 2021 at 04:35, <tomas@tuxteam.de> wrote:
> >
> > Hm. I have the feeling that it'll difficult to appreciate the
> > differences between lexical and dynamic bindings whithin such
> > short snippets. You don't have much room to build up a lexical
> > environment worth its salt :-)
> >
> > The metaphor which, for me, did "click" was: lexical binding is
> > a binding along "space", dynamic binding along "time".
> 
> 
> Hi Tomas,
> 
> I forgot to explain some things about the style of that tutorial... I
> thought that they would be obvious, but they're not.

Hm. I'll have to wrap my head around that.

Cheers
 - t

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 20:23     ` Gregory Heytings
@ 2021-08-14 21:05       ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14 21:13         ` tomas
  0 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:05 UTC (permalink / raw)
  To: help-gnu-emacs

Gregory Heytings wrote:

>>> (defvar saved-buffer-read-only)
>>> (defun delete-whitespace-at-eol ()
>>>   (interactive)
>>>   (setq saved-buffer-read-only buffer-read-only)
>>>   (setq buffer-read-only nil)
>>>   (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))
>>>   (setq buffer-read-only saved-buffer-read-only))
>>
>> OK, but you don't need to store the old value in a global variable...
>>
> Of course you do, you need to restore the original value [...]

But there is still no need to use a global variable...

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 21:05       ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-14 21:13         ` tomas
  2021-08-14 21:28           ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: tomas @ 2021-08-14 21:13 UTC (permalink / raw)
  To: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 827 bytes --]

On Sat, Aug 14, 2021 at 11:05:53PM +0200, Emanuel Berg via Users list for the GNU Emacs text editor wrote:
> Gregory Heytings wrote:
> 
> >>> (defvar saved-buffer-read-only)
> >>> (defun delete-whitespace-at-eol ()
> >>>   (interactive)
> >>>   (setq saved-buffer-read-only buffer-read-only)
> >>>   (setq buffer-read-only nil)
> >>>   (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))
> >>>   (setq buffer-read-only saved-buffer-read-only))
> >>
> >> OK, but you don't need to store the old value in a global variable...
> >>
> > Of course you do, you need to restore the original value [...]
> 
> But there is still no need to use a global variable...

That's not the point. You perhaps don't want to trample on one. The
let-binding helps you with that. In both cases.

Cheers
 - t

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 20:31     ` tomas
@ 2021-08-14 21:26       ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14 21:29         ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:26 UTC (permalink / raw)
  To: help-gnu-emacs

tomas wrote:

> If you add nonlocal exits (exceptions, setjmp/longjmp,
> continuations), you are in hot water ;-)

Let's see, an exception is an exception...

setjmp/longjmp are C functions to save state and then
restore/resume execution at a specific location after
an error.
            
A continuation - the functional equivalent of the GOTO
statement <https://en.wikipedia.org/wiki/Continuation> - is
used in continuation-passing style computing, CPS, where an
explicit continuation function is sent to a function and
that gets called with the value instead of returning it.
So if f(a, f') = f'(f(a)) then f' is the continuation?

"Nonlocal exits unbind all variable bindings made by the
constructs being exited."
<https://www.gnu.org/software/emacs/manual/html_node/elisp/Nonlocal-Exits.html>

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 21:13         ` tomas
@ 2021-08-14 21:28           ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:28 UTC (permalink / raw)
  To: help-gnu-emacs

tomas wrote:

>> But there is still no need to use a global variable...
>
> That's not the point.

It is my point.

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Lexical vs. dynamic: small examples?
  2021-08-14 21:26       ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-14 21:29         ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:29 UTC (permalink / raw)
  To: help-gnu-emacs

> <https://www.gnu.org/software/emacs/manual/html_node/elisp/Nonlocal-Exits.html>

That page doesn't have a title BTW.

-- 
underground experts united
https://dataswamp.org/~incal




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

* RE: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-14 19:00 ` Gregory Heytings
  2021-08-14 20:16   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-14 20:41   ` tomas
@ 2021-08-15  0:29   ` Drew Adams
  2021-08-15  0:52     ` Emanuel Berg via Users list for the GNU Emacs text editor
                       ` (2 more replies)
  2 siblings, 3 replies; 61+ messages in thread
From: Drew Adams @ 2021-08-15  0:29 UTC (permalink / raw)
  To: Gregory Heytings, Eduardo Ochs; +Cc: help-gnu-emacs

> Now if you M-x trim-whitespaces-at-eol in a read-only buffer, you'll get a
> "Buffer is read-only" error.  Suppose you want to make that function work
> for read-only buffers.  If Emacs Lisp only had lexical binding, you would
> have to alter the global "buffer-read-only" variable, that is, to do
> something like:
> 
> (defvar saved-buffer-read-only)
> (defun delete-whitespace-at-eol ()
>    (interactive)
>    (setq saved-buffer-read-only buffer-read-only)
>    (setq buffer-read-only nil)
>    ...
>    (setq buffer-read-only saved-buffer-read-only))

`buffer-read-only' is a dynamically scoped, set, and
bound variable.  (It's also buffer-local.)  What you did
there was change the value for the dynamic extent of
the function call.  It's not defined by the scope of the
function definition.

All variables defined using defvar and defcustom are
dynamically scoped.  Same with top-level `setq', i.e.,
variables that are not explicitly defined in any
scope, other that the top level.

Same with frame parameters, faces, etc. - all essentially
dynamically-scoped variables.  Their values have
indefinite scope and dynamic extent.

"Dynamic scope" is a misnomer, BTW; it means only that -
no particular scope and dynamic extent.  See the very
good explanation in CLTL:

https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html#SECTION00700000000000000000

Common Lisp calls such variables "special" variables.

Wrt usefulness: if you've ever used user options or
defvar variables, or frame parameters, or faces,...
then you recognize their utility.  Now try to imagine
Emacs, as a flexible, dynamic user-interaction
environment/lab _without_ dynamic binding...

> This becomes much simpler with dynamic binding:
> (defun delete-whitespace-at-eol ()
>    (interactive)
>    (let ((buffer-read-only nil))
>      ...))

That's just a simpler way to do the same thing.
In both cases, it is the globally visible
(buffer-local) variable whose value is changed
for the _duration_ of the function call (unless
something else changes it in the meantime).

`let' binds the global variable (which, again,
happens to be buffer-local).  That's how `let'
behaves with a "special" var.  Otherwise, i.e.,
for vars that are not "special", `let' provides
a lexical binding - the scope ends where the
`let' ends, lexically.

Dynamic scope/binding means variable name capture
is always an inherent, potential problem.

From the CLTL chapter on Scope and Extent cited
above, remember this:

"A reference by name to an entity with dynamic extent
 will always refer to the entity of that name that
 has been most recently established that has not yet
 been disestablished."



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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15  0:29   ` [External] : " Drew Adams
@ 2021-08-15  0:52     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15  1:04     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15  1:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15  0:52 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

> `let' binds the global variable (which, again,
> happens to be buffer-local).  That's how `let'
> behaves with a "special" var.  Otherwise, i.e.,
> for vars that are not "special", `let' provides
> a lexical binding - the scope ends where the
> `let' ends, lexically.

Can't we have a "let-special" that makes its own variables
special within its scope?

Then one could use let-special for dynamic scope (which now
would in fact be scoped!) and `let' would always be lexical
and one would never have to use ;;; -*- lexical-binding: t -*-

?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15  0:29   ` [External] : " Drew Adams
  2021-08-15  0:52     ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15  1:04     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15  1:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15  1:04 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

> Wrt usefulness: if you've ever used user options or defvar
> variables, or frame parameters, or faces,... then you
> recognize their utility. Now try to imagine Emacs, as
> a flexible, dynamic user-interaction environment/lab
> _without_ dynamic binding...

Options as global variables - useful.

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15  0:29   ` [External] : " Drew Adams
  2021-08-15  0:52     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15  1:04     ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15  1:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15  4:44       ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 15:42       ` FW: " Drew Adams
  2 siblings, 2 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15  1:18 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

> "Dynamic scope" is a misnomer, BTW; it means only that - no
> particular scope and dynamic extent [...] `let' provides
> a lexical binding - the scope ends where the `let'
> ends, lexically.

But with `let' doesn't the scope end where the let ends even
for dynamic binding?

And one can think of global variables as having the whole
program as their scope.

If this is only about let "let's" have two lets, one
"let-stay" and one "let-follow".

If it isn't only about let, what is it about more?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15  1:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15  4:44       ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15  5:02         ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 15:49         ` Drew Adams
  2021-08-15 15:42       ` FW: " Drew Adams
  1 sibling, 2 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15  4:44 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote, somewhere else:

  > If this is only about let "let's" have two lets, one
  > "let-stay" and one "let-follow".

  `let' is not the only construct that can define a
  scope.  For example, a function definition (a `defun'
  or a lambda) defines the scope of its formal
  parameters - they're lexically scoped.

Yes, and what happens is, the formal parameters are check
first, only after that are global variables checked!

But that is completely normal and 100% expected. If that is
"lexical scope", how would one do it in another way? (OK, it
_is_ lexical binding for the arguments and dynamic for the
globals but has this any practical implications?)

No, the only thing I've seen so far - maybe the only thing it
is? - is `let', and that acts in two ways, the lexical way if
one puts

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

first thing in the source file, and if one doesn't, it acts in
the dynamic way.

So I wonder again, why not just have two let, one "let-stay"
(the variables stay so has to be used and/or passed
explicitely), and "let-follow" (the variables follow
everywhere the code goes within the let form).

Then one could drop this whole discussion because everything
would work as expected and everyone could use whatever they
wanted and instead of explaining some scope vs another in
terms of theory one would have one docstring for "let-stay"
and one for "let-follow" and these would also not confuse
anything by engaging in a theoretical discussion but just
describe what the function does and what its purpose is.

?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15  4:44       ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15  5:02         ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 15:49         ` Drew Adams
  1 sibling, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15  5:02 UTC (permalink / raw)
  To: help-gnu-emacs

> So I wonder again, why not just have two let, one "let-stay"
> (the variables stay so has to be used and/or passed
> explicitely), and "let-follow" (the variables follow
> everywhere the code goes within the let form).

Even better, let `let' be the lexical let.

Then the old dynamic let will be called "with-variables-as".

So this

  (let ((x  1)
        (y  2)
        (z -1) )
    (draw-grid x y z) )

would be the equivalent of

  (with-variables-as ((x  1)
                      (y  2)
                      (z -1) )
    (draw-grid) )

-- 
underground experts united
https://dataswamp.org/~incal




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

* FW: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15  1:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15  4:44       ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15 15:42       ` Drew Adams
  1 sibling, 0 replies; 61+ messages in thread
From: Drew Adams @ 2021-08-15 15:42 UTC (permalink / raw)
  To: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'; +Cc: Emanuel Berg

[-- Attachment #1: Type: text/plain, Size: 1236 bytes --]

[Was bitten by Reply All not including the list again...]

> > "Dynamic scope" is a misnomer, BTW; it means only that - no
> > particular scope and dynamic extent [...] `let' provides
> > a lexical binding - the scope ends where the `let'
> > ends, lexically.
> 
> But with `let' doesn't the scope end where the let ends even
> for dynamic binding?

No.  Dynamic bindings have indefinite scope - that is,
no particular scope.

The binding has dynamic _extent_ - it lasts _as long as_
(time) the code in the `let' body is executing (which
can include nonlocal exits by that code (or code called
by that code) - e.g. `throw').

For such a variable the `let' does not define a scope;
it only determines which code realizes the binding's
duration.

Scope and extent (duration for referencing) are two
different things.

See the CLTL chapter I pointed to.

> If it isn't only about let, what is it about more?

`let' is not the only construct that can define a
scope.  For example, a function definition (a `defun'
or a lambda) defines the scope of its formal
parameters - they're lexically scoped.

Again, I recommend that CLTL chapter.  It's short, and
it explains things well, including with examples.

[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 13542 bytes --]

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

* RE: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15  4:44       ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15  5:02         ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15 15:49         ` Drew Adams
  2021-08-15 18:49           ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 1 reply; 61+ messages in thread
From: Drew Adams @ 2021-08-15 15:49 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'

[-- Attachment #1: Type: text/plain, Size: 1231 bytes --]

> (OK, it _is_ lexical binding for the arguments and dynamic
> for the globals but has this any practical implications?)

As I said, `let' (in both Elisp and Common Lisp) binds
"special" vars dynamically and non-special vars lexically.
There's nothing else to it.

> No, the only thing I've seen so far - maybe the only thing it
> is? - is `let', and that acts in two ways, the lexical way if
> one puts
> 
> ;;; -*- lexical-binding: t -*-
> 
> first thing in the source file, and if one doesn't, it acts in
> the dynamic way.

See above.  In Elisp we have var `lexical-binding', and
lexical binding is not not turned on by default.  With
Common Lisp there's no such variable, and the effect is
as if `lexical-binding' were always non-nil.  (There are
other differences, wrt how/where you can declare vars to
be "special".)

> So I wonder again, why not just have two let, one "let-stay"
> (the variables stay so has to be used and/or passed
> explicitely), and "let-follow" (the variables follow
> everywhere the code goes within the let form).

Sorry, I don't follow you.  It's not clear to me what
you're proposing or (more importantly) what problem
you think you have with the designed behavior.

[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 13878 bytes --]

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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 15:49         ` Drew Adams
@ 2021-08-15 18:49           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 21:55             ` Stefan Monnier via Users list for the GNU Emacs text editor
                               ` (2 more replies)
  0 siblings, 3 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 18:49 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

>> So I wonder again, why not just have two let, one
>> "let-stay" (the variables stay so has to be used and/or
>> passed explicitely), and "let-follow" (the variables follow
>> everywhere the code goes within the let form).
>
> Sorry, I don't follow you. It's not clear to me what you're
> proposing or (more importantly) what problem you think you
> have with the designed behavior.

`let' does two different things, that is confusing, and it is
usually explained with theory - and the terms are confusing as
well - and to set what usage one gets one has to mess with
a variable - what kind of style is that? Just imagine, instead
of `+', `-', etc we would have just one function, "do-math"
which would look for for the value of "operator" to determine
what to do...

So the proposal/question is, instead one could have `let'
_always_ be lexical, and one "with-variables-as" which would
be what is now called "dynamic binding" with let.

"Dynamic" is something that changes over time, but TBH I don't
really see the static/dynamic aspect or difference here?
But OK, for the sake of the discussion, let's call them "letl"
(the lexical one) and "letd" (the dynamic one).

If one did it like that, for practical purposes, the whole
lexical/static vs special/dynamic binding or scope (and
extent) could be dropped, one would just write one docstring
for "letl" and one for "letd"!

(Let's not bring in the issue of nonlocal exits like
exceptions and continuations because if they are indeed
"exceptions" they can be whatever.)

OK, that's let, you also mention global variables, they are
always special/dynamic. However I don't see how that could or
should be done in any other way, how can they be lexical?
If they can't, that issue (the issue of global variables) can
be cancelled out from the discussion as well.

You also mention functions (`defun's) which are lexical in
terms of the their formal parameters (= arguments, only
theoretically, not applied). Because the whole idea with
functions is to modularize and encapsulate I find the concept
of function dynamic scope a bit bizarre, so in a way this
issue (defuns) could be cancelled out as well. But sure, if
someone want them to be dynamic, then why don't we do the same
as I proposed for `let' (which was `let' = "letl", lexical;
and "letd", dynamic), i.e. we would have

  `defun' = "defunl", lexical; and
  "defund", dynamic

?

Then no one would have to mess with `lexical-binding', in any
way (especially not that commented way that reminds me of
a C preprocessor or something), one would just use whatever
one wanted and to explain it to newcomers one would just refer
to the docstrings, no need for CS theory or anything (not
saying it should be forbidden or anything) but for practical
purposes it wouldn't be needed. Everyone would see in the code
- ah, here it is used like that, there it is used the
other way.

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 18:49           ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15 21:55             ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-15 22:04               ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 21:57             ` Drew Adams
  2021-08-15 22:02             ` Lars Ingebrigtsen
  2 siblings, 1 reply; 61+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 21:55 UTC (permalink / raw)
  To: help-gnu-emacs

> "Dynamic" is something that changes over time, but TBH I don't
> really see the static/dynamic aspect or difference here?

This use of the term is the same as used in code analysis.
"static" refers to the fact that you can find the definition
corresponding to a particular use by just looking at the code without
having "run" it.

In contrast "dynamic" refers to the fact that in order to find which
definition corresponds to a particular use can only be done you need to
run the code (or simulate a run, typically in your head).

It can also be considered from the following point of view: with
lexical/static scoping, a given variable reference will always refer to
the same definition point, i.e. the "use-to-def" doesn't change and is
hence "static", whereas with dynamic scoping, a given variable reference
can refer to various definitions at different moments of a program
execution, i.e. the "use-to-def" can change and is hence dynamic.


        Stefan




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

* RE: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 18:49           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 21:55             ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2021-08-15 21:57             ` Drew Adams
  2021-08-15 22:20               ` Emanuel Berg via Users list for the GNU Emacs text editor
                                 ` (2 more replies)
  2021-08-15 22:02             ` Lars Ingebrigtsen
  2 siblings, 3 replies; 61+ messages in thread
From: Drew Adams @ 2021-08-15 21:57 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'

[-- Attachment #1: Type: text/plain, Size: 5973 bytes --]

> So the proposal/question is, instead one could have `let'
> _always_ be lexical, and one "with-variables-as" which would
> be what is now called "dynamic binding" with let.

You might want to send your proposal/question along
via `M-x report-emacs-bug'.  That's the best way to
request enhancements, new features, and bug fixes.

You might also want to consider that Common Lisp,
designed by pretty much all of the wizards of Lisp
at the time, does what Emacs Lisp does.

With the exception that Emacs is not yet there all
the way: we have variable `lexical-binding', which,
yes, is a kludge indicating that we're straddling
two chairs.

IMHO, there is no confusion in the Common Lisp
world/community about `let' (or other constructs)
wrt lexical vs dynamic binding of a variable.

I think there's confusion in the Emacs world because
(1) Emacs long had only dynamic binding, (2) dynamic
binding is what Emacs users (but maybe less so Elisp
programmers) expect and make good use of when it comes
their own binding/setting of variables (e.g. options),
and (3) as noted above, Emacs is "entre deux chaises".

> OK, that's let, you also mention global variables, they are
> always special/dynamic. However I don't see how that could or
> should be done in any other way, how can they be lexical?

Many/most languages have pretty much only lexical
binding.  But yes, an exception is made for top-level
definitions, in the sense that you can dynamically
issue another define/defun/defvar for the same thing.

There's _no_ scope for such definitions (though each
defines a scope _within_ it, for other bindings).
Each name defined with those constructs has indefinite
scope and dynamic extent (duration).

> If they can't, that issue (the issue of global variables)
> can be cancelled out from the discussion as well.

There's no "issue".  I mentioned defvar, defcustom,
defconst, defface, frame parameters, etc. as examples
of dynamically bound things that Emacs users are used
to.  The point was that dynamic binding is not exotic
or foreign for Emacs users.  But like Monsieur Jourdain,
they might well not be aware that they've been speaking
such prose all their Emacs lives.

The question was raised as to the usefulness of dynamic
binding for Emacs users.  I pointed to RMS's (excellent)
reasons for supporting it, and to the (dynamic) behavior
of those constructs, as what you (I, anyway) really want
in an interactive environment such as Emacs.

You can see that, when it comes to interaction with such
an environment, pretty much all languages have a dynamic
top level.  You can _imagine_ no defuns etc. but only a
big let, but you'll soon see that interacting with that
could be cumbersome.

Beyond such top-level dynamic binding of names, the real
advantages that RMS cites are what are important, and
they are more controversial.  Disparagement of "monkey
patching" is common.

And beyond the question of dynamic/lexical binding, there
are plenty of other "dirty" things to disparage in Lisp.

You can start with side effects.  And `quote' (which on
its own is enough to destroy referential transparency).

And you can continue with applicative-order, instead of
normal-order, evaluation.  That can lead to incorrect
results and to unnecessary infinite computation.

There are Lisps and other, more declarative, more purely
functional or logic languages, that do away with this or
that dirtiness.  And they're wonderful, and safe, and
more amenable to proof, and...  But maybe not so 
wonderful for an editing environment.

(You can even program in "pure", "academic" Lisp -
essentially lambda calculus with some built-in data
types.  That's used mainly for papers and proofs.)

> You also mention functions (`defun's) which are lexical in
> terms of the their formal parameters (= arguments, only
> theoretically, not applied). 

No idea what you mean by only theoretically.  A function
definition. whether by defun or as a lambda, is a binding
construct, just like let is, or an integral or sigma
expression is, or a logic expression with quantification
is.  You can define `forall' using lambda, just as you
can define let using lambda.

They're all abstractions - their purpose is to abstract.

(https://www.youtube.com/watch?v=-J_xL4IGhJA, minute 29:00)

As such, they all introduce variables and variable binding.

(There's no _need_ for variables actually.  Combinatory
logic is equivalent to lambda calculus, and it involves
no variables.  But for mere mortals, variables give us
some peace of mind and a map of the territory.)

Actual arguments to functions are bound lexically in Lisp
(modulo... depending on the approach).

There's a difference between how a function's parameters
are handled (which is lexically) and how the function
name itself is handled (dynamically, for a defun).

> Because the whole idea with functions is to modularize
> and encapsulate I find the concept of function dynamic
> scope a bit bizarre

Do you want to be able to redefine a function easily?

(defun foo (a) ...)
;; later...
(defun foo (a b c) ...)

> why don't we do the same as I proposed for `let'
> (which was `let' = "letl", lexical;
> and "letd", dynamic), i.e. we would have
> 
>   `defun' = "defunl", lexical; and
>   "defund", dynamic

See CLTL, flet and labels:

https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node83.html

defun is convenient.  Even non-Emacsing lispers want
the convenience of a supple interactive environment.

(You have a similar situation with setq as with let,
BTW. It can assign to a lexical variable or a dynamic
one.)

> Then no one would have to mess with `lexical-binding',

Having to mess with the variable `lexical-binding' is
orthogonal.  As mentioned, that's only an Emacs thing,
and it's there only because we're between two chairs
at the moment (it's been a long moment).

[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 17094 bytes --]

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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 18:49           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 21:55             ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-15 21:57             ` Drew Adams
@ 2021-08-15 22:02             ` Lars Ingebrigtsen
  2021-08-15 22:22               ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 22:44               ` Emanuel Berg via Users list for the GNU Emacs text editor
  2 siblings, 2 replies; 61+ messages in thread
From: Lars Ingebrigtsen @ 2021-08-15 22:02 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg via Users list for the GNU Emacs text editor
<help-gnu-emacs@gnu.org> writes:

> So the proposal/question is, instead one could have `let'
> _always_ be lexical, and one "with-variables-as" which would
> be what is now called "dynamic binding" with let.

These are `lexical-let' and `dlet' (in Emacs 28).

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no



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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 21:55             ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2021-08-15 22:04               ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:04 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

>> "Dynamic" is something that changes over time, but TBH
>> I don't really see the static/dynamic aspect or
>> difference here?
>
> This use of the term is the same as used in code analysis.
> "static" refers to the fact that you can find the definition
> corresponding to a particular use by just looking at the
> code without having "run" it.
>
> In contrast "dynamic" refers to the fact that in order to
> find which definition corresponds to a particular use can
> only be done you need to run the code (or simulate a run,
> typically in your head).
>
> It can also be considered from the following point of view:
> with lexical/static scoping, a given variable reference will
> always refer to the same definition point, i.e.
> the "use-to-def" doesn't change and is hence "static",
> whereas with dynamic scoping, a given variable reference can
> refer to various definitions at different moments of
> a program execution, i.e. the "use-to-def" can change and is
> hence dynamic.

Great, thanks!

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 21:57             ` Drew Adams
@ 2021-08-15 22:20               ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 22:54                 ` Drew Adams
  2021-08-15 23:16               ` Drew Adams
  2021-08-15 23:42               ` Arthur Miller
  2 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:20 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

>> Because the whole idea with functions is to modularize and
>> encapsulate I find the concept of function dynamic scope
>> a bit bizarre
>
> Do you want to be able to redefine a function easily?
>
> (defun foo (a) ...)
> ;; later...
> (defun foo (a b c) ...)

No, they are global, of course!

I meant dynamic with respect to the functional parameters.
I think that would be bizarre but I'm a maximalist in terms of
features so why not.

However then one would call it something else, for example
`defund' (d for "dynamic" and it refers to how the function
would handle the functional parameters, not back on the
function itself).

>> why don't we do the same as I proposed for `let'
>> (which was `let' = "letl", lexical;
>> and "letd", dynamic), i.e. we would have
>> 
>>   `defun' = "defunl", lexical; and
>>   "defund", dynamic
>
> See CLTL, flet and labels:
>
> https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node83.html
>
> defun is convenient.  Even non-Emacsing lispers want
> the convenience of a supple interactive environment.
>
> (You have a similar situation with setq as with let,
> BTW. It can assign to a lexical variable or a dynamic
> one.)

OK, now we got it plain and clear:

1. Remove `lexical-binding'.

2. Duplicate everything that acts differently because of it
   into "func" (the same as "funcl") and "funcd" (funk'd, ha)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 22:02             ` Lars Ingebrigtsen
@ 2021-08-15 22:22               ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 22:44                 ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-15 22:44               ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:22 UTC (permalink / raw)
  To: help-gnu-emacs

Lars Ingebrigtsen wrote:

>> So the proposal/question is, instead one could have `let'
>> _always_ be lexical, and one "with-variables-as" which
>> would be what is now called "dynamic binding" with let.
>
> These are `lexical-let' and `dlet' (in Emacs 28).

Ha! Now you are telling...

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 22:22               ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15 22:44                 ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-21  3:38                   ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 22:44 UTC (permalink / raw)
  To: help-gnu-emacs

Emanuel Berg via Users list for the GNU Emacs text editor [2021-08-16 00:22:43] wrote:
> Lars Ingebrigtsen wrote:
>>> So the proposal/question is, instead one could have `let'
>>> _always_ be lexical, and one "with-variables-as" which
>>> would be what is now called "dynamic binding" with let.
>> These are `lexical-let' and `dlet' (in Emacs 28).
> Ha! Now you are telling...

Note that `lexical-let` is an old thing of the deprecated `cl.el`
library which let you have static scoping let-bindings before
`lexical-binding` existed.

When `lexical-binding` is not enabled it's still currently the only way
I know to get a statically scoped let-binding, but when
`lexical-binding` is enabled you can use:

    (defmacro slet (bindings &rest body)
      (unless lexical-binding
        (error "`slet' requires `lexical-binding' to be enabled"))
      `(funcall
         (lambda ,(mapcar #'car bindings)
           ,@body)
         ,@(mapcar #'cadr bindings)))

instead,


        Stefan




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 22:02             ` Lars Ingebrigtsen
  2021-08-15 22:22               ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15 22:44               ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 22:58                 ` Stefan Monnier via Users list for the GNU Emacs text editor
  1 sibling, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:44 UTC (permalink / raw)
  To: help-gnu-emacs

Lars Ingebrigtsen wrote:

> These are `lexical-let' and `dlet'

Can't we have an official alias "llet" for `lexical-let'?

  (defalias 'llet  #'lexical-let)
  (defalias 'llet* #'lexical-let*)

It is much faster to type than lexical-let and smaller, also
it would make it consistent with `dlet' and perhaps soften the
psychological transition from `let' :)

Ah... can't wait to remove all the

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

from my code :)

-- 
underground experts united
https://dataswamp.org/~incal




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

* RE: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 22:20               ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15 22:54                 ` Drew Adams
  0 siblings, 0 replies; 61+ messages in thread
From: Drew Adams @ 2021-08-15 22:54 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'

[-- Attachment #1: Type: text/plain, Size: 887 bytes --]

> >> Because the whole idea with functions is to modularize and
> >> encapsulate I find the concept of function dynamic scope
> >> a bit bizarre
> >
> > Do you want to be able to redefine a function easily?
> >
> > (defun foo (a) ...)
> > ;; later...
> > (defun foo (a b c) ...)
> 
> No, they are global, of course!
> 
> I meant dynamic with respect to the functional parameters.
> I think that would be bizarre but I'm a maximalist in terms of
> features so why not.

As I explained, args to a function are bound lexically.

(This is all documented, of course, in both CLTL and the
Elisp manual.)

A defun essentially dynamically binds a lambda to a name,
the function name.  It is the binding of that name that
is dynamic.  A lambda is itself a binding construct, and
its formal parameters are bound to its actual arguments
lexically.

But I repeat myself.

[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 14126 bytes --]

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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 22:44               ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15 22:58                 ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-15 23:13                   ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 22:58 UTC (permalink / raw)
  To: help-gnu-emacs

> Ah... can't wait to remove all the
>
>   ;;; -*- lexical-binding: t -*-
>
> from my code :)

That won't happen before all the files contain the above line, sadly.


        Stefan




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 22:58                 ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2021-08-15 23:13                   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 23:56                     ` Stefan Monnier via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 23:13 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

>> Ah... can't wait to remove all the
>>
>>   ;;; -*- lexical-binding: t -*-
>>
>> from my code :)
>
> That won't happen before all the files contain the above
> line, sadly.

Can't it be done with `lexical-let'?

It seems to work:

;;; this file:
;;;   http://user.it.uu.se/~embe8573/emacs-init/geh-dyn.el
;;;   https://dataswamp.org/~incal/emacs-init/geh-dyn.el

(require 'cl-lib)

(defun *a10 ()
  (* a 2) )

(defun mult ()
  (lexical-let ((a 10))
    (*a10) ))

;; (mult) ; *a10: Symbol’s value as variable is void: a

But sometimes it says (invalid-function (a 10)) - hm ...

-- 
underground experts united
https://dataswamp.org/~incal




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

* RE: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 21:57             ` Drew Adams
  2021-08-15 22:20               ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15 23:16               ` Drew Adams
  2022-01-09  7:08                 ` Jean Louis
  2021-08-15 23:42               ` Arthur Miller
  2 siblings, 1 reply; 61+ messages in thread
From: Drew Adams @ 2021-08-15 23:16 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'

[-- Attachment #1: Type: text/plain, Size: 837 bytes --]

FWIW, I just wrote a tiny library, `dyna-show.el',
that defines minor mode `dyna-show-mode', which
highlights occurrences of "special" (aka dynamically
scoped) variables.

It just uses `special-variable-p', which is limited.

From the attachment, you can see another limitation:
occurrences of a function, e.g. `font-lock-mode',
that has the same name as a dynamic variable are also
highlighted.

If it helps, good; if not, don't use it. ;-)

You can use it together with library `hl-defined.el',
which highlights symbols known to be defined as
Emacs-Lisp functions or variables or both.  (It can
also highlight symbols _not_ known to be defined as
fns or vars.)

https://www.emacswiki.org/emacs/dyna-show.el

https://www.emacswiki.org/emacs/HighlightLispFunctions

https://www.emacswiki.org/emacs/hl-defined.el

[-- Attachment #2: throw-dyna-show.png --]
[-- Type: image/png, Size: 94588 bytes --]

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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 21:57             ` Drew Adams
  2021-08-15 22:20               ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-15 23:16               ` Drew Adams
@ 2021-08-15 23:42               ` Arthur Miller
  2 siblings, 0 replies; 61+ messages in thread
From: Arthur Miller @ 2021-08-15 23:42 UTC (permalink / raw)
  To: Drew Adams
  Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)', Emanuel Berg

Drew Adams <drew.adams@oracle.com> writes:

> You might also want to consider that Common Lisp,
> designed by pretty much all of the wizards of Lisp
> at the time, does what Emacs Lisp does.
>
> With the exception that Emacs is not yet there all
> the way:

I wish Emacs stayed at simpler Lisp, rather than redoing CL, but that is
just my personal opinion.



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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 23:13                   ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-15 23:56                     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-16  0:43                       ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 23:56 UTC (permalink / raw)
  To: help-gnu-emacs

> Can't it be done with `lexical-let'?

`lexical-let` is deprecated (and expands to ugly code, is less efficient
than using `lexical-binding`, and makes debugging harder).

Note that I also consider not using `lexical-binding` as deprecated
(tho this is not yet the official position of Emacs maintainers).


        Stefan




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 23:56                     ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2021-08-16  0:43                       ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-16  0:43 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

>> Can't it be done with `lexical-let'?
>
> `lexical-let` is deprecated (and expands to ugly code, is
> less efficient than using `lexical-binding`, and makes
> debugging harder).

OK, gotcha.

> Note that I also consider not using `lexical-binding` as
> deprecated (tho this is not yet the official position of
> Emacs maintainers).

I know right?

BTW I've realized static vs. dynamic scope are the best terms.
The words are each others opposites but they are also the best
in terms of technology.

Static scope:

  (let ((x 1))                  
    .                        <- that's right! no 
    (when run-time-condition <- matter conditions or
      (take-a-long-detour) ) <- detours it's the
    . )                      <- same scope

Dynamic scope:

    (let ((x 1))                  
    .                        <- oh, no! x's scope now depends
    (when run-time-condition <- on run-time particulars which
      (take-a-long-detour) ) <- determine if it extends or
    . )                      <- not into the detour function

"Lexical" is intuitive with respect to the static scope but it
isn't as intuitive why the dynamic scope _isn't_ "lexical".
One has to think of the above to get there. But if one has to
think of the above, one might just stop at that and call
it dynamic.

"Special" is confusing, especially because global variables
behaves intuitively and dynamic `let' don't - and
they are all special!

The static vs. dynamic position of definition, does that
relate to how this is implemented (a new variable vs. a new
value pushed to the stack?) - but, since it works for the best
terms, i.e. static vs. dynamic scope, the more the merrier :)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 22:44                 ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2021-08-21  3:38                   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-24  2:08                     ` Stefan Monnier via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-21  3:38 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

> When `lexical-binding` is not enabled it's still currently
> the only way I know to get a statically scoped let-binding,
> but when `lexical-binding` is enabled you can use:
>
>     (defmacro slet (bindings &rest body)
>       (unless lexical-binding
>         (error "`slet' requires `lexical-binding' to be enabled"))
>       `(funcall
>          (lambda ,(mapcar #'car bindings)
>            ,@body)
>          ,@(mapcar #'cadr bindings)))

"slet" for statically scoped `let'!

But ... if `lexical-binding' has to be enabled anyway then one
can just use `let' anyway?

Good that there is `letd' tho, now static/lexical scope just
has to be made t by default and we're all slet :)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-21  3:38                   ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-24  2:08                     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-25 23:34                       ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-24  2:08 UTC (permalink / raw)
  To: help-gnu-emacs

> "slet" for statically scoped `let'!
> But ... if `lexical-binding' has to be enabled anyway then one
> can just use `let' anyway?

Not if the var has been declared as dynamically scoped.


        Stefan




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-24  2:08                     ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2021-08-25 23:34                       ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-25 23:40                         ` Emanuel Berg via Users list for the GNU Emacs text editor
                                           ` (2 more replies)
  0 siblings, 3 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-25 23:34 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

>> "slet" for statically scoped `let'! But ... if
>> `lexical-binding' has to be enabled anyway then one can
>> just use `let' anyway?
>
> Not if the var has been declared as dynamically scoped.

You are right! It is the `defvar' that does it!

This means, I've been using `defvar' to shut up the
byte-compiler about variables not known to be defined, and
this has actually made them dynamic?

I wonder if I should remove the defvar and have the
byte-compiler complain all it wants (I thought defvar only
meant one intended to use the variable).

But weren't all globals dynamic, I heard?

So why does it "work" with no defvar, just `setq'?

BTW notice that "slet" produces a warning altho it is `let's
behavior one should be wary of ...

;;; -*- lexical-binding: t -*-
;;;
;;; this file:
;;;   http://user.it.uu.se/~embe8573/emacs-init/geh.el
;;;   https://dataswamp.org/~incal/emacs-init/geh.el

(defmacro slet (bindings &rest body)
  (unless lexical-binding
    (error "`slet' requires `lexical-binding' to be enabled") )
  `(funcall
    (lambda ,(mapcar #'car bindings)
      ,@body)
    ,@(mapcar #'cadr bindings) ))

(defvar a)
(setq a 100)

(defun fun ()
  a)

;; geh.el:21:1: Warning: Lexical argument shadows the dynamic variable a
(slet ((a 1))
      (list a (fun)) ) ; (1 100)

(let ((a 2))
  (list a (fun))) ; (2 2)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-25 23:34                       ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-25 23:40                         ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-26  0:10                           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-25 23:46                         ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-25 23:47                         ` Stefan Monnier via Users list for the GNU Emacs text editor
  2 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-25 23:40 UTC (permalink / raw)
  To: help-gnu-emacs

> So why does it "work" with no defvar, just `setq'?

Indeed, it works with just `setq', and no `defvar'!

Now the byte-compiler instead warns about a reference to
a free variable. Maybe it shouldn't do that and instead warn
when one uses `defvar'?

;;; -*- lexical-binding: t -*-
;;;
;;; this file:
;;;   http://user.it.uu.se/~embe8573/emacs-init/geh.el
;;;   https://dataswamp.org/~incal/emacs-init/geh.el

(defmacro slet (bindings &rest body)
  (unless lexical-binding
    (error "`slet' requires `lexical-binding' to be enabled") )
  `(funcall
    (lambda ,(mapcar #'car bindings)
      ,@body)
    ,@(mapcar #'cadr bindings) ))

(setq b 200)

(defun fun ()
  b) ; geh.el:18:3: Warning: reference to free variable ‘b’

(slet ((b 1))
      (list b (fun)) ) ; (1 200)

(let ((b 2))
  (list b (fun))) ; (2 200)

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-25 23:34                       ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-25 23:40                         ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-25 23:46                         ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-25 23:47                         ` Stefan Monnier via Users list for the GNU Emacs text editor
  2 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-25 23:46 UTC (permalink / raw)
  To: help-gnu-emacs

> (defmacro slet (bindings &rest body)
>   (unless lexical-binding
>     (error "`slet' requires `lexical-binding' to be enabled") )
>   `(funcall
>     (lambda ,(mapcar #'car bindings)
>       ,@body)
>     ,@(mapcar #'cadr bindings) ))

Can't we add "slet" to Emacs, then one would always get the
intended static scope and it is even foolproof since it warns
if `lexical-binding' isn't enabled.

Don't forget the auto-indentation for `emacs-lisp-mode' ...

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-25 23:34                       ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-25 23:40                         ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-25 23:46                         ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-25 23:47                         ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-26  0:57                           ` Emanuel Berg via Users list for the GNU Emacs text editor
                                             ` (2 more replies)
  2 siblings, 3 replies; 61+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-25 23:47 UTC (permalink / raw)
  To: help-gnu-emacs

> This means, I've been using `defvar' to shut up the
> byte-compiler about variables not known to be defined, and
> this has actually made them dynamic?

Of course.  If the compiler says it's "not known to be defined" that
means the var isn't bound lexically (either that, or there's a bug in
the compiler), so it can only make sense if the var is
global or dynamically scoped (and both are closely related).

There exist global variables which shouldn't be dynamically scoped, but
they're rare in ELisp, mostly because of our use of namespace prefixes.

One example is the variable `pi` which holds the famous constant but we
don't want (let ((pi (get-previous-interval x))) ...) to temporarily
redefine `pi` to something unrelated.

This example is obsolete, tho: you should use `float-pi` instead of `pi`
to refer to the famous constant.


        Stefan




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-25 23:40                         ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-26  0:10                           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-26  0:44                             ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26  0:10 UTC (permalink / raw)
  To: help-gnu-emacs

> Now the byte-compiler instead warns about a reference to
> a free variable. Maybe it shouldn't do that and instead warn
> when one uses `defvar'?

The byte-compiler also warns about the assignment to the same
variable, this is the `setq' line.

  geh.el: 
  In toplevel form:
  geh.el:15:7: Warning: assignment to free variable ‘b’

  In fun:
  geh.el:18:3: Warning: reference to free variable ‘b’

Other byte-compiler questions are, why does it stop warning
after a second compilation? Because there is no change to the
source file, so no compilation happens? But doesn't that mean
you can just compile away the shortcomings of the code?

Also, why does the warnings appear so many times? The file
(geh.el) isn't `require'd or anything from any other file.
Just `load'ed, once. Yet both warnings appear 6 times!

And all the cl warnings, from slime ... slime stuff is
required from two files, `slime' but also
`slime-presentations', `slime-autoloads', `slime-banner', and
`slime-reply'. (I use a/the MELPA version, 2.26.1.)

Anyway, that warning appear 12 times! See output after geh.el,
and last the Makefile.

;;; -*- lexical-binding: t -*-
;;;
;;; this file:
;;;   http://user.it.uu.se/~embe8573/emacs-init/geh.el
;;;   https://dataswamp.org/~incal/emacs-init/geh.el

(defmacro slet (bindings &rest body)
  (unless lexical-binding
    (error "`slet' requires `lexical-binding' to be enabled") )
  `(funcall
    (lambda ,(mapcar #'car bindings)
      ,@body)
    ,@(mapcar #'cadr bindings) ))

(setq b 200)

(defun fun ()
  b) ; geh.el:18:3: Warning: reference to free variable ‘b’

(slet ((b 1))
      (list b (fun)) ) ; (1 200)

(let ((b 2))
  (list b (fun))) ; (2 200)

(how-many "Warning: assignment to free variable ‘b’" (point) (point-max)) ;  6
(how-many "Warning: reference to free variable ‘b’"  (point) (point-max)) ;  6
(how-many "Warning: Package cl is deprecated"        (point) (point-max)) ; 12

erc/erc-kill.el:
erc/erc-iterate.el:
In toplevel form:
geh.el:15:7: Warning: assignment to free variable ‘b’

In fun:
geh.el:18:3: Warning: reference to free variable ‘b’

In toplevel form:
geh.el:15:7: Warning: assignment to free variable ‘b’

In fun:
geh.el:18:3: Warning: reference to free variable ‘b’

frame-size.el:
erc/erc-spell.el:
In toplevel form:
geh.el:15:7: Warning: assignment to free variable ‘b’

In fun:
geh.el:18:3: Warning: reference to free variable ‘b’

geh.el:
get-search-string.el:
In toplevel form:
geh.el:15:7: Warning: assignment to free variable ‘b’

In fun:
geh.el:18:3: Warning: reference to free variable ‘b’

In toplevel form:
geh.el:15:7: Warning: assignment to free variable ‘b’

In fun:
geh.el:18:3: Warning: reference to free variable ‘b’

In toplevel form:
geh.el:15:7: Warning: assignment to free variable ‘b’

In fun:
geh.el:18:3: Warning: reference to free variable ‘b’

gnus/mail.el:
In toplevel form:
ide/slime-incal.el:33:1: Warning: Package cl is deprecated

ide/slime-incal.el:
In toplevel form:
ide/slime-incal.el:33:1: Warning: Package cl is deprecated

global-keys.el:
In toplevel form:
ide/slime-incal.el:33:1: Warning: Package cl is deprecated

face.el:
ide/ide.el:
In toplevel form:
face.el:15:1: Warning: Package cl is deprecated

In toplevel form:
face.el:15:1: Warning: Package cl is deprecated

sort-incal.el:
street.el:
In toplevel form:
face.el:15:1: Warning: Package cl is deprecated

In toplevel form:
face.el:15:1: Warning: Package cl is deprecated

string.el:
In toplevel form:
face.el:15:1: Warning: Package cl is deprecated

navigate-fs-keys.el:
In toplevel form:
face.el:15:1: Warning: Package cl is deprecated

super.el:
scroll.el:
In toplevel form:
face.el:15:1: Warning: Package cl is deprecated

In toplevel form:
face.el:15:1: Warning: Package cl is deprecated

string-minibuffer.el:
In toplevel form:
face.el:15:1: Warning: Package cl is deprecated

# this file:
#   http://user.it.uu.se/~embe8573/emacs-init/Makefile
#   https://dataswamp.org/~incal/emacs-init/Makefile

emacs=/usr/local/bin/emacs

ema-path=~/.emacs.d/emacs-init

ema-erc=\"${ema-path}/erc\"
ema-gnus=\"${ema-path}/gnus\"
ema-ide=\"${ema-path}/ide\"
ema-init=\"${ema-path}\"
ema-w3m=\"${ema-path}/w3m\"
ema=${ema-erc} ${ema-gnus} ${ema-ide} ${ema-init} ${ema-w3m}

elpa-path=~/.emacs.d/elpa

markdown-mode=\"${elpa-path}/markdown-mode-20201220.253\"
w3m=\"${elpa-path}/w3m-20210615.103\"

elpa=${markdown-mode} ${w3m}

slime=\"/usr/share/emacs/site-lisp/elpa-src/slime-2.26.1/\"

packs=${ema} ${elpa} ${slime}

byte-compile=$(emacs)                                       \
	--batch                                                  \
	--eval "(setq load-path (append load-path '(${packs})))" \
	-f batch-byte-compile

sed-filter=2>&1 | sed '/^\(Loading\|Wrote\)/d' # errors and warnings only

error-file=error.txt

INIT_FILE=~/.emacs
INIT_FILE_BC=$(INIT_FILE).elc

ELS = $(shell zsh -c "ls -1 **/*.el")
ELCS= $(ELS:.el=.elc)

all: $(ELCS) $(INIT_FILE_BC)
	rm -f $(error-file)

$(INIT_FILE_BC): $(INIT_FILE)
	$(byte-compile) $< $(sed-filter)

%.elc: %.el
	$(byte-compile) $< $(sed-filter) > $(error-file)
	if [ -s $(error-file) ]; then echo -n "\n$<: "; cat $(error-file); fi
	rm -f $<~

clean:
	$(shell zsh -c "rm -rf **/*.elc(N)")
	rm -f $(INIT_FILE_BC) $(error-file)

again:
	${MAKE} clean
	${MAKE}

new:
	${MAKE} again

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-26  0:10                           ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-26  0:44                             ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-26 17:01                               ` FW: " Drew Adams
  0 siblings, 1 reply; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26  0:44 UTC (permalink / raw)
  To: help-gnu-emacs

So the way it should be done is:

Put ;;; -*- lexical-binding: t -*- in the beginning of
the file.

Use `defvar' and `setq' for global variables that then become
special/dynamic.

Use `let' for local variables that then become lexical/static
(because of `lexical-binding').

And nothing unexpected ever happens, because for the global,
special/dynamic variables one uses prefixes?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-25 23:47                         ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2021-08-26  0:57                           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-28  1:36                           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-28  1:41                           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26  0:57 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

> One example is the variable `pi` which holds the famous
> constant but we don't want (let ((pi (get-previous-interval
> x))) ...) to temporarily redefine `pi` to
> something unrelated.
>
> This example is obsolete, tho: you should use `float-pi`
> instead of `pi` to refer to the famous constant.

Right, but `float-pi' is defined with `defconst'.

Let's see what it says ...

  Define SYMBOL as a constant variable. This declares that
  neither programs nor users should ever change the value.
  This constancy is not actually enforced by Emacs Lisp, but
  SYMBOL is marked as a special variable so that it is never
  lexically bound.

It looks like this in float-sup.el:

  (defconst float-pi (* 4 (atan 1)) "The value of Pi (3.1415926...).")
  (with-suppressed-warnings ((lexical pi))
    (defconst pi float-pi
      "Obsolete since Emacs-23.3.  Use `float-pi' instead."))
  (internal-make-var-non-special 'pi)

So `pi' is explicitely made non-dynamic with
`internal-make-var-non-special'.

-- 
underground experts united
https://dataswamp.org/~incal




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

* FW: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-26  0:44                             ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-26 17:01                               ` Drew Adams
  2021-08-26 23:05                                 ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Drew Adams @ 2021-08-26 17:01 UTC (permalink / raw)
  To: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'

[-- Attachment #1: Type: text/plain, Size: 714 bytes --]

> So the way it should be done is:
> 
> Put ;;; -*- lexical-binding: t -*- in the beginning of
> the file.
> 
> Use `defvar' and `setq' for global variables that then become
> special/dynamic.
> 
> Use `let' for local variables that then become lexical/static
> (because of `lexical-binding').

Except `let' binds dynamically bound (aka "special")
vars dynamically.  E.g., if you have a (defvar foo)
declaration then a subsequent (let ((foo ...))...)
binds `foo' dynamically.

> And nothing unexpected ever happens, because for the global,
> special/dynamic variables one uses prefixes?

Does one?  Maybe.  But how do you think a
prefix in the name changes something wrt
the kind of binding?

[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 14138 bytes --]

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

* Re: FW: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-26 17:01                               ` FW: " Drew Adams
@ 2021-08-26 23:05                                 ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26 23:05 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

>> Use `let' for local variables that then become
>> lexical/static (because of `lexical-binding').
>
> Except `let' binds dynamically bound (aka "special")
> vars dynamically.  E.g., if you have a (defvar foo)
> declaration then a subsequent (let ((foo ...))...)
> binds `foo' dynamically.
>
>> And nothing unexpected ever happens, because for the
>> global, special/dynamic variables one uses prefixes?
>
> Does one? Maybe. But how do you think a prefix in the name
> changes something wrt the kind of binding?

I don't know, maybe one isn't supposed to use prefixes in
`let'?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-25 23:47                         ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-26  0:57                           ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-28  1:36                           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-28  1:41                           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-28  1:36 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

> Of course. If the compiler says it's "not known to be
> defined" that means the var isn't bound lexically (either
> that, or there's a bug in the compiler), so it can only make
> sense if the var is global or dynamically scoped (and both
> are closely related).

Check this out, here we seemingly define a global variable
which isn't special/dynamic (because `special-variable-p' says
it isn't) but it behaves like one anyway so I guess it is?
Maybe it (the predicate) can only look at the definition and
if it doesn't have an initial/default value it can't tell
... something?

;;; -*- lexical-binding: t -*-
;;;
;;; this file:
;;;   https://dataswamp.org/~incal/emacs-init/scope.el
;;;
;;; g  = global
;;; sd = special/dynamic
;;; ls = lexical/static
;;; v  = variable

(defvar gsd-v 1)            ; 1
(special-variable-p 'gsd-v) ; t

(defvar gls-v)
(setq gls-v 2)              ; 2
(special-variable-p 'gls-v) ; nil

(defun fun-lol ()
  (list gsd-v gls-v v) )

(setq lexical-binding nil)

(let ((gsd-v 100)
      (gls-v 200)
      (v     300) )
  (list (list gsd-v gls-v v)
        (fun-lol) )) ; ((100 200 300) (100 200 300))

(setq lexical-binding t)

(let ((gsd-v 100)
      (gls-v 200)
      (v     300) )
  (list (list gsd-v gls-v v)
        (fun-lol) )) ; DNC, lexical/static `let' binding v undefined in fun-lol

(defun fun-lol-2 ()
  (list gsd-v gls-v) )

(let ((gsd-v 100)
      (gls-v 200)
      (v     300) )
  (list (list gsd-v gls-v v)
        (fun-lol-2) )) ; ((100 200 300) (100 200))

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-25 23:47                         ` Stefan Monnier via Users list for the GNU Emacs text editor
  2021-08-26  0:57                           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-08-28  1:36                           ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-08-28  1:41                           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-28  1:41 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

> One example is the variable `pi` which holds the famous
> constant but we don't want (let ((pi (get-previous-interval
> x))) ...) to temporarily redefine `pi` to
> something unrelated.

(defconst float-pi (* 4 (atan 1)) "The value of Pi (3.1415926...).")
(with-suppressed-warnings ((lexical pi))
  (defconst pi float-pi
    "Obsolete since Emacs-23.3.  Use `float-pi' instead."))
(make-obsolete-variable 'pi 'float-pi "23.3")
(internal-make-var-non-special 'pi)

OT, can't (make-obsolete-variable 'pi 'float-pi "23.3") make
that docstring ... obsolete?

Or perhaps one still wants it so it'll be human-language
readable in the code, not just the help/byte-compiler?

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2021-08-15 23:16               ` Drew Adams
@ 2022-01-09  7:08                 ` Jean Louis
  2022-01-09 15:03                   ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Jean Louis @ 2022-01-09  7:08 UTC (permalink / raw)
  To: Drew Adams
  Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)', Emanuel Berg

* Drew Adams <drew.adams@oracle.com> [2021-08-16 02:17]:
> FWIW, I just wrote a tiny library, `dyna-show.el',
> that defines minor mode `dyna-show-mode', which
> highlights occurrences of "special" (aka dynamically
> scoped) variables.
> 
> It just uses `special-variable-p', which is limited.
> 
> From the attachment, you can see another limitation:
> occurrences of a function, e.g. `font-lock-mode',
> that has the same name as a dynamic variable are also
> highlighted.

Thanks, it is very helpful for cosmetics of the code.

-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



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

* Re: [External] : Re: Lexical vs. dynamic: small examples?
  2022-01-09  7:08                 ` Jean Louis
@ 2022-01-09 15:03                   ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-01-09 15:03 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

>> FWIW, I just wrote a tiny library, `dyna-show.el', that
>> defines minor mode `dyna-show-mode', which highlights
>> occurrences of "special" (aka dynamically
>> scoped) variables.
>> 
>> It just uses `special-variable-p', which is limited.
>> 
>> From the attachment, you can see another limitation:
>> occurrences of a function, e.g. `font-lock-mode', that has
>> the same name as a dynamic variable are also highlighted.
>
> Thanks, it is very helpful for cosmetics of the code.

But here it also has a functional value. Or to be even more
precise, the functional value is also what is appealing, since
I think it started in that end.

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Lexical vs. dynamic: small examples?
@ 2022-01-09 17:40 Drew Adams
  2022-01-10 13:10 ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 61+ messages in thread
From: Drew Adams @ 2022-01-09 17:40 UTC (permalink / raw)
  To: Emanuel Berg, 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'

[-- Attachment #1: Type: text/plain, Size: 1776 bytes --]

> >> FWIW, I just wrote a tiny library, `dyna-show.el', that
> >> defines minor mode `dyna-show-mode', which highlights
> >> occurrences of "special" (aka dynamically
> >> scoped) variables.
> >>
> >> It just uses `special-variable-p', which is limited.
> >>
> >> From the attachment, you can see another limitation:
> >> occurrences of a function, e.g. `font-lock-mode', that has
> >> the same name as a dynamic variable are also highlighted.
> >
> > Thanks, it is very helpful for cosmetics of the code.
> 
> But here it also has a functional value. Or to be even more
> precise, the functional value is also what is appealing, since
> I think it started in that end.

tl;dr:
1. It can be useful.  2. It's not foolproof.
___

I guess you're referring to this (from the
`dyna-show.el' Commentary)?

 [I]f a function has the same name as a dynamic
 variable, then its occurrences are also
 highlighted, as if they were occurrences of
 the variable.

For example `font-lock-mode' is a variable as
well as a function.  Both kinds of occurrences
of that symbol are highlighted the same.

Whether this is considered a feature or a
limitation, the reason is that it requires no
analysis of the code (which would anyway be
problematic and limited) to determine how each
occurrence is used.  

The Commentary calls it out as a limitation.
And the sentence above comes right after this
additional caveat:

 The simple built-in test `special-variable-p'
 is used.  That test is not 100% reliable.  It
 doesn't respect vacuous `defvar' sexps, which
 declare a variable to be special in a given
 context, without assigning a value to the
 variable.  Instead, it uses `defvar',`defconst',
 and `defcustom' sexps with a value arg present.

[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 13769 bytes --]

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

* Re: Lexical vs. dynamic: small examples?
  2022-01-09 17:40 Drew Adams
@ 2022-01-10 13:10 ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 61+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-01-10 13:10 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

>> But here it also has a functional value. Or to be even more
>> precise, the functional value is also what is appealing,
>> since I think it started in that end.
>
> tl;dr:
> 1. It can be useful.  2. It's not foolproof.
> ___
>
> I guess you're referring to this (from the
> `dyna-show.el' Commentary)?
>
>  [I]f a function has the same name as a dynamic
>  variable, then its occurrences are also
>  highlighted, as if they were occurrences of
>  the variable.
>
> For example `font-lock-mode' is a variable as
> well as a function.  Both kinds of occurrences
> of that symbol are highlighted the same.
>
> Whether this is considered a feature or a
> limitation, the reason is that it requires no
> analysis of the code (which would anyway be
> problematic and limited) to determine how each
> occurrence is used.  
>
> The Commentary calls it out as a limitation.
> And the sentence above comes right after this
> additional caveat:
>
>   The simple built-in test `special-variable-p' is used.
>   That test is not 100% reliable. It doesn't respect vacuous
>   `defvar' sexps, which declare a variable to be special in
>   a given context, without assigning a value to the
>   variable. Instead, it uses `defvar',`defconst', and
>   `defcustom' sexps with a value arg present.

Well, yes, that's a good example, but actually the functional
gain starts with the programmer thinking "hey, what should it
be called?" - "obey tradition" (follow the convention) and
even at that point the harsh reality of a programmer gets
a little "bit" easier ;)

-- 
underground experts united
https://dataswamp.org/~incal




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

end of thread, other threads:[~2022-01-10 13:10 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-14  3:34 Lexical vs. dynamic: small examples? Eduardo Ochs
2021-08-14  3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-14  4:12   ` Eduardo Ochs
2021-08-14  7:35 ` tomas
2021-08-14 16:00   ` Eduardo Ochs
2021-08-14 19:41     ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-14 20:42     ` tomas
2021-08-14 19:31   ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-14 20:31     ` tomas
2021-08-14 21:26       ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-14 21:29         ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-14 13:35 ` [External] : " Drew Adams
2021-08-14 16:15   ` Eduardo Ochs
2021-08-14 19:00 ` Gregory Heytings
2021-08-14 20:16   ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-14 20:23     ` Gregory Heytings
2021-08-14 21:05       ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-14 21:13         ` tomas
2021-08-14 21:28           ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-14 20:41   ` tomas
2021-08-15  0:29   ` [External] : " Drew Adams
2021-08-15  0:52     ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15  1:04     ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15  1:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15  4:44       ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15  5:02         ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 15:49         ` Drew Adams
2021-08-15 18:49           ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 21:55             ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-08-15 22:04               ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 21:57             ` Drew Adams
2021-08-15 22:20               ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 22:54                 ` Drew Adams
2021-08-15 23:16               ` Drew Adams
2022-01-09  7:08                 ` Jean Louis
2022-01-09 15:03                   ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 23:42               ` Arthur Miller
2021-08-15 22:02             ` Lars Ingebrigtsen
2021-08-15 22:22               ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 22:44                 ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-08-21  3:38                   ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-24  2:08                     ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-08-25 23:34                       ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-25 23:40                         ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-26  0:10                           ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-26  0:44                             ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-26 17:01                               ` FW: " Drew Adams
2021-08-26 23:05                                 ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-25 23:46                         ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-25 23:47                         ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-08-26  0:57                           ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-28  1:36                           ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-28  1:41                           ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 22:44               ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 22:58                 ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-08-15 23:13                   ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 23:56                     ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-08-16  0:43                       ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-08-15 15:42       ` FW: " Drew Adams
  -- strict thread matches above, loose matches on Subject: below --
2022-01-09 17:40 Drew Adams
2022-01-10 13:10 ` Emanuel Berg via Users list for the GNU Emacs text editor

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.