unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Effect of lexical binding upon function paramaters
@ 2022-11-03 11:01 Heime
  2022-11-03 13:01 ` Emanuel Berg
  0 siblings, 1 reply; 9+ messages in thread
From: Heime @ 2022-11-03 11:01 UTC (permalink / raw)
  To: Heime via Users list for the GNU Emacs text editor


Now that files will use lexical binding, would there be any implications
to the following code?

(defun ignition (featr actm)
  "TODO."

  (when (eq 'sweep featr) (setq featr 'icomplt))
  (message "%S" featr))

Calling the following sequence of commands

(setq featr 'sweep)
(ignition featr actm)
(message "%S" featr)

gives the following result

icomplt
sweep

This means that paramaters of the function definition become local variables within the function body.
Does this behaviour change upon whether lexical or dynamic binding is used.   What should be the correct
approach now that lexical binding is the usual way to proceed?






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

* Re: Effect of lexical binding upon function paramaters
  2022-11-03 11:01 Effect of lexical binding upon function paramaters Heime
@ 2022-11-03 13:01 ` Emanuel Berg
  2022-11-04 19:30   ` Stefan Monnier via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 9+ messages in thread
From: Emanuel Berg @ 2022-11-03 13:01 UTC (permalink / raw)
  To: help-gnu-emacs

Heime wrote:

> (defun ignition (featr actm)
>   "TODO."
>
>   (when (eq 'sweep featr) (setq featr 'icomplt))
>   (message "%S" featr))
>
> Calling the following sequence of commands
>
> (setq featr 'sweep)
> (ignition featr actm)
> (message "%S" featr)

What I can see from this test below, formal parameters
("arguments" in standard information interchange) are always
dynamic under dynabound, and always static under lexical
binding, this holds even in the presence of same-named global
variables (and it doesn't matter if they are lexical or
special).

Yeah, too complicated ...

But observe,

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/geh.el

(setq i 1)
(special-variable-p 'i) ; nil

(defvar j 2)
(special-variable-p 'j) ; t

(defun use-i-and-j ()
  (list i j) )

(defun vars-ij (i j)
  (setq i 123123)
  (setq j 666888)
  (use-i-and-j) )

(vars-ij 111111 222222) ; (1 2) lexical
                        ; (123123 666888) dynamic

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




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

* Re: Effect of lexical binding upon function paramaters
  2022-11-03 13:01 ` Emanuel Berg
@ 2022-11-04 19:30   ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-11-04 20:23     ` Heime
  2022-11-05 15:32     ` Emanuel Berg
  0 siblings, 2 replies; 9+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-11-04 19:30 UTC (permalink / raw)
  To: help-gnu-emacs

> What I can see from this test below, formal parameters
> ("arguments" in standard information interchange) are always
> dynamic under dynabound, and always static under lexical

Yup.  Same holds for the var bound by `condition-case`.  The binding
constructs that can be "either/or" are `let` and `let*` (via
`lexical-let` for the dynbound dialect and via `defvar` for the
lexbound dialect).


        Stefan




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

* Re: Effect of lexical binding upon function paramaters
  2022-11-04 19:30   ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-11-04 20:23     ` Heime
  2022-11-04 20:34       ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-11-05 16:25       ` Emanuel Berg
  2022-11-05 15:32     ` Emanuel Berg
  1 sibling, 2 replies; 9+ messages in thread
From: Heime @ 2022-11-04 20:23 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs


------- Original Message -------
On Friday, November 4th, 2022 at 7:30 PM, Stefan Monnier via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote:


> > What I can see from this test below, formal parameters
> > ("arguments" in standard information interchange) are always
> > dynamic under dynabound, and always static under lexical
> 
> 
> Yup. Same holds for the var bound by `condition-case`. The binding
> constructs that can be "either/or" are `let` and `let*` (via
> `lexical-let` for the dynbound dialect and via `defvar` for the
> lexbound dialect).
> 
> 
> Stefan

So what are we to do or understand?




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

* Re: Effect of lexical binding upon function paramaters
  2022-11-04 20:23     ` Heime
@ 2022-11-04 20:34       ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-11-04 20:45         ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-11-05 16:25       ` Emanuel Berg
  1 sibling, 1 reply; 9+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-11-04 20:34 UTC (permalink / raw)
  To: help-gnu-emacs

> So what are we to do

Write more and better ELisp code, of course.

> or understand?

As much as possible, obviously,


        Stefan




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

* Re: Effect of lexical binding upon function paramaters
  2022-11-04 20:34       ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-11-04 20:45         ` Stefan Monnier via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 9+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-11-04 20:45 UTC (permalink / raw)
  To: help-gnu-emacs

More seriously, I haven't been able to understand what is the problem
you're trying to solve (or even that you were trying to solve
a problem).  All I could see was a question about how ELisp works.


        Stefan


Stefan Monnier via Users list for the GNU Emacs text editor [2022-11-04 16:34:18] wrote:

>> So what are we to do
>
> Write more and better ELisp code, of course.
>
>> or understand?
>
> As much as possible, obviously,
>
>
>         Stefan




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

* Re: Effect of lexical binding upon function paramaters
  2022-11-04 19:30   ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-11-04 20:23     ` Heime
@ 2022-11-05 15:32     ` Emanuel Berg
  2022-11-06 20:44       ` Emanuel Berg
  1 sibling, 1 reply; 9+ messages in thread
From: Emanuel Berg @ 2022-11-05 15:32 UTC (permalink / raw)
  To: help-gnu-emacs

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

>> What I can see from this test below, formal parameters
>> ("arguments" in standard information interchange) are
>> always dynamic under dynabound, and always static under
>> lexical
>
> Yup. Same holds for the var bound by `condition-case`.
> The binding constructs that can be "either/or" are `let` and
> `let*` (via `lexical-let` for the dynbound dialect and via
> `defvar` for the lexbound dialect).

For dynbound `let'/`let*' defaults to dynamic, just as it
defaults to lexical for lexbound.

However in the presence of another variable with the same
name, while `let'/`let*' can bind it to another value, it
doesn't change the lexical/dynamic status of the variable -
and this is the case for both dialects.

So how do you create a lexical binding under dynbound?
`lexical-let'. (See example last.) And a dynamic/special
variable under lexbound? `defvar'.

So is it all about what let/let* defaults to? Almost?

The other cases (formal parameters etc), should one consider
them being dynamic as just collateral damage from an
implementation policy detail which had to do with something
else or are there arguments (ha) for that as well?

(defun test-y ()
  y)

(let ((y 1))
  (test-y) ) ; works, y is dynamic

(lexical-let ((y 6))
  (let ((y 10))
    y ; 10 but ...
    (test-y) )) ; DNC in test-y, y is lexical

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




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

* Re: Effect of lexical binding upon function paramaters
  2022-11-04 20:23     ` Heime
  2022-11-04 20:34       ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-11-05 16:25       ` Emanuel Berg
  1 sibling, 0 replies; 9+ messages in thread
From: Emanuel Berg @ 2022-11-05 16:25 UTC (permalink / raw)
  To: help-gnu-emacs

Heime wrote:

>>> What I can see from this test below, formal parameters
>>> ("arguments" in standard information interchange) are
>>> always dynamic under dynabound, and always static under
>>> lexical
>> 
>> Yup. Same holds for the var bound by `condition-case`.
>> The binding constructs that can be "either/or" are `let`
>> and `let*` (via `lexical-let` for the dynbound dialect and
>> via `defvar` for the lexbound dialect).
>
> So what are we to do

Use lexbound, so far by adding this, as you know

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

as the first line of every Elisp source file.

Byte-compile the source, it will warn you for unused lexical
variables for example.

Avoid global lexical variables (created with `setq' in the
absence of another variable with the same name), instead use
let-closures for the 'persistent value' (state) and
share-between-functions use cases.

If you desire to create a global variable in the "option"
sense, i.e. you want to introduce something like the
`fill-column' variable, because you imagine it will be used
across a range of functions and different settings (ha), even
be used by future functions - then use `defvar'.

Use `let'/`let*' for function-local variables to organize the
code neatly and break up computations into smaller steps, this
will be the number one use case, however let/let* can also be
used in the "with-option-temporarily-as" sense, in that case
that variable must already exist and be dynamic/special, so
either it is an Emacs option already _or_ you have created it
as described above, with `defvar'.

Note that you can mix this up, let/let* handles it all for you
transparently, just spell everything correctly, okay?

In the example below, we see that `fill-column' is already
a dynamic/special variable, i.e. a global option.
In a lexbound `let', we create "a" and "b" and since they
don't exist they default to lexical. `fill-column' OTOH is
temporarily assigned a new value and remains dynamic/special.

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

fill-column ; 62

(special-variable-p 'fill-column) ; t, i.e. dynamic/special

(let ((a 1) ; lexical/static
      (b 2) ; lexical/static
      (fill-column 10) ) ; dynamic/special
  (fill-paragraph) ) ; eval me, then change `fill-column' to say 99 and retry

fill-column ; 62

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




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

* Re: Effect of lexical binding upon function paramaters
  2022-11-05 15:32     ` Emanuel Berg
@ 2022-11-06 20:44       ` Emanuel Berg
  0 siblings, 0 replies; 9+ messages in thread
From: Emanuel Berg @ 2022-11-06 20:44 UTC (permalink / raw)
  To: help-gnu-emacs

> So is it all about what let/let* defaults to? [...]

So for completeness we need:

slet  - always static let

salet - static-adaptive let, defaults to static but don't
        change dynamic global binidngs with the same name,
        but binds new value for its reach

alet  - adaptive let, defaults to static if `lexical-binding'
        (which itself defautls to t), else defautls to
        dynamic. Also don't change existing globals from
        either binding styles into the other. (alet/alet* are
        also aliased from `let'/`let*'.)

dalet - dynamic-adaptive let, defaults to dynamic, don't
        change static

dlet  - always dynamic

For clarity and practical day-to-day use we need:

Alias 'locals' to slet (locals as in local variables).

A wrapper function or macro called 'opts' (as in "with options
as") which will first check if such an option has been defined
as a dynamic/special variable (i.e. with `defvar' or already
existing in Emacs as an option, possibly defined in C even),
and if all do exit it will just be like `dlet' and new values
will be assieged for its reach and duration.

So then the code would look like this

(locals ((x 5)
         (y 8) )
  ;; ...
  (opts ((fill-column 10))
    (fill-paragraph) )
  ;; ... )

and slet, salet, alet, dalet and dlet would seldom be used, at
least not directly, but they would be there for anyone who'd
want them.

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




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

end of thread, other threads:[~2022-11-06 20:44 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-03 11:01 Effect of lexical binding upon function paramaters Heime
2022-11-03 13:01 ` Emanuel Berg
2022-11-04 19:30   ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-11-04 20:23     ` Heime
2022-11-04 20:34       ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-11-04 20:45         ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-11-05 16:25       ` Emanuel Berg
2022-11-05 15:32     ` Emanuel Berg
2022-11-06 20:44       ` Emanuel Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).