all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* How do I pass a variable defined in a wrapping let, to a lambda?
@ 2022-03-11 22:44 Steinar Bang
  2022-03-11 23:04 ` Eric Abrahamsen
                   ` (2 more replies)
  0 siblings, 3 replies; 48+ messages in thread
From: Steinar Bang @ 2022-03-11 22:44 UTC (permalink / raw)
  To: help-gnu-emacs

I have been trying to write a restclient.el[1] result function that can be
used to save the body of a GET result to a file[2].

My first attempt didn't work[3].

I tried to look at an existing result function that actually worked[4],
and I finally figured it out: the final form of that function is a
lambda!

So it was probably that lambda that was run to create the result?

I rewrote my example code to this[5].

But it still didn't work.  And the reason it didn't work is that
filename didn't have a value set.

If I replace the filename variable with a text constant[6], then the
function works.

But as far as I can tell, the function in[4] uses variables defined in
the wrapping (let) in the lambda...?

So why is that working but my filename failing?

Thanks!


- Steinar

References:
[1] <https://github.com/pashky/restclient.el>
[2] <https://github.com/pashky/restclient.el/issues/275>
[3] <https://github.com/pashky/restclient.el/issues/275#issuecomment-1047537935>
[4] <https://github.com/pashky/restclient.el/blob/9e2cfa86529133eba6c9ef53794be182f15e4c21/restclient-jq.el#L49>
[5] <https://gist.github.com/steinarb/fe442b78fda5d70a2733785c8c50e976>
[6] <https://gist.github.com/steinarb/61ccca486827f84a08cbc3f414cfda27>



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-11 22:44 How do I pass a variable defined in a wrapping let, to a lambda? Steinar Bang
@ 2022-03-11 23:04 ` Eric Abrahamsen
  2022-03-12  4:52   ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-03-12  8:51   ` Steinar Bang
  2022-03-11 23:48 ` Eric Abrahamsen
  2022-03-11 23:58 ` Emanuel Berg via Users list for the GNU Emacs text editor
  2 siblings, 2 replies; 48+ messages in thread
From: Eric Abrahamsen @ 2022-03-11 23:04 UTC (permalink / raw)
  To: help-gnu-emacs

Steinar Bang <sb@dod.no> writes:

> I have been trying to write a restclient.el[1] result function that can be
> used to save the body of a GET result to a file[2].
>
> My first attempt didn't work[3].
>
> I tried to look at an existing result function that actually worked[4],
> and I finally figured it out: the final form of that function is a
> lambda!
>
> So it was probably that lambda that was run to create the result?
>
> I rewrote my example code to this[5].
>
> But it still didn't work.  And the reason it didn't work is that
> filename didn't have a value set.
>
> If I replace the filename variable with a text constant[6], then the
> function works.
>
> But as far as I can tell, the function in[4] uses variables defined in
> the wrapping (let) in the lambda...?
>
> So why is that working but my filename failing?

They've got a lexical-binding cookie at the top of the file, but you don't! :)




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-11 22:44 How do I pass a variable defined in a wrapping let, to a lambda? Steinar Bang
  2022-03-11 23:04 ` Eric Abrahamsen
@ 2022-03-11 23:48 ` Eric Abrahamsen
  2022-03-12  0:43   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-12  1:37   ` Michael Heerdegen
  2022-03-11 23:58 ` Emanuel Berg via Users list for the GNU Emacs text editor
  2 siblings, 2 replies; 48+ messages in thread
From: Eric Abrahamsen @ 2022-03-11 23:48 UTC (permalink / raw)
  To: help-gnu-emacs

Steinar Bang <sb@dod.no> writes:

>> I have been trying to write a restclient.el[1] result function that can be
>> used to save the body of a GET result to a file[2].
>>
>> My first attempt didn't work[3].
>>
>> I tried to look at an existing result function that actually worked[4],
>> and I finally figured it out: the final form of that function is a
>> lambda!
>>
>> So it was probably that lambda that was run to create the result?
>>
>> I rewrote my example code to this[5].
>>
>> But it still didn't work.  And the reason it didn't work is that
>> filename didn't have a value set.
>>
>> If I replace the filename variable with a text constant[6], then the
>> function works.
>>
>> But as far as I can tell, the function in[4] uses variables defined in
>> the wrapping (let) in the lambda...?
>>
>> So why is that working but my filename failing?

> They've got a lexical-binding cookie at the top of the file, but you
> don't! :)

Oh, maybe I'm wrong. I just tested some code in two different elisp
buffers, one with lexical-binding -> t and one with it nil, and it
worked in both cases. Darn -- I thought I understood lexical-binding.

(defun steinars-test (file)
  (let ((fname (expand-file-name file)))
    (lambda () (message "file is %s" fname))))

(setq payload (steinars-test "~/.emacs.d/init.el"))

(funcall payload)




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-11 22:44 How do I pass a variable defined in a wrapping let, to a lambda? Steinar Bang
  2022-03-11 23:04 ` Eric Abrahamsen
  2022-03-11 23:48 ` Eric Abrahamsen
@ 2022-03-11 23:58 ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-12  0:47   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2 siblings, 1 reply; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-11 23:58 UTC (permalink / raw)
  To: help-gnu-emacs

Steinar Bang wrote:

> But it still didn't work. And the reason it didn't work is
> that filename didn't have a value set.
>
> If I replace the filename variable with a text constant[6],
> then the function works.
>
> But as far as I can tell, the function in uses variables
> defined in the wrapping (let) in the lambda...?

Dynamic/special scope?

But I see that you don't have that ... weird.

This works:

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

(defun add-one-f (term)
  (let ((tm term))
    (lambda () (1+ tm)) ))

(funcall (add-one-f 2)) ; 3

But not this:

;; this file:
;;   https://dataswamp.org/~incal/emacs-init/geh-dynamic.el

(defun add-two-f (term)
  (let ((tm term))
    (lambda () (+ 2 tm)) ))

(funcall (add-two-f 2)) ; Symbol’s value as variable is void: tm

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




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-11 23:48 ` Eric Abrahamsen
@ 2022-03-12  0:43   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-12  0:52     ` Eric Abrahamsen
  2022-03-12  0:58     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-12  1:37   ` Michael Heerdegen
  1 sibling, 2 replies; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-12  0:43 UTC (permalink / raw)
  To: help-gnu-emacs

Eric Abrahamsen wrote:

> Oh, maybe I'm wrong. I just tested some code in two
> different elisp buffers, one with lexical-binding -> t and
> one with it nil, and it worked in both cases.
>
> (defun steinars-test (file)
>   (let ((fname (expand-file-name file)))
>     (lambda () (message "file is %s" fname))))
>
> (setq payload (steinars-test "~/.emacs.d/init.el"))
>
> (funcall payload)

This doesn't work with dynamic/special binding for me ...

> Darn -- I thought I understood lexical-binding

Same :(

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




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-11 23:58 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-12  0:47   ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-12  0:47 UTC (permalink / raw)
  To: help-gnu-emacs

With static/lexical scope, you get the closure:

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

(defun add-one-f (term)
  (let ((tm term))
    (lambda () (1+ tm)) ))

;; (funcall (add-one-f 2)) ; 3

;; (add-one-f 2) ; (closure ((tm . 2) (term . 2) t) nil (1+ tm))

But with dynamic/special scope, you get only the lambda:

;; this file:
;;   https://dataswamp.org/~incal/emacs-init/geh-dynamic.el

(defun add-two-f (term)
  (let ((tm term))
    (lambda () (+ 2 tm)) ))

;; (funcall (add-two-f 2)) ; Symbol’s value as variable is void: tm

 ;; (add-two-f 2) ; (lambda nil (+ 2 tm))

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




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  0:43   ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-12  0:52     ` Eric Abrahamsen
  2022-03-12  1:00       ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-12  0:58     ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 1 reply; 48+ messages in thread
From: Eric Abrahamsen @ 2022-03-12  0:52 UTC (permalink / raw)
  To: help-gnu-emacs

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

> Eric Abrahamsen wrote:
>
>> Oh, maybe I'm wrong. I just tested some code in two
>> different elisp buffers, one with lexical-binding -> t and
>> one with it nil, and it worked in both cases.
>>
>> (defun steinars-test (file)
>>   (let ((fname (expand-file-name file)))
>>     (lambda () (message "file is %s" fname))))
>>
>> (setq payload (steinars-test "~/.emacs.d/init.el"))
>>
>> (funcall payload)
>
> This doesn't work with dynamic/special binding for me ...

Oh, but that's good -- it's not supposed to work with dynamic binding! I
might have just messed something up while testing.




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  0:43   ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-12  0:52     ` Eric Abrahamsen
@ 2022-03-12  0:58     ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 0 replies; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-12  0:58 UTC (permalink / raw)
  To: help-gnu-emacs

>> Darn -- I thought I understood lexical-binding
>
> Same :(

With static/lexical scope a function within a `let' is
a closure:

(let ((f 2))
  (defun two ()
    f) )
(two) ; 2

But with dynamic/special scope it isn't:

(let ((f 1))
  (defun one ()
    f) )
(one) ; Symbol’s value as variable is void: f

Same with lambdas - they are anonymous functions.

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




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  0:52     ` Eric Abrahamsen
@ 2022-03-12  1:00       ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-12  1:00 UTC (permalink / raw)
  To: help-gnu-emacs

Eric Abrahamsen wrote:

>>> (defun steinars-test (file)
>>>   (let ((fname (expand-file-name file)))
>>>     (lambda () (message "file is %s" fname))))
>>>
>>> (setq payload (steinars-test "~/.emacs.d/init.el"))
>>>
>>> (funcall payload)
>>
>> This doesn't work with dynamic/special binding for me ...
>
> Oh, but that's good -- it's not supposed to work with
> dynamic binding! I might have just messed something up
> while testing.

Still, didn't the OP use the "cookie" line as you called it?

;;; restclient-jq.el --- Support for setting restclient vars from jq expressions -*- lexical-binding: t; -*-                                      

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




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-11 23:48 ` Eric Abrahamsen
  2022-03-12  0:43   ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-12  1:37   ` Michael Heerdegen
  2022-03-12  2:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-12  2:19     ` Eric Abrahamsen
  1 sibling, 2 replies; 48+ messages in thread
From: Michael Heerdegen @ 2022-03-12  1:37 UTC (permalink / raw)
  To: help-gnu-emacs

Hi Eric,

you may want to find out what evaluating lexical-binding in the buffer
with lexical-binding -> nil gives you.

Second: (AFAIK...) be sure to reeval `steinars-test' with
lexical-binding -> nil.  `steinars-test' defined using the lexical
binding dialect will return a closure even when called in the
dynamcially binding dialect.

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> Oh, maybe I'm wrong. I just tested some code in two different elisp
> buffers, one with lexical-binding -> t and one with it nil, and it
> worked in both cases. Darn -- I thought I understood lexical-binding.
>
> (defun steinars-test (file)
>   (let ((fname (expand-file-name file)))
>     (lambda () (message "file is %s" fname))))
>
> (setq payload (steinars-test "~/.emacs.d/init.el"))
>
> (funcall payload)




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  1:37   ` Michael Heerdegen
@ 2022-03-12  2:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-12  6:40       ` Jean Louis
  2022-03-12  2:19     ` Eric Abrahamsen
  1 sibling, 1 reply; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-12  2:18 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen wrote:

> you may want to find out what evaluating lexical-binding in
> the buffer with lexical-binding -> nil gives you.
>
> Second: (AFAIK...) be sure to reeval `steinars-test' with
> lexical-binding -> nil. `steinars-test' defined using the
> lexical binding dialect will return a closure even when
> called in the dynamcially binding dialect.

This is an example of why I think there should be three `let':

* "let" that is static/lexical except for already-defined
  dynamic/special variables (i.e., what `let' is already under
  static/lexical scope, so won't break any code to change.
  well, there wouldn't be any change except static/lexical
  would be default everywhere)

* "dlet" that is always dynamic/special

* "slet" that is always static/lexical

Then we could get rid of the ugly and impractical cookie:

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

The insistence on "dlet" would break code for people w/o the
cookie who expects `let' do be dynamic/special, however it is
only good they are forced to be explicit with that and besides
it is only one `replace-regexp' away anyway ... all the way!

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




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  1:37   ` Michael Heerdegen
  2022-03-12  2:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-12  2:19     ` Eric Abrahamsen
  1 sibling, 0 replies; 48+ messages in thread
From: Eric Abrahamsen @ 2022-03-12  2:19 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen <michael_heerdegen@web.de> writes:

> Hi Eric,
>
> you may want to find out what evaluating lexical-binding in the buffer
> with lexical-binding -> nil gives you.
>
> Second: (AFAIK...) be sure to reeval `steinars-test' with
> lexical-binding -> nil.  `steinars-test' defined using the lexical
> binding dialect will return a closure even when called in the
> dynamcially binding dialect.

Yeah, I tried to do the second experiment with the function and variable
names incremented, but I think I was just in too much of a hurry and missed
one of them out (using the previous `steinars-test' instead of the
newler function). Anyway, nice to recover some confidence...




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-11 23:04 ` Eric Abrahamsen
@ 2022-03-12  4:52   ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-03-12  6:08     ` Eduardo Ochs
  2022-03-12  8:53     ` Steinar Bang
  2022-03-12  8:51   ` Steinar Bang
  1 sibling, 2 replies; 48+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-03-12  4:52 UTC (permalink / raw)
  To: help-gnu-emacs

Eric Abrahamsen [2022-03-11 15:04:30] wrote:
> They've got a lexical-binding cookie at the top of the file, but you don't! :)

That's right.
Nowadays, *all* files with a `.el` extension should have
`-*- lexical-binding:t -*-` somewhere on their first line.

Emacs-28 gives an orange `/d` warning in the modeline when that line
is missing (and uses a discrete `/l` instead when the line is present).
And you can click on the `/d` to fix the problem.


        Stefan




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  4:52   ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-03-12  6:08     ` Eduardo Ochs
  2022-03-12 13:33       ` Stefan Monnier
  2022-03-12  8:53     ` Steinar Bang
  1 sibling, 1 reply; 48+ messages in thread
From: Eduardo Ochs @ 2022-03-12  6:08 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs

On Sat, 12 Mar 2022 at 01:56, Stefan Monnier via Users list for the
GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote:
>
> That's right.
> Nowadays, *all* files with a `.el` extension should have
> `-*- lexical-binding:t -*-` somewhere on their first line.

Or a `-*- lexical-binding:nil -*-`...
Cheers,
  Eduardo Ochs
  http://angg.twu.net/#eev
  http://angg.twu.net/eev-intros/find-lexical-intro.html



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  2:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-12  6:40       ` Jean Louis
  2022-03-14 13:57         ` `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?) Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-14 14:51         ` How do I pass a variable defined in a wrapping let, to a lambda? Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 2 replies; 48+ messages in thread
From: Jean Louis @ 2022-03-12  6:40 UTC (permalink / raw)
  To: help-gnu-emacs

* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2022-03-12 05:41]:
> Michael Heerdegen wrote:
> 
> > you may want to find out what evaluating lexical-binding in
> > the buffer with lexical-binding -> nil gives you.
> >
> > Second: (AFAIK...) be sure to reeval `steinars-test' with
> > lexical-binding -> nil. `steinars-test' defined using the
> > lexical binding dialect will return a closure even when
> > called in the dynamcially binding dialect.
> 
> This is an example of why I think there should be three `let':
> 
> * "let" that is static/lexical except for already-defined
>   dynamic/special variables (i.e., what `let' is already under
>   static/lexical scope, so won't break any code to change.
>   well, there wouldn't be any change except static/lexical
>   would be default everywhere)
> 
> * "dlet" that is always dynamic/special

New `dlet' is this and it broke my programs because somebody removed
`let*'  inside. I don't think that person who changed it every used
`dlet' in their own programs. Reason is semantics, "dlet" uses "let*"
so they changed it, but did not provide "dlet*" (though is easy to
adapt it).

new `dlet':

(defmacro dlet (binders &rest body)
  "Like `let' but using dynamic scoping."
  (declare (indent 1) (debug let))
  ;; (defvar FOO) only affects the current scope, but in order for
  ;; this not to affect code after the main `let' we need to create a new scope,
  ;; which is what the surrounding `let' is for.
  ;; FIXME: (let () ...) currently doesn't actually create a new scope,
  ;; which is why we use (let (_) ...).
  `(let (_)
     ,@(mapcar (lambda (binder)
                 `(defvar ,(if (consp binder) (car binder) binder)))
               binders)
     (let ,binders ,@body)))

so I have just changed it back to what it was and use it with my own
prefix as `rcd-dlet' -- that way there is no need for quarrel.

(defmacro rcd-dlet (binders &rest body)
  "Like `let*' but using dynamic scoping."
  (declare (indent 1) (debug let))
  ;; (defvar FOO) only affects the current scope, but in order for
  ;; this not to affect code after the main `let' we need to create a new scope,
  ;; which is what the surrounding `let' is for.
  ;; FIXME: (let () ...) currently doesn't actually create a new scope,
  ;; which is why we use (let (_) ...).
  `(let (_)
     ,@(mapcar (lambda (binder)
                 `(defvar ,(if (consp binder) (car binder) binder)))
               binders)
     (let* ,binders ,@body)))


I find `dlet', rather `rcd-dlet' very useful in interpolation of
variables and templates that come from third sources, thus not coming
from the Emacs Lisp file itself.

Some insights:

      (rcd-dlet ((wrs::template (gethash "templates_content" wrs::template))
                 ;; now wrs::template is visible inside of
                 ;; wrs::template, sounds funny
	     (open-graph-type "Article")
                 ;; now "open-graph-type" variable is accessible
                 ;; for use or interpolation within wrs::template scripts
	     (wrs::html (rcd-template-eval wrs::template '("⟦" "⟧") wrs::variables))
                 ;; now wrs::template is interpolating various
                 ;; wrs::variables, expanding them inside of the
                 ;; template as otherwise they would not be visible
                 ;; rcd-dlet as only rcd-dlet breaks out of lexical binding
 	     (wrs::local-file (wrs-page-url page-id t))
	     (wrs::local-dir (file-name-directory wrs::local-file)))
	(make-directory wrs::local-dir t)
	(string-to-file-force wrs::html wrs::local-file)))))

-- 
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] 48+ messages in thread

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-11 23:04 ` Eric Abrahamsen
  2022-03-12  4:52   ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-03-12  8:51   ` Steinar Bang
  2022-03-12  9:34     ` Steinar Bang
  2022-03-12 14:03     ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 2 replies; 48+ messages in thread
From: Steinar Bang @ 2022-03-12  8:51 UTC (permalink / raw)
  To: help-gnu-emacs

>>>>> Eric Abrahamsen <eric@ericabrahamsen.net>:
> Steinar Bang <sb@dod.no> writes:
[snip!]
>> If I replace the filename variable with a text constant[6], then the
>> function works.

>> But as far as I can tell, the function in[4] uses variables defined in
>> the wrapping (let) in the lambda...?

>> So why is that working but my filename failing?

> They've got a lexical-binding cookie at the top of the file, but you don't! :)

Wait..? What...?  Huh...?

This thing:  -*- lexical-binding: t; -*- ?

Now *that* wasn't obscure at all...! :-)

But then this may be fixable after all.  I was going a bit crazy here
trying to figure out what was the difference between my code and the
code that worked.

(And I see from this thread that I'm not alone in being confused)

So thanks to all that contributed!

Too many to respond to each individually! :-)



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  4:52   ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-03-12  6:08     ` Eduardo Ochs
@ 2022-03-12  8:53     ` Steinar Bang
  2022-03-12 14:47       ` Stefan Monnier via Users list for the GNU Emacs text editor
  1 sibling, 1 reply; 48+ messages in thread
From: Steinar Bang @ 2022-03-12  8:53 UTC (permalink / raw)
  To: help-gnu-emacs

>>>>> Stefan Monnier via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org>:

> Eric Abrahamsen [2022-03-11 15:04:30] wrote:
>> They've got a lexical-binding cookie at the top of the file, but you don't! :)

> That's right.
> Nowadays, *all* files with a `.el` extension should have
> `-*- lexical-binding:t -*-` somewhere on their first line.

Can I do that in .emacs?

Or should I put this function in a separate .el file?

Thanks!


- Steinar



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  8:51   ` Steinar Bang
@ 2022-03-12  9:34     ` Steinar Bang
  2022-03-12 19:13       ` Steinar Bang
  2022-03-12 14:03     ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 1 reply; 48+ messages in thread
From: Steinar Bang @ 2022-03-12  9:34 UTC (permalink / raw)
  To: help-gnu-emacs

>>>>> Steinar Bang <sb@dod.no>:

> But then this may be fixable after all.

Ok, fixed!

I created this file in a directory in load-path, and byte compiled it.
 https://gist.github.com/steinarb/655b632c5f453f0d92bf346a1ac3f96a

Then I changed the .emacs settings to this:

;; restclient from git to get restclient-jq
(add-to-list 'load-path (expand-file-name "~/git/restclient.el"))
(when (locate-library "restclient")
  (require 'restclient)
  (require 'restclient-jq)
  (require 'sb-restclient)
  (restclient-register-result-func "save-body" #'restclient-save-body "Save body to filename given as arg"))

And then C-c C-c on this restclient rule, fetched the URL with GET and
saved the body to the file ~/.stinkyAuthtoken:

# -*-restclient-*-
# Fetch token
GET http://lorenzo.hjemme.lan/api/authorize
X-CSRF: 1
-> save-body ~/.stinkyAuthtoken

Thanks again to all that responded!

(and I can highly recommend restclient.el to all who are weary of postman)



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  6:08     ` Eduardo Ochs
@ 2022-03-12 13:33       ` Stefan Monnier
  2022-03-12 18:56         ` Eduardo Ochs
  0 siblings, 1 reply; 48+ messages in thread
From: Stefan Monnier @ 2022-03-12 13:33 UTC (permalink / raw)
  To: Eduardo Ochs; +Cc: help-gnu-emacs

Eduardo Ochs [2022-03-12 03:08:04] wrote:
> On Sat, 12 Mar 2022 at 01:56, Stefan Monnier via Users list for the
> GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote:
>> That's right.
>> Nowadays, *all* files with a `.el` extension should have
>> `-*- lexical-binding:t -*-` somewhere on their first line.
>
> Or a `-*- lexical-binding:nil -*-`...

The only justification I've seen for that so far is for tests that check
whether something still works with the old dialect of ELisp (i.e. for
files which can simply be deleted the day this old dialect is not
supported any more).


        Stefan




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  8:51   ` Steinar Bang
  2022-03-12  9:34     ` Steinar Bang
@ 2022-03-12 14:03     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-13 16:06       ` Eric Abrahamsen
  1 sibling, 1 reply; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-12 14:03 UTC (permalink / raw)
  To: help-gnu-emacs

Steinar Bang wrote:

>> They've got a lexical-binding cookie at the top of the
>> file, but you don't! :)
>
> Wait..? What...?  Huh...?
>
> This thing:  -*- lexical-binding: t; -*- ?

Why didn't that work, you had it when you asked the question?

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




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  8:53     ` Steinar Bang
@ 2022-03-12 14:47       ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-03-12 16:59         ` Steinar Bang
  0 siblings, 1 reply; 48+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-03-12 14:47 UTC (permalink / raw)
  To: help-gnu-emacs

Steinar Bang [2022-03-12 09:53:32] wrote:
>>>>>> Stefan Monnier via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org>:
>> Eric Abrahamsen [2022-03-11 15:04:30] wrote:
>>> They've got a lexical-binding cookie at the top of the file, but you don't! :)
>> That's right.
>> Nowadays, *all* files with a `.el` extension should have
>> `-*- lexical-binding:t -*-` somewhere on their first line.
> Can I do that in .emacs?

Depends what you mean by "do that".  You can't easily write a chunk of
ELisp code to put into your init file that will magically cause all
other files to have that cookie (at least not without probably
breaking some code somewhere).

But yes you can have that magic thingy on the first line of your init
file, just as for any other ELisp file.


        Stefan




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 14:47       ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-03-12 16:59         ` Steinar Bang
  2022-03-12 17:15           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-12 19:09           ` Stefan Monnier via Users list for the GNU Emacs text editor
  0 siblings, 2 replies; 48+ messages in thread
From: Steinar Bang @ 2022-03-12 16:59 UTC (permalink / raw)
  To: help-gnu-emacs

>>>>> Stefan Monnier via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org>:

> Steinar Bang [2022-03-12 09:53:32] wrote:
>>>>>>> Stefan Monnier via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org>:
>>> Eric Abrahamsen [2022-03-11 15:04:30] wrote:
>>>> They've got a lexical-binding cookie at the top of the file, but you don't! :)
>>> That's right.
>>> Nowadays, *all* files with a `.el` extension should have
>>> `-*- lexical-binding:t -*-` somewhere on their first line.

>> Can I do that in .emacs?

> Depends what you mean by "do that".  You can't easily write a chunk of
> ELisp code to put into your init file that will magically cause all
> other files to have that cookie (at least not without probably
> breaking some code somewhere).

> But yes you can have that magic thingy on the first line of your init
> file, just as for any other ELisp file.

I think what I meant was "should I enable lexical-binding in .emacs? Or
am I better off not enabling lexical-binding in .emacs?"

And I figured "probably better off not enabling lexical-binding in
.emacs", and put the function in a separate file.



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 16:59         ` Steinar Bang
@ 2022-03-12 17:15           ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-13 18:11             ` Steinar Bang
  2022-03-12 19:09           ` Stefan Monnier via Users list for the GNU Emacs text editor
  1 sibling, 1 reply; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-12 17:15 UTC (permalink / raw)
  To: help-gnu-emacs

Steinar Bang wrote:

> I think what I meant was "should I enable lexical-binding in
> .emacs? Or am I better off not enabling lexical-binding in
> .emacs?"
>
> And I figured "probably better off not enabling
> lexical-binding in .emacs", and put the function in
> a separate file.

Enable it everywhere ...

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




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 13:33       ` Stefan Monnier
@ 2022-03-12 18:56         ` Eduardo Ochs
  2022-03-12 19:12           ` Stefan Monnier
  2022-03-12 20:34           ` tomas
  0 siblings, 2 replies; 48+ messages in thread
From: Eduardo Ochs @ 2022-03-12 18:56 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs

On Sat, 12 Mar 2022 at 10:33, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>
> Eduardo Ochs [2022-03-12 03:08:04] wrote:
> > On Sat, 12 Mar 2022 at 01:56, Stefan Monnier via Users list for the
> > GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote:
> >> That's right.
> >> Nowadays, *all* files with a `.el` extension should have
> >> `-*- lexical-binding:t -*-` somewhere on their first line.
> >
> > Or a `-*- lexical-binding:nil -*-`...
>
> The only justification I've seen for that so far is for tests that check
> whether something still works with the old dialect of ELisp (i.e. for
> files which can simply be deleted the day this old dialect is not
> supported any more).

Well, SOME people like dynamic binding very much and they have code
that would be VERY hard to rewrite in lexical binding...

  https://lists.gnu.org/archive/html/help-gnu-emacs/2021-08/msg00345.html
  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=30078#86
  https://www.gnu.org/software/emacs/emacs-paper.html#SEC18

Cheers, E.



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 16:59         ` Steinar Bang
  2022-03-12 17:15           ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-12 19:09           ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-03-12 20:57             ` Steinar Bang
  1 sibling, 1 reply; 48+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-03-12 19:09 UTC (permalink / raw)
  To: help-gnu-emacs

> I think what I meant was "should I enable lexical-binding in .emacs?"

Yes, just like in all ELisp files.


        Stefan




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 18:56         ` Eduardo Ochs
@ 2022-03-12 19:12           ` Stefan Monnier
  2022-03-12 20:17             ` Eduardo Ochs
  2022-03-12 20:34           ` tomas
  1 sibling, 1 reply; 48+ messages in thread
From: Stefan Monnier @ 2022-03-12 19:12 UTC (permalink / raw)
  To: Eduardo Ochs; +Cc: help-gnu-emacs

> Well, SOME people like dynamic binding very much and they have code
> that would be VERY hard to rewrite in lexical binding...

`-*- lexical-binding:t -*-` doesn't prevent the use of dynamic scoping.


        Stefan




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  9:34     ` Steinar Bang
@ 2022-03-12 19:13       ` Steinar Bang
  0 siblings, 0 replies; 48+ messages in thread
From: Steinar Bang @ 2022-03-12 19:13 UTC (permalink / raw)
  To: help-gnu-emacs

>>>>> Steinar Bang <sb@dod.no>:

> And then C-c C-c on this restclient rule, fetched the URL with GET and
> saved the body to the file ~/.stinkyAuthtoken:

> # -*-restclient-*-
> # Fetch token
> GET http://lorenzo.hjemme.lan/api/authorize
> X-CSRF: 1
-> save-body ~/.stinkyAuthtoken

> Thanks again to all that responded!

> (and I can highly recommend restclient.el to all who are weary of postman)

I added a summary of what I found out, in a comment on the restclient.el
github issue:
 https://github.com/pashky/restclient.el/issues/275



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 19:12           ` Stefan Monnier
@ 2022-03-12 20:17             ` Eduardo Ochs
  2022-03-12 20:31               ` [External] : " Drew Adams
  0 siblings, 1 reply; 48+ messages in thread
From: Eduardo Ochs @ 2022-03-12 20:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs

On Sat, 12 Mar 2022 at 16:12, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>
> > Well, SOME people like dynamic binding very much and they have code
> > that would be VERY hard to rewrite in lexical binding...
>
> `-*- lexical-binding:t -*-` doesn't prevent the use of dynamic scoping.

How do I define a function that uses dynamic binding in a file that has
`-*- lexical-binding:t -*-`?

  E.



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

* RE: [External] : Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 20:17             ` Eduardo Ochs
@ 2022-03-12 20:31               ` Drew Adams
  2022-03-12 22:33                 ` Eduardo Ochs
  0 siblings, 1 reply; 48+ messages in thread
From: Drew Adams @ 2022-03-12 20:31 UTC (permalink / raw)
  To: Eduardo Ochs, Stefan Monnier; +Cc: help-gnu-emacs

> > `-*- lexical-binding:t -*-` doesn't prevent the use of 
> > dynamic scoping.
> 
> How do I define a function that uses dynamic binding in a 
> file that has `-*- lexical-binding:t -*-`?

A _function_ that uses it?  Just what do you mean by that?

Function names are (typically) bound dynamically, with defun.
___

For a variable, you use a vacuous defvar:

(defvar foo) ; "special" var, i.e. dynamically bound

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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 18:56         ` Eduardo Ochs
  2022-03-12 19:12           ` Stefan Monnier
@ 2022-03-12 20:34           ` tomas
  1 sibling, 0 replies; 48+ messages in thread
From: tomas @ 2022-03-12 20:34 UTC (permalink / raw)
  To: help-gnu-emacs

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

On Sat, Mar 12, 2022 at 03:56:24PM -0300, Eduardo Ochs wrote:
> On Sat, 12 Mar 2022 at 10:33, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> >
> > Eduardo Ochs [2022-03-12 03:08:04] wrote:
> > > On Sat, 12 Mar 2022 at 01:56, Stefan Monnier via Users list for the
> > > GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote:
> > >> That's right.
> > >> Nowadays, *all* files with a `.el` extension should have
> > >> `-*- lexical-binding:t -*-` somewhere on their first line.
> > >
> > > Or a `-*- lexical-binding:nil -*-`...
> >
> > The only justification I've seen for that so far is for tests that check
> > whether something still works with the old dialect of ELisp (i.e. for
> > files which can simply be deleted the day this old dialect is not
> > supported any more).
> 
> Well, SOME people like dynamic binding very much and they have code
> that would be VERY hard to rewrite in lexical binding...
> 
>   https://lists.gnu.org/archive/html/help-gnu-emacs/2021-08/msg00345.html

This reference is actually an argument *for* lexical binding
as a default, which is what -*- lexical-binding:t -*- does.

>   https://debbugs.gnu.org/cgi/bugreport.cgi?bug=30078#86

This one doesn't argue against -*- lexical-binding:t -*- but only
for keeping the possibility of having single dynamically bound
variables (and if you actually read your first reference carefully,
Drew favours "lexical by default, dynamic as an exception", so
definitely not -*- lexical-binding:nil -*-, as you propose.

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

 "This paper was written by Richard Stallman in 1981 and delivered in
  the ACM Conference on Text Processing."

Perl was born 1988 (seven years later) with dynamic binding (after
all, one of its spiritual parents was the UNIX shell, which also
has dynamic binding). In the meantime it is firmly in the lexical
camp (it keeps dynamic variables, they are useful, but they are
*by far* the exception).

Things have changed since then... a lot.

You can do what the above reference does with closures, which take...
lexical binding. Besides, the closure way is clearer and safer.

You might argue that dynamic binding is useful in some *single*
exceptional cases (this is the position Common Lisp or Perl take;
also the Schemes). But as a default for a whole file... no, you
don't really want that.

You want to put -*- lexical-binding:nil -*- at the top of a file
if you have inherited it and haven't come around to check whether
it will break under the (not anymore so) new discipline.

Note that most well-writen code won't mind which kind of binding
you use.

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 19:09           ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-03-12 20:57             ` Steinar Bang
  0 siblings, 0 replies; 48+ messages in thread
From: Steinar Bang @ 2022-03-12 20:57 UTC (permalink / raw)
  To: help-gnu-emacs

>>>>> Stefan Monnier via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org>:


>> I think what I meant was "should I enable lexical-binding in .emacs?"

> Yes, just like in all ELisp files.

Ah, well! It does seem like the most logical behaviour.



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

* Re: [External] : Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 20:31               ` [External] : " Drew Adams
@ 2022-03-12 22:33                 ` Eduardo Ochs
  2022-03-12 23:14                   ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-03-13  0:20                   ` Michael Heerdegen
  0 siblings, 2 replies; 48+ messages in thread
From: Eduardo Ochs @ 2022-03-12 22:33 UTC (permalink / raw)
  To: Drew Adams; +Cc: help-gnu-emacs, Stefan Monnier

On Sat, 12 Mar 2022 at 17:32, Drew Adams <drew.adams@oracle.com> wrote:
>
> > > `-*- lexical-binding:t -*-` doesn't prevent the use of
> > > dynamic scoping.
> >
> > How do I define a function that uses dynamic binding in a
> > file that has `-*- lexical-binding:t -*-`?
>
> A _function_ that uses it?  Just what do you mean by that?
>
> Function names are (typically) bound dynamically, with defun.
> ___
>
> For a variable, you use a vacuous defvar:
>
> (defvar foo) ; "special" var, i.e. dynamically bound

Hi Drew,

Here is something that I don't know how to port to lexical binding.
My functions that call `ee-template00' are all defined in files with
"-*- lexical-binding: nil; -*-" - they don't work if I put them in
files with "-*- lexical-binding: t; -*-".

  Cheers, E.


(defvar ee-template00-re "{\\([^{}]+\\)}")

;; Tests:
;; (ee-template00 "a{(+ 2 3)}b")
;; (let ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}"))
;;
(defun ee-template00 (str)
  "Replace substrings enclosed by `{}'s in STR by the result of evaluating them.
Examples:\n
  (ee-template00 \"a{(+ 2 3)}b\")
    -->  \"a5b\"\n
  (let ((hi \"Here:\") (a 22) (b 33))
    (ee-template00 \"{hi} {a} + {b} = {(+ a b)}\"))
    -->  \"22 + 33 = 55\""
  (save-match-data
    (replace-regexp-in-string
     ee-template00-re
     (lambda (_code_) (format "%s" (eval (read (substring _code_ 1 -1)))))
     str 'fixedcase 'literal)))

;; Test:
;;   (ee-dynlex-test "Aa" "Bb")
;; The sexp above returns this with dynamic binding,
;;   "<Aa AaAa Bb BbBb>"
;; and yields this error in lexical binding:
;;   "format: Symbol's value as variable is void: a"
;;
(defun ee-dynlex-test (a b)
  (let* ((aa (concat a a))
         (bb (concat b b)))
    (ee-template00 "<{a} {aa} {b} {bb}>")))



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

* Re: [External] : Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 22:33                 ` Eduardo Ochs
@ 2022-03-12 23:14                   ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-03-13 12:19                     ` Eduardo Ochs
  2022-03-13  0:20                   ` Michael Heerdegen
  1 sibling, 1 reply; 48+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-03-12 23:14 UTC (permalink / raw)
  To: help-gnu-emacs

> Here is something that I don't know how to port to lexical binding.
> My functions that call `ee-template00' are all defined in files with
> "-*- lexical-binding: nil; -*-" - they don't work if I put them in
> files with "-*- lexical-binding: t; -*-".

You can make it work by sprinkling enough `defvar`, of course: often
add `-*- lexical-binding: t; -*-` is all it takes, but sometimes you
have to work harder.

I remember battling with this code to beat it into submission by
restructuring it a bit so that it doesn't rely so heavily on
`eval` and dynamic scoping.  I must have sent you the resulting patch back
then (that was around the time we added it to GNU ELPA).


> ;; (let ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}"))

Try

    (dlet ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}"))

or

    (defvar hi) (defvar a) (defvar b)
    (let ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}"))

IIRC my patch changed `ee-template00` into a macro, instead, so the references
inside your string template had lexical access to the variables.


        Stefan




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

* Re: [External] : Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 22:33                 ` Eduardo Ochs
  2022-03-12 23:14                   ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-03-13  0:20                   ` Michael Heerdegen
  1 sibling, 0 replies; 48+ messages in thread
From: Michael Heerdegen @ 2022-03-13  0:20 UTC (permalink / raw)
  To: help-gnu-emacs

Eduardo Ochs <eduardoochs@gmail.com> writes:

> ;; Tests:
> ;; (ee-template00 "a{(+ 2 3)}b")
> ;; (let ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}"))
> ;;
> (defun ee-template00 (str)
>   "Replace substrings enclosed by `{}'s in STR by the result of evaluating them.
> Examples:\n
>   (ee-template00 \"a{(+ 2 3)}b\")
>     -->  \"a5b\"\n
>   (let ((hi \"Here:\") (a 22) (b 33))
>     (ee-template00 \"{hi} {a} + {b} = {(+ a b)}\"))
>     -->  \"22 + 33 = 55\""

The answer depends on how real life use cases looks like, especially
with respect to the referenced variables.

Michael.




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

* Re: [External] : Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 23:14                   ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-03-13 12:19                     ` Eduardo Ochs
  2022-03-13 23:46                       ` Stefan Monnier via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 48+ messages in thread
From: Eduardo Ochs @ 2022-03-13 12:19 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs

On Sat, 12 Mar 2022 at 21:08, Stefan Monnier via Users list for the
GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote:
>
> > Here is something that I don't know how to port to lexical binding.
> > My functions that call `ee-template00' are all defined in files with
> > "-*- lexical-binding: nil; -*-" - they don't work if I put them in
> > files with "-*- lexical-binding: t; -*-".
>
> You can make it work by sprinkling enough `defvar`, of course: often
> add `-*- lexical-binding: t; -*-` is all it takes, but sometimes you
> have to work harder.
>
> I remember battling with this code to beat it into submission by
> restructuring it a bit so that it doesn't rely so heavily on
> `eval` and dynamic scoping.  I must have sent you the resulting patch back
> then (that was around the time we added it to GNU ELPA).
>
>
> > ;; (let ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}"))
>
> Try
>
>     (dlet ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}"))
>
> or
>
>     (defvar hi) (defvar a) (defvar b)
>     (let ((hi "Here: ") (a 22) (b 33)) (ee-template00 "{hi}{a}+{b}={(+ a b)}"))
>
> IIRC my patch changed `ee-template00` into a macro, instead, so the references
> inside your string template had lexical access to the variables.


Ouch, Stefan, sorry -

when you sent me that code I misread something and I thought that it
was just an incomplete prototype... it was not, only its docs were
incomplete. I have just added it to eev with very small changes - now
people can choose between `ee-template0', that needs dynamic binding
but is easier to understand, and `ee-template0-lex', that works in
both dynamic binding and lexical binding but uses macros...

The code is here:

http://angg.twu.net/eev-current/eev-template0.el.html#ee-template0-lex

Cheers =S,
  E.



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 14:03     ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-13 16:06       ` Eric Abrahamsen
  2022-03-13 18:20         ` Steinar Bang
  0 siblings, 1 reply; 48+ messages in thread
From: Eric Abrahamsen @ 2022-03-13 16:06 UTC (permalink / raw)
  To: help-gnu-emacs

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

> Steinar Bang wrote:
>
>>> They've got a lexical-binding cookie at the top of the
>>> file, but you don't! :)
>>
>> Wait..? What...?  Huh...?
>>
>> This thing:  -*- lexical-binding: t; -*- ?
>
> Why didn't that work, you had it when you asked the question?

He didn't have it in his .emacs file.




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12 17:15           ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-13 18:11             ` Steinar Bang
  0 siblings, 0 replies; 48+ messages in thread
From: Steinar Bang @ 2022-03-13 18:11 UTC (permalink / raw)
  To: help-gnu-emacs

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

> Steinar Bang wrote:
>> I think what I meant was "should I enable lexical-binding in
>> .emacs? Or am I better off not enabling lexical-binding in
>> .emacs?"

>> And I figured "probably better off not enabling
>> lexical-binding in .emacs", and put the function in
>> a separate file.

> Enable it everywhere ...

Noted!



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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-13 16:06       ` Eric Abrahamsen
@ 2022-03-13 18:20         ` Steinar Bang
  0 siblings, 0 replies; 48+ messages in thread
From: Steinar Bang @ 2022-03-13 18:20 UTC (permalink / raw)
  To: help-gnu-emacs

>>>>> Eric Abrahamsen <eric@ericabrahamsen.net>:

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

>> Steinar Bang wrote:
>> 
>>>> They've got a lexical-binding cookie at the top of the
>>>> file, but you don't! :)

>>> Wait..? What...?  Huh...?

>>> This thing:  -*- lexical-binding: t; -*- ?

>> Why didn't that work, you had it when you asked the question?

> He didn't have it in his .emacs file.

Correct! 

This thread is where I learned about lexical-binding and emacs lisp.



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

* Re: [External] : Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-13 12:19                     ` Eduardo Ochs
@ 2022-03-13 23:46                       ` Stefan Monnier via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 48+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-03-13 23:46 UTC (permalink / raw)
  To: help-gnu-emacs

> The code is here:
>
> http://angg.twu.net/eev-current/eev-template0.el.html#ee-template0-lex

I think the fact that it works with lexical scoping is a side-efect of
the main change which is to expose the code, so things like
`flymake-mode` can warn you when you're using a variable that doesn't
exist etc...


        Stefan




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

* `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?)
  2022-03-12  6:40       ` Jean Louis
@ 2022-03-14 13:57         ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-15  7:36           ` Jean Louis
  2022-03-15 15:26           ` [External] : " Drew Adams
  2022-03-14 14:51         ` How do I pass a variable defined in a wrapping let, to a lambda? Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 2 replies; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-14 13:57 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

> New `dlet' is this and it broke my programs because somebody
> removed `let*' inside. I don't think that person who changed
> it every used `dlet' in their own programs. Reason is
> semantics, "dlet" uses "let*" so they changed it, but did
> not provide "dlet*" (though is easy to adapt it).

Okay, well, I'm not a `dlet' user myself since dynamic/special
scope isn't in my programmer's DNA ...

As for `let' vs `let*' in theory `let' is parallel and `let*'
sequential but in practice `let*' allows references back to
its own bindings, so it is recursive `let' if you will, and
`let' isn't ...

I have seen examples where `let' doesn't behave the same way
as `let*' and this is by design, those examples felt to
a large extent artificial to me tho.

I don't know, would it be a good idea to just have `let' and
that would then be the same as today's `let*'? One could keep
a `let*' alias to `let' to avoid breaking code ...

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




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

* Re: How do I pass a variable defined in a wrapping let, to a lambda?
  2022-03-12  6:40       ` Jean Louis
  2022-03-14 13:57         ` `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?) Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-14 14:51         ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 0 replies; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-14 14:51 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

> New `dlet' is this and it broke my programs because somebody
> removed `let*' inside. I don't think that person who changed
> it every used `dlet' in their own programs. Reason is
> semantics, "dlet" uses "let*" so they changed it, but did
> not provide "dlet*" (though is easy to adapt it).

So there is a `dlet', there is also a `lexical-let'

  lexical-let is a Lisp macro in ‘cl.el’.

  (lexical-let BINDINGS BODY)

  Like ‘let’, but lexically scoped.
  The main visible difference is that lambdas inside BODY will
  create lexical closures as in Common Lisp.

However ... I don't know how useful this is, especially not in
the face of `dlet' and even more so the consensus (?) that
static/lexical scope should be the default?

Also based on that the docstring is confusing since that's
what you get with `let' under static/lexical scope (at least
the closure example; I don't now if `lexical-let' is ALWAYS
static/lexical or if it allows already dynamic/special
variables just as `let' does even under static/lexical scope?
I think they are the same there as well, right?).

But/so better would be an `slet' (with an `llet' alias, or the
other way around) which is always static/lexical, a `dlet'
which is always dynamic/special, and a `let' that can be both
- static/lexical unless dynamic/special variable(s)
is/are already present with the same name(s) ...

`lexical-let' would be deprecated/obsolete which would be
stated in the docstring and by the byte-compiler, to not break
code one could alias it to `let' - not that I think think
people use it a lot, right?

Then static/lexical scope would be the default, ugly and
error-prone cookies with respect to this would be unnecessary
and all dynamic/special use would be explicit and much easier
to describe in docstrings on a function-by-function basis.

Use of dynamic/special scope would be reduced a lot since
a lot of today's use is probably due to either ignorance or
old habits of not using the cookie to set/get
static/lexical scope.

Problem solved!

Any questions?

PS. When the legendary African leader Patrice Lumumba held his
    speeches he always concluded with that question. And there
    were never any questions, because if anyone asked he was
    later beaten up by Lumumba supporters :)

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




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

* Re: `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?)
  2022-03-14 13:57         ` `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?) Emanuel Berg via Users list for the GNU Emacs text editor
@ 2022-03-15  7:36           ` Jean Louis
  2022-03-15  8:30             ` Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-15 15:26           ` [External] : " Drew Adams
  1 sibling, 1 reply; 48+ messages in thread
From: Jean Louis @ 2022-03-15  7:36 UTC (permalink / raw)
  To: help-gnu-emacs

* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2022-03-15 06:16]:
> Jean Louis wrote:
> 
> > New `dlet' is this and it broke my programs because somebody
> > removed `let*' inside. I don't think that person who changed
> > it every used `dlet' in their own programs. Reason is
> > semantics, "dlet" uses "let*" so they changed it, but did
> > not provide "dlet*" (though is easy to adapt it).
> 
> Okay, well, I'm not a `dlet' user myself since dynamic/special
> scope isn't in my programmer's DNA ...
> 
> As for `let' vs `let*' in theory `let' is parallel and `let*'
> sequential but in practice `let*' allows references back to
> its own bindings, so it is recursive `let' if you will, and
> `let' isn't ...

In the `dlet' discussion, well... I see it so, dlet is creating
dynamically bound variables, and thus they should be available to all
variables inside of `dlet"

(dlet ((first-var 1)
       (second-var first-var))
   second-var)

second-var should be equal to first var, but developer Mattias
Engdegård, he changed it for the reason that dlet is not dlet* 

>   commit b72f88518b89560accf740a4548368863e6238e0
>   Author: Mattias Engdegård <mattiase@acm.org>
>   Date:   Sun Aug 1 17:05:48 2021 +0200
  
> *     Make dlet work like let, not let*
      
> *     Change `dlet` so that it has binding semantics like `let` because that
> *     is what a user would expect and it allows a corresponding `dlet*` to
>       be added later should the need arise.  Fortunately the change has no
>       effect where it is currently used.

That is what user would expect. But that is not what I as user
expect. And nobody of other users complained on that, though the
definition of dlet is changed.

dlet is described with: Like ‘let’ but using dynamic scoping.

(dlet ((first-var 1) ;; if this is now in dynamic scoping, then:
       (second-var first-var)) ;; it should be visible 
                               ;; also in this second line
   second-var) ;; but it is not visible

Common Emacs Lisp users will get all variables from files. That is
what you do and majority of other people.

In my use case variables come from database. There are scripts in the
database that wish to access some information. 

For example there may be a template in the database asking for the
title of the page. In this below example it is `wrs::title'

<!DOCTYPE html>
<html lang="⟦ languages_extension ⟧">
  <head>
    <title>⟦ (xml-escape wrs::title) ⟧</title>
  </head>
  <body>
    ⟦ pages_content ⟧
    ⟦ after_content ⟧
    ⟦ inquiry ⟧
  </body>
</html>

Unless the variable wrs::title is dynamically bound it would not be
seen for further interpolation inside of the template. That is where
`dlet' becomes useful from within lexically scoped programs. Though I
use it with reverted modification as `rcd-dlet' so that all variables
defined within `rcd-dlet' become globally visible to other variables
in the same function.


-- 
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] 48+ messages in thread

* Re: `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?)
  2022-03-15  7:36           ` Jean Louis
@ 2022-03-15  8:30             ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-15  8:30 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

>> As for `let' vs `let*' in theory `let' is parallel and
>> `let*' sequential but in practice `let*' allows references
>> back to its own bindings, so it is recursive `let' if you
>> will, and `let' isn't ...
>
> In the `dlet' discussion, well... I see it so, dlet is
> creating dynamically bound variables, and thus they should
> be available to all variables inside of `dlet"
>
> (dlet ((first-var 1)
>        (second-var first-var))
>    second-var)
>
> second-var should be equal to first var

Well, the discussion can go both ways ...

(defvar first-var)
(setq first-var 0)

(dlet ((first-var 1)
       (second-var first-var))
    (list second-var first-var)) ; (0 1)

> but developer Mattias Engdegård, he changed it for the
> reason that dlet is not dlet*
>
>>   commit b72f88518b89560accf740a4548368863e6238e0
>>   Author: Mattias Engdegård <mattiase@acm.org>
>>   Date:   Sun Aug 1 17:05:48 2021 +0200
>>
>> *     Make dlet work like let, not let*
>>
>> *     Change `dlet` so that it has binding semantics like `let` because that
>> *     is what a user would expect and it allows a corresponding `dlet*` to
>>       be added later should the need arise.  Fortunately the change has no
>>       effect where it is currently used.
>
> That is what user would expect. But that is not what I as
> user expect. And nobody of other users complained on that,
> though the definition of dlet is changed.

If there are `let' and `let*' I think it makes sense with
`dlet' and dlet*, and slet/llet and slet*/llet*.

Don't know how much sense `let' and `let*' do tho.
Maybe someone is working on the/a true parallel `let' as we
speak ... well, keep it then I guess :)

> dlet is described with: Like ‘let’ but using
> dynamic scoping.

Poor docstring. Because `let' can do dynamic/special variables
even under static/lexical scope. Maybe one could get away with
just adding the word ALWAYS somewhere ...

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




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

* RE: [External] : `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?)
  2022-03-14 13:57         ` `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?) Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-15  7:36           ` Jean Louis
@ 2022-03-15 15:26           ` Drew Adams
  2022-03-15 15:41             ` tomas
  2022-03-15 17:16             ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 2 replies; 48+ messages in thread
From: Drew Adams @ 2022-03-15 15:26 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'

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

> would it be a good idea to just have `let' and
> that would then be the same as today's `let*'?

No.  Having both makes it clear(er) to _human_
readers when some of the bound variables might
depend on others.

Using `let' lets readers know that (at least
from the binding forms) there are no such
dependencies.  Using `let*' offers a signal
that there likely are such dependencies.

It's for us people.
___

You can do all conditional things you want
with only `cond'.  Or only `if'.  Or only
`when'.  Or only `unless'.  These multiple
constructs exist for us humans - to help
convey use/intention/purpose.

But such an advantage depends on some use
pattern that's conventional.  Same with
`let(*)'.

And whoever says you can use convention
to help convey meaning also implies that
you can mislead, by misusing or not using
convention.

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

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

* Re: [External] : `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?)
  2022-03-15 15:26           ` [External] : " Drew Adams
@ 2022-03-15 15:41             ` tomas
  2022-03-15 22:40               ` [External] : `let' vs `let*' Stefan Monnier via Users list for the GNU Emacs text editor
  2022-03-16  0:25               ` [External] : `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?) Emanuel Berg via Users list for the GNU Emacs text editor
  2022-03-15 17:16             ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 2 replies; 48+ messages in thread
From: tomas @ 2022-03-15 15:41 UTC (permalink / raw)
  To: help-gnu-emacs

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

On Tue, Mar 15, 2022 at 03:26:17PM +0000, Drew Adams wrote:
> > would it be a good idea to just have `let' and
> > that would then be the same as today's `let*'?
> 
> No.  Having both makes it clear(er) to _human_
> readers when some of the bound variables might
> depend on others.

Besides, sometimes you actually *want* that
independence (aka frozen environment). Here's
a simplistic example

  (setq a 42)
  (setq b 43)
  (let ((a b)
        (b a))
    (list a b))

  => (43 42)

Of course, a real-life example might be more complex.
And one could ask oneself whether it's wise to shadow
variables from the outer environment (the only case
which will show differences between let and let*, AFAIK).

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

* Re: [External] : `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?)
  2022-03-15 15:26           ` [External] : " Drew Adams
  2022-03-15 15:41             ` tomas
@ 2022-03-15 17:16             ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 0 replies; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-15 17:16 UTC (permalink / raw)
  To: help-gnu-emacs

Drew Adams wrote:

>> would it be a good idea to just have `let' and that would
>> then be the same as today's `let*'?
>
> No. Having both makes it clear(er) to _human_ readers when
> some of the bound variables might depend on others.
>
> Using `let' lets readers know that (at least from the
> binding forms) there are no such dependencies. Using `let*'
> offers a signal that there likely are such dependencies.
>
> It's for us people.

If so it fails for me since one of the most frequent error is
it begins with `let', then should be `let*' but I didn't
change, eval, error. I think ~1/4 of all Lisp errors is
this one?

And everyone has this error more or less frequently!

The other 3/4 errors will remain a mystery tho ...

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




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

* Re: [External] : `let' vs `let*'
  2022-03-15 15:41             ` tomas
@ 2022-03-15 22:40               ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-03-16  0:25               ` [External] : `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?) Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 0 replies; 48+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-03-15 22:40 UTC (permalink / raw)
  To: help-gnu-emacs

>   (setq a 42)
>   (setq b 43)
>   (let ((a b)
>         (b a))
>     (list a b))
>
>   => (43 42)

While you can come up with such examples, they tend to always
be contrived.  In my experience, the benefit of `let` is only really
seen in macros, where you can do:

    `(let ((x ,arg1)
           (y ,arg2)
           (f (lambda (,z) ,@body)))
       ...)

without fear of capturing an `x` that might occur inside `arg2` or `body`.
In hand-written code, having only `let*` and no `let` would make almost
no difference.


        Stefan




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

* Re: [External] : `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?)
  2022-03-15 15:41             ` tomas
  2022-03-15 22:40               ` [External] : `let' vs `let*' Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-03-16  0:25               ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 0 replies; 48+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-03-16  0:25 UTC (permalink / raw)
  To: help-gnu-emacs

Re: [External] : `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?)
tomas wrote:

>   (setq a 42)
>   (setq b 43)
>   (let ((a b)
>         (b a))
>     (list a b))
>
>   => (43 42)
>
> [...] And one could ask oneself whether it's wise to shadow
> variables from the outer environment

And the answer is: it is foolish.

So, examples are academic, and in practice it doesn't
make sense?

No:

  1. Let `let' be `let*'; and

  2. let let* be an alias to `let'.

So then we would have:
[f -> g denotes (defalias 'f #'g) ]

 obsolete/remove
       ↓
       ↓       dlet* -> dlet
       ↓        let*  -> let
lexical-let -> llet* -> llet -> let _or_ slet [note]
               slet* -> slet

[note] Both make sense: `let' by convention, and intuitive
       that the well-known let under static/lexical scope is
       llet (the lexical let); OHOH it could be alias to slet
       just as well to uphold consistency with the others, as
       dlet means ONLY dynamic/special and slet means ONLY
       static/lexical, so llet should perhaps then mean only
       static/lexical as well which then would be = slet.

`let' is/can be static/lexical AND/OR dynamical/special, the
other two means one for all dynamic/special (dlet) and one for all
static/lexical (slet).

The one.   
The mix.  
The other. 

That's All Folks!

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




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

end of thread, other threads:[~2022-03-16  0:25 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-11 22:44 How do I pass a variable defined in a wrapping let, to a lambda? Steinar Bang
2022-03-11 23:04 ` Eric Abrahamsen
2022-03-12  4:52   ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-03-12  6:08     ` Eduardo Ochs
2022-03-12 13:33       ` Stefan Monnier
2022-03-12 18:56         ` Eduardo Ochs
2022-03-12 19:12           ` Stefan Monnier
2022-03-12 20:17             ` Eduardo Ochs
2022-03-12 20:31               ` [External] : " Drew Adams
2022-03-12 22:33                 ` Eduardo Ochs
2022-03-12 23:14                   ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-03-13 12:19                     ` Eduardo Ochs
2022-03-13 23:46                       ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-03-13  0:20                   ` Michael Heerdegen
2022-03-12 20:34           ` tomas
2022-03-12  8:53     ` Steinar Bang
2022-03-12 14:47       ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-03-12 16:59         ` Steinar Bang
2022-03-12 17:15           ` Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-13 18:11             ` Steinar Bang
2022-03-12 19:09           ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-03-12 20:57             ` Steinar Bang
2022-03-12  8:51   ` Steinar Bang
2022-03-12  9:34     ` Steinar Bang
2022-03-12 19:13       ` Steinar Bang
2022-03-12 14:03     ` Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-13 16:06       ` Eric Abrahamsen
2022-03-13 18:20         ` Steinar Bang
2022-03-11 23:48 ` Eric Abrahamsen
2022-03-12  0:43   ` Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-12  0:52     ` Eric Abrahamsen
2022-03-12  1:00       ` Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-12  0:58     ` Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-12  1:37   ` Michael Heerdegen
2022-03-12  2:18     ` Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-12  6:40       ` Jean Louis
2022-03-14 13:57         ` `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?) Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-15  7:36           ` Jean Louis
2022-03-15  8:30             ` Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-15 15:26           ` [External] : " Drew Adams
2022-03-15 15:41             ` tomas
2022-03-15 22:40               ` [External] : `let' vs `let*' Stefan Monnier via Users list for the GNU Emacs text editor
2022-03-16  0:25               ` [External] : `let' vs `let*' (was: Re: How do I pass a variable defined in a wrapping let, to a lambda?) Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-15 17:16             ` Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-14 14:51         ` How do I pass a variable defined in a wrapping let, to a lambda? Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-12  2:19     ` Eric Abrahamsen
2022-03-11 23:58 ` Emanuel Berg via Users list for the GNU Emacs text editor
2022-03-12  0:47   ` 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.