* Understanding the "let" construct and the setting of variables
@ 2020-12-17 0:10 steve-humphreys
2020-12-17 0:21 ` Joost Kremers
` (2 more replies)
0 siblings, 3 replies; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 0:10 UTC (permalink / raw)
To: Help Gnu Emacs
I have been writing some elisp to set the time grid in the agenda.
The discussion progressed towards the use of the "let" construct.
But, the discussion got too advanced for me to follow the different
points of view and make a decision.
This message is for showing some examples, of how to set and use variables
in a "let", because people criticise using "setq". But discussion needs
simple examples that would not overwhelm a relative beginner.
(defun timfutur ()
(interactive)
(setq tim 845)
(setq tsk 80)
(setq thr (/ tim 100))
(setq tmn (- tim (* thr 100)))
(setq tinc_mn (+ tmn tsk))
(setq tinc_hr (/ (+ tmn tsk) 60))
(setq tinc_mn (- tinc_mn (* tinc_hr 60)) )
(setq thr_futur (* (+ thr tinc_hr) 100) )
(setq tmn_futur tinc_mn)
(setq tim_out (+ thr_futur tmn_futur))
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:10 Understanding the "let" construct and the setting of variables steve-humphreys
@ 2020-12-17 0:21 ` Joost Kremers
2020-12-17 2:08 ` steve-humphreys
` (2 more replies)
2020-12-17 0:25 ` steve-humphreys
2020-12-18 15:33 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 3 replies; 50+ messages in thread
From: Joost Kremers @ 2020-12-17 0:21 UTC (permalink / raw)
To: steve-humphreys; +Cc: help-gnu-emacs
On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> I have been writing some elisp to set the time grid in the agenda.
> The discussion progressed towards the use of the "let" construct.
>
> But, the discussion got too advanced for me to follow the different
> points of view and make a decision.
>
> This message is for showing some examples, of how to set and use variables
> in a "let", because people criticise using "setq". But discussion needs
> simple examples that would not overwhelm a relative beginner.
>
> (defun timfutur ()
> (interactive)
> (setq tim 845)
> (setq tsk 80)
>
> (setq thr (/ tim 100))
> (setq tmn (- tim (* thr 100)))
>
> (setq tinc_mn (+ tmn tsk))
> (setq tinc_hr (/ (+ tmn tsk) 60))
> (setq tinc_mn (- tinc_mn (* tinc_hr 60)) )
>
> (setq thr_futur (* (+ thr tinc_hr) 100) )
> (setq tmn_futur tinc_mn)
> (setq tim_out (+ thr_futur tmn_futur))
I'm not sure what exactly you're asking, (I'm wondering if your message is
complete or was accidentally sent before you finished it), but to understand the
problem with `setq`, evaluate your function above in the `*scratch*` buffer.
(Copy the function into the `*scratch*` buffer, put the cursor right after it
and press `C-x C-e`; note that you need to add another closing parenthesis on
the last line). That will define your function and make it available to
Emacs.
Then open a Lisp interaction buffer with `M-x ielm RET`. You'll get a buffer
called `*ielm*` with a prompt where you can type Elisp expressions that get
executed right away. Type `tim` (without parentheses) and hit RET. You should
get a void variable error:
*** Eval error *** Symbol’s value as variable is void: tim"
Then type `(timfutur)` and hit RET. You'll get the return value 1005 (displayed
also in octal and hexadecimal).
Now type `tim` again at the prompt. This time, there won't be an error anymore.
Instead you'll get the value 845.
Running your function has created a global variable `tim` (plus all the other
variables you've setq'ed), and since there are no packages or namespaces in
Elisp, your variable is now available to all of Emacs.
While I was writing this, your two questions arrived:
> 1. In what simple circumstances would one use a "setq" in the body of a let?
One common idiom would be to create or consume a list inside a loop, e.g.,
```
(let ((lst (some-function-that-produces-a-list)))
(while (some-condition-on (car lst))
(do-something-with (car lst))
(setq lst (cdr lst))))
```
Nowadays such an idiom would more often be handled with a higher-order function
of the map/reduce/filter-family, but there may be situations in which that
doesn't work.
Another example would be the case where you want to modify a value based on some
set of conditions, e.g.,:
```
(let ((x (get-some-value))
(y (get-some-other-value)))
(cond
((some-condition-on y)
(setq x (do-something-with y)))
((some-other-condition-on y)
(setq x (do-something-else-with x)))
(:otherwise
(setq y nil)))
(now-do-something-with x y))
```
You could probably rewrite this without `setq` using `let*` and some
intermediate variables, but sometimes I find using `setq` to be clearer,
especially if you have multiple values that are interdependent in complex ways.
> 2. What simple option does one have that is more advantageous than using a "setq"?
`let*` in the example function you gave above. For creating or consuming a list,
there's the map/filter/reduce-family or cl-loop.
Not sure if that makes it any easier for a relative beginner :-/ but I hope it
helps a bit anyway.
--
Joost Kremers
Life has its moments
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:10 Understanding the "let" construct and the setting of variables steve-humphreys
2020-12-17 0:21 ` Joost Kremers
@ 2020-12-17 0:25 ` steve-humphreys
2020-12-17 0:35 ` steve-humphreys
` (2 more replies)
2020-12-18 15:33 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 3 replies; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 0:25 UTC (permalink / raw)
To: steve-humphreys; +Cc: Help Gnu Emacs
Let's introspect two questions.
1. In what simple circumstances would one use a "setq" in the body of a let?
2. What simple option does one have that is more advantageous than using a "setq"?
> Sent: Thursday, December 17, 2020 at 1:10 AM
> From: steve-humphreys@gmx.com
> To: "Help Gnu Emacs" <help-gnu-emacs@gnu.org>
> Subject: Understanding the "let" construct and the setting of variables
>
> I have been writing some elisp to set the time grid in the agenda.
> The discussion progressed towards the use of the "let" construct.
>
> But, the discussion got too advanced for me to follow the different
> points of view and make a decision.
>
> This message is for showing some examples, of how to set and use variables
> in a "let", because people criticise using "setq". But discussion needs
> simple examples that would not overwhelm a relative beginner.
>
> (defun timfutur ()
> (interactive)
> (setq tim 845)
> (setq tsk 80)
>
> (setq thr (/ tim 100))
> (setq tmn (- tim (* thr 100)))
>
> (setq tinc_mn (+ tmn tsk))
> (setq tinc_hr (/ (+ tmn tsk) 60))
> (setq tinc_mn (- tinc_mn (* tinc_hr 60)) )
>
> (setq thr_futur (* (+ thr tinc_hr) 100) )
> (setq tmn_futur tinc_mn)
> (setq tim_out (+ thr_futur tmn_futur))
>
>
>
>
>
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:25 ` steve-humphreys
@ 2020-12-17 0:35 ` steve-humphreys
2020-12-17 1:05 ` Joost Kremers
2020-12-17 4:34 ` Jean Louis
2020-12-18 17:14 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 1 reply; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 0:35 UTC (permalink / raw)
To: steve-humphreys; +Cc: Help Gnu Emacs
For example, the following fails. Why? Haw can one fix the function?
(defun lett (tim tsk)
(let* ( (thr (/ tim 100))
(tmn (- tim (* thr 100)))
(tinc_mn (+ tmn tsk))
(tinc_hr (/ (+ tmn tsk) 60))
(tinc_mn (- tinc_mn (* tinc_hr 60)))
(thr_futur (* (+ thr tinc_hr) 100))
(tmn_futur tinc_mn)
(tim_out (+ thr_futur tmn_futur))
(message "%d %d" tim_out) )
(message "%s" "lett") ))
(lett 845 80)
> Sent: Thursday, December 17, 2020 at 1:25 AM
> From: steve-humphreys@gmx.com
> To: steve-humphreys@gmx.com
> Cc: "Help Gnu Emacs" <help-gnu-emacs@gnu.org>
> Subject: Re: Understanding the "let" construct and the setting of variables
>
> Let's introspect two questions.
>
> 1. In what simple circumstances would one use a "setq" in the body of a let?
> 2. What simple option does one have that is more advantageous than using a "setq"?
>
>
>
> > Sent: Thursday, December 17, 2020 at 1:10 AM
> > From: steve-humphreys@gmx.com
> > To: "Help Gnu Emacs" <help-gnu-emacs@gnu.org>
> > Subject: Understanding the "let" construct and the setting of variables
> >
> > I have been writing some elisp to set the time grid in the agenda.
> > The discussion progressed towards the use of the "let" construct.
> >
> > But, the discussion got too advanced for me to follow the different
> > points of view and make a decision.
> >
> > This message is for showing some examples, of how to set and use variables
> > in a "let", because people criticise using "setq". But discussion needs
> > simple examples that would not overwhelm a relative beginner.
> >
> > (defun timfutur ()
> > (interactive)
> > (setq tim 845)
> > (setq tsk 80)
> >
> > (setq thr (/ tim 100))
> > (setq tmn (- tim (* thr 100)))
> >
> > (setq tinc_mn (+ tmn tsk))
> > (setq tinc_hr (/ (+ tmn tsk) 60))
> > (setq tinc_mn (- tinc_mn (* tinc_hr 60)) )
> >
> > (setq thr_futur (* (+ thr tinc_hr) 100) )
> > (setq tmn_futur tinc_mn)
> > (setq tim_out (+ thr_futur tmn_futur))
> >
> >
> >
> >
> >
> >
>
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:35 ` steve-humphreys
@ 2020-12-17 1:05 ` Joost Kremers
2020-12-17 1:20 ` steve-humphreys
0 siblings, 1 reply; 50+ messages in thread
From: Joost Kremers @ 2020-12-17 1:05 UTC (permalink / raw)
To: steve-humphreys; +Cc: help-gnu-emacs
On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> For example, the following fails. Why? Haw can one fix the function?
>
> (defun lett (tim tsk)
>
> (let* ( (thr (/ tim 100))
> (tmn (- tim (* thr 100)))
>
> (tinc_mn (+ tmn tsk))
> (tinc_hr (/ (+ tmn tsk) 60))
> (tinc_mn (- tinc_mn (* tinc_hr 60)))
>
> (thr_futur (* (+ thr tinc_hr) 100))
> (tmn_futur tinc_mn)
> (tim_out (+ thr_futur tmn_futur))
>
> (message "%d %d" tim_out) )
>
> (message "%s" "lett") ))
>
> (lett 845 80)
The error is a bit cryptic, but it's telling you that you need to move the first
`message` into the body of the `let*`. Right now, it's in the list of variables
to bind, but it's not a valid binding form:
```
(defun lett (tim tsk)
(let* ((thr (/ tim 100))
(tmn (- tim (* thr 100)))
(tinc_mn (+ tmn tsk))
(tinc_hr (/ (+ tmn tsk) 60))
(tinc_mn (- tinc_mn (* tinc_hr 60)))
(thr_futur (* (+ thr tinc_hr) 100))
(tmn_futur tinc_mn)
(tim_out (+ thr_futur tmn_futur)))
(message "%d %d" tim_out)
(message "%s" "lett") ))
```
Note that this will still produce an error, because the first `message` has a
format string that requires two arguments but only one is given.
--
Joost Kremers
Life has its moments
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 1:05 ` Joost Kremers
@ 2020-12-17 1:20 ` steve-humphreys
2020-12-18 20:58 ` Emanuel Berg via Users list for the GNU Emacs text editor
0 siblings, 1 reply; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 1:20 UTC (permalink / raw)
To: Joost Kremers; +Cc: help-gnu-emacs
> Sent: Thursday, December 17, 2020 at 2:05 AM
> From: "Joost Kremers" <joostkremers@fastmail.fm>
> To: steve-humphreys@gmx.com
> Cc: help-gnu-emacs@gnu.org
> Subject: Re: Understanding the "let" construct and the setting of variables
>
>
> On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> > For example, the following fails. Why? Haw can one fix the function?
> >
> > (defun lett (tim tsk)
> >
> > (let* ( (thr (/ tim 100))
> > (tmn (- tim (* thr 100)))
> >
> > (tinc_mn (+ tmn tsk))
> > (tinc_hr (/ (+ tmn tsk) 60))
> > (tinc_mn (- tinc_mn (* tinc_hr 60)))
> >
> > (thr_futur (* (+ thr tinc_hr) 100))
> > (tmn_futur tinc_mn)
> > (tim_out (+ thr_futur tmn_futur))
> >
> > (message "%d %d" tim_out) )
> >
> > (message "%s" "lett") ))
> >
> > (lett 845 80)
>
> The error is a bit cryptic, but it's telling you that you need to move the first
> `message` into the body of the `let*`. Right now, it's in the list of variables
> to bind, but it's not a valid binding form:
>
> ```
> (defun lett (tim tsk)
>
> (let* ((thr (/ tim 100))
> (tmn (- tim (* thr 100)))
>
> (tinc_mn (+ tmn tsk))
> (tinc_hr (/ (+ tmn tsk) 60))
> (tinc_mn (- tinc_mn (* tinc_hr 60)))
>
> (thr_futur (* (+ thr tinc_hr) 100))
> (tmn_futur tinc_mn)
> (tim_out (+ thr_futur tmn_futur)))
>
> (message "%d %d" tim_out)
>
> (message "%s" "lett") ))
> ```
>
> Note that this will still produce an error, because the first `message` has a
> format string that requires two arguments but only one is given.
This means that I can use the variables in the body of the "let". Great explanation,
I fixed to. Now I need to have the function output "tim_out".
> --
> Joost Kremers
> Life has its moments
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:21 ` Joost Kremers
@ 2020-12-17 2:08 ` steve-humphreys
2020-12-17 3:12 ` steve-humphreys
2020-12-17 8:10 ` Joost Kremers
2020-12-17 2:49 ` steve-humphreys
2020-12-18 20:33 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 2 replies; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 2:08 UTC (permalink / raw)
To: Joost Kremers; +Cc: help-gnu-emacs
Finally I got some useful information (ielm). Fantastic.
ACCEPTED: Running function has created a global variable `tim` (plus all the other
variables you've setq'ed), and since there are no packages or namespaces in
Elisp, your variable is now available to all of Emacs.
QUESTION: What happens if one does a "setq" on a variable defined in the binding part of the
"let"? Can one do that?
QUESTION: What goes in the body of a "let"? I would think I can use the variables defined within
the binding section of "let".
QUESTION: Can one update a variable in the body of the "let" (the variable being defined within
the binding section of "let").
> Sent: Thursday, December 17, 2020 at 1:21 AM
> From: "Joost Kremers" <joostkremers@fastmail.fm>
> To: steve-humphreys@gmx.com
> Cc: help-gnu-emacs@gnu.org
> Subject: Re: Understanding the "let" construct and the setting of variables
>
>
> On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> > I have been writing some elisp to set the time grid in the agenda.
> > The discussion progressed towards the use of the "let" construct.
> >
> > But, the discussion got too advanced for me to follow the different
> > points of view and make a decision.
> >
> > This message is for showing some examples, of how to set and use variables
> > in a "let", because people criticise using "setq". But discussion needs
> > simple examples that would not overwhelm a relative beginner.
> >
> > (defun timfutur ()
> > (interactive)
> > (setq tim 845)
> > (setq tsk 80)
> >
> > (setq thr (/ tim 100))
> > (setq tmn (- tim (* thr 100)))
> >
> > (setq tinc_mn (+ tmn tsk))
> > (setq tinc_hr (/ (+ tmn tsk) 60))
> > (setq tinc_mn (- tinc_mn (* tinc_hr 60)) )
> >
> > (setq thr_futur (* (+ thr tinc_hr) 100) )
> > (setq tmn_futur tinc_mn)
> > (setq tim_out (+ thr_futur tmn_futur))
>
> I'm not sure what exactly you're asking, (I'm wondering if your message is
> complete or was accidentally sent before you finished it), but to understand the
> problem with `setq`, evaluate your function above in the `*scratch*` buffer.
> (Copy the function into the `*scratch*` buffer, put the cursor right after it
> and press `C-x C-e`; note that you need to add another closing parenthesis on
> the last line). That will define your function and make it available to
> Emacs.
>
> Then open a Lisp interaction buffer with `M-x ielm RET`. You'll get a buffer
> called `*ielm*` with a prompt where you can type Elisp expressions that get
> executed right away. Type `tim` (without parentheses) and hit RET. You should
> get a void variable error:
>
> *** Eval error *** Symbol’s value as variable is void: tim"
Correct. That's what I got.
> Then type `(timfutur)` and hit RET. You'll get the return value 1005 (displayed
> also in octal and hexadecimal).
Ok, got that.
--------
ELISP> (timfutur)
1005 (#o1755, #x3ed)
> Now type `tim` again at the prompt. This time, there won't be an error anymore.
> Instead you'll get the value 845.
> Running your function has created a global variable `tim` (plus all the other
> variables you've setq'ed), and since there are no packages or namespaces in
> Elisp, your variable is now available to all of Emacs.
ELISP> tim
845 (#o1515, #x34d)
> While I was writing this, your two questions arrived:
>
> > 1. In what simple circumstances would one use a "setq" in the body of a let?
>
> One common idiom would be to create or consume a list inside a loop, e.g.,
>
> ```
> (let ((lst (some-function-that-produces-a-list)))
> (while (some-condition-on (car lst))
> (do-something-with (car lst))
> (setq lst (cdr lst))))
> ```
>
> Nowadays such an idiom would more often be handled with a higher-order function
> of the map/reduce/filter-family, but there may be situations in which that
> doesn't work.
>
> Another example would be the case where you want to modify a value based on some
> set of conditions, e.g.,:
>
> ```
> (let ((x (get-some-value))
> (y (get-some-other-value)))
> (cond
> ((some-condition-on y)
> (setq x (do-something-with y)))
> ((some-other-condition-on y)
> (setq x (do-something-else-with x)))
> (:otherwise
> (setq y nil)))
> (now-do-something-with x y))
> ```
>
> You could probably rewrite this without `setq` using `let*` and some
> intermediate variables, but sometimes I find using `setq` to be clearer,
> especially if you have multiple values that are interdependent in complex ways.
>
> > 2. What simple option does one have that is more advantageous than using a "setq"?
>
> `let*` in the example function you gave above. For creating or consuming a list,
> there's the map/filter/reduce-family or cl-loop.
>
> Not sure if that makes it any easier for a relative beginner :-/ but I hope it
> helps a bit anyway.
>
>
> --
> Joost Kremers
> Life has its moments
>
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:21 ` Joost Kremers
2020-12-17 2:08 ` steve-humphreys
@ 2020-12-17 2:49 ` steve-humphreys
2020-12-17 7:58 ` Joost Kremers
2020-12-18 20:33 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 1 reply; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 2:49 UTC (permalink / raw)
To: Joost Kremers; +Cc: help-gnu-emacs
> Sent: Thursday, December 17, 2020 at 1:21 AM
> From: "Joost Kremers" <joostkremers@fastmail.fm>
> To: steve-humphreys@gmx.com
> Cc: help-gnu-emacs@gnu.org
> Subject: Re: Understanding the "let" construct and the setting of variables
>
>
> On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> > I have been writing some elisp to set the time grid in the agenda.
> > The discussion progressed towards the use of the "let" construct.
> >
> > But, the discussion got too advanced for me to follow the different
> > points of view and make a decision.
> >
> > This message is for showing some examples, of how to set and use variables
> > in a "let", because people criticise using "setq". But discussion needs
> > simple examples that would not overwhelm a relative beginner.
> >
> > (defun timfutur ()
> > (interactive)
> > (setq tim 845)
> > (setq tsk 80)
> >
> > (setq thr (/ tim 100))
> > (setq tmn (- tim (* thr 100)))
> >
> > (setq tinc_mn (+ tmn tsk))
> > (setq tinc_hr (/ (+ tmn tsk) 60))
> > (setq tinc_mn (- tinc_mn (* tinc_hr 60)) )
> >
> > (setq thr_futur (* (+ thr tinc_hr) 100) )
> > (setq tmn_futur tinc_mn)
> > (setq tim_out (+ thr_futur tmn_futur))
>
> I'm not sure what exactly you're asking, (I'm wondering if your message is
> complete or was accidentally sent before you finished it), but to understand the
> problem with `setq`, evaluate your function above in the `*scratch*` buffer.
> (Copy the function into the `*scratch*` buffer, put the cursor right after it
> and press `C-x C-e`; note that you need to add another closing parenthesis on
> the last line). That will define your function and make it available to
> Emacs.
>
> Then open a Lisp interaction buffer with `M-x ielm RET`. You'll get a buffer
> called `*ielm*` with a prompt where you can type Elisp expressions that get
> executed right away. Type `tim` (without parentheses) and hit RET. You should
> get a void variable error:
>
> *** Eval error *** Symbol’s value as variable is void: tim"
>
> Then type `(timfutur)` and hit RET. You'll get the return value 1005 (displayed
> also in octal and hexadecimal).
>
> Now type `tim` again at the prompt. This time, there won't be an error anymore.
> Instead you'll get the value 845.
>
> Running your function has created a global variable `tim` (plus all the other
> variables you've setq'ed), and since there are no packages or namespaces in
> Elisp, your variable is now available to all of Emacs.
I ran the following
ELISP> tima
(lett 845 80)
"tim_out: 1005"
ELISP> tim
*** Eval error *** Symbol’s value as variable is void: tim
ELISP> (lett 845 90)
"tim_out: 1015"
ELISP> tim
*** Eval error *** Symbol’s value as variable is void: tim
So this is quite different from using "setq". The variable "tim" is
not available to all of emacs.
------- code ------
(defun lett (tim tsk)
(let* ( (thr (/ tim 100))
(tmn (- tim (* thr 100)))
(tinc_mn (+ tmn tsk))
(tinc_hr (/ (+ tmn tsk) 60))
(tinc_mn (- tinc_mn (* tinc_hr 60)))
(thr_futur (* (+ thr tinc_hr) 100))
(tmn_futur tinc_mn)
(tim_out (+ thr_futur tmn_futur)) )
;; --- body of let ----
(message "tim_out: %d" tim_out) ))
> While I was writing this, your two questions arrived:
>
> > 1. In what simple circumstances would one use a "setq" in the body of a let?
>
> One common idiom would be to create or consume a list inside a loop, e.g.,
>
> ```
> (let ((lst (some-function-that-produces-a-list)))
> (while (some-condition-on (car lst))
> (do-something-with (car lst))
> (setq lst (cdr lst))))
> ```
>
> Nowadays such an idiom would more often be handled with a higher-order function
> of the map/reduce/filter-family, but there may be situations in which that
> doesn't work.
>
> Another example would be the case where you want to modify a value based on some
> set of conditions, e.g.,:
>
> ```
> (let ((x (get-some-value))
> (y (get-some-other-value)))
> (cond
> ((some-condition-on y)
> (setq x (do-something-with y)))
> ((some-other-condition-on y)
> (setq x (do-something-else-with x)))
> (:otherwise
> (setq y nil)))
> (now-do-something-with x y))
> ```
>
> You could probably rewrite this without `setq` using `let*` and some
> intermediate variables, but sometimes I find using `setq` to be clearer,
> especially if you have multiple values that are interdependent in complex ways.
>
> > 2. What simple option does one have that is more advantageous than using a "setq"?
>
> `let*` in the example function you gave above. For creating or consuming a list,
> there's the map/filter/reduce-family or cl-loop.
>
> Not sure if that makes it any easier for a relative beginner :-/ but I hope it
> helps a bit anyway.
>
>
> --
> Joost Kremers
> Life has its moments
>
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 2:08 ` steve-humphreys
@ 2020-12-17 3:12 ` steve-humphreys
2020-12-17 8:01 ` Joost Kremers
2020-12-17 8:10 ` Joost Kremers
1 sibling, 1 reply; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 3:12 UTC (permalink / raw)
To: steve-humphreys; +Cc: Joost Kremers, help-gnu-emacs
I want the function "lett" to return "tim_out". I understand that the last command
is the output of the function. But should this be done in the binding part or in the
body part of the "let". Or outside the "let".
(defun lett (tim tsk)
(let* ( (thr (/ tim 100))
(tmn (- tim (* thr 100)))
(tinc_mn (+ tmn tsk))
(tinc_hr (/ (+ tmn tsk) 60))
(tinc_mn (- tinc_mn (* tinc_hr 60)))
(thr_futur (* (+ thr tinc_hr) 100))
(tmn_futur tinc_mn)
(tim_out (+ thr_futur tmn_futur)) )
;; --- body of let ----
(message "tim_out: %d" tim_out) ))
> Sent: Thursday, December 17, 2020 at 3:08 AM
> From: steve-humphreys@gmx.com
> To: "Joost Kremers" <joostkremers@fastmail.fm>
> Cc: help-gnu-emacs@gnu.org
> Subject: Re: Understanding the "let" construct and the setting of variables
>
> Finally I got some useful information (ielm). Fantastic.
>
> ACCEPTED: Running function has created a global variable `tim` (plus all the other
> variables you've setq'ed), and since there are no packages or namespaces in
> Elisp, your variable is now available to all of Emacs.
>
> QUESTION: What happens if one does a "setq" on a variable defined in the binding part of the
> "let"? Can one do that?
>
> QUESTION: What goes in the body of a "let"? I would think I can use the variables defined within
> the binding section of "let".
>
> QUESTION: Can one update a variable in the body of the "let" (the variable being defined within
> the binding section of "let").
>
>
>
>
> > Sent: Thursday, December 17, 2020 at 1:21 AM
> > From: "Joost Kremers" <joostkremers@fastmail.fm>
> > To: steve-humphreys@gmx.com
> > Cc: help-gnu-emacs@gnu.org
> > Subject: Re: Understanding the "let" construct and the setting of variables
> >
> >
> > On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> > > I have been writing some elisp to set the time grid in the agenda.
> > > The discussion progressed towards the use of the "let" construct.
> > >
> > > But, the discussion got too advanced for me to follow the different
> > > points of view and make a decision.
> > >
> > > This message is for showing some examples, of how to set and use variables
> > > in a "let", because people criticise using "setq". But discussion needs
> > > simple examples that would not overwhelm a relative beginner.
> > >
> > > (defun timfutur ()
> > > (interactive)
> > > (setq tim 845)
> > > (setq tsk 80)
> > >
> > > (setq thr (/ tim 100))
> > > (setq tmn (- tim (* thr 100)))
> > >
> > > (setq tinc_mn (+ tmn tsk))
> > > (setq tinc_hr (/ (+ tmn tsk) 60))
> > > (setq tinc_mn (- tinc_mn (* tinc_hr 60)) )
> > >
> > > (setq thr_futur (* (+ thr tinc_hr) 100) )
> > > (setq tmn_futur tinc_mn)
> > > (setq tim_out (+ thr_futur tmn_futur))
> >
> > I'm not sure what exactly you're asking, (I'm wondering if your message is
> > complete or was accidentally sent before you finished it), but to understand the
> > problem with `setq`, evaluate your function above in the `*scratch*` buffer.
> > (Copy the function into the `*scratch*` buffer, put the cursor right after it
> > and press `C-x C-e`; note that you need to add another closing parenthesis on
> > the last line). That will define your function and make it available to
> > Emacs.
> >
> > Then open a Lisp interaction buffer with `M-x ielm RET`. You'll get a buffer
> > called `*ielm*` with a prompt where you can type Elisp expressions that get
> > executed right away. Type `tim` (without parentheses) and hit RET. You should
> > get a void variable error:
> >
> > *** Eval error *** Symbol’s value as variable is void: tim"
>
> Correct. That's what I got.
>
> > Then type `(timfutur)` and hit RET. You'll get the return value 1005 (displayed
> > also in octal and hexadecimal).
>
> Ok, got that.
> --------
> ELISP> (timfutur)
> 1005 (#o1755, #x3ed)
>
> > Now type `tim` again at the prompt. This time, there won't be an error anymore.
> > Instead you'll get the value 845.
>
> > Running your function has created a global variable `tim` (plus all the other
> > variables you've setq'ed), and since there are no packages or namespaces in
> > Elisp, your variable is now available to all of Emacs.
>
> ELISP> tim
> 845 (#o1515, #x34d)
>
> > While I was writing this, your two questions arrived:
> >
> > > 1. In what simple circumstances would one use a "setq" in the body of a let?
> >
> > One common idiom would be to create or consume a list inside a loop, e.g.,
> >
> > ```
> > (let ((lst (some-function-that-produces-a-list)))
> > (while (some-condition-on (car lst))
> > (do-something-with (car lst))
> > (setq lst (cdr lst))))
> > ```
> >
> > Nowadays such an idiom would more often be handled with a higher-order function
> > of the map/reduce/filter-family, but there may be situations in which that
> > doesn't work.
> >
> > Another example would be the case where you want to modify a value based on some
> > set of conditions, e.g.,:
> >
> > ```
> > (let ((x (get-some-value))
> > (y (get-some-other-value)))
> > (cond
> > ((some-condition-on y)
> > (setq x (do-something-with y)))
> > ((some-other-condition-on y)
> > (setq x (do-something-else-with x)))
> > (:otherwise
> > (setq y nil)))
> > (now-do-something-with x y))
> > ```
> >
> > You could probably rewrite this without `setq` using `let*` and some
> > intermediate variables, but sometimes I find using `setq` to be clearer,
> > especially if you have multiple values that are interdependent in complex ways.
> >
> > > 2. What simple option does one have that is more advantageous than using a "setq"?
> >
> > `let*` in the example function you gave above. For creating or consuming a list,
> > there's the map/filter/reduce-family or cl-loop.
> >
> > Not sure if that makes it any easier for a relative beginner :-/ but I hope it
> > helps a bit anyway.
> >
> >
> > --
> > Joost Kremers
> > Life has its moments
> >
> >
>
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:25 ` steve-humphreys
2020-12-17 0:35 ` steve-humphreys
@ 2020-12-17 4:34 ` Jean Louis
2020-12-17 5:12 ` steve-humphreys
` (2 more replies)
2020-12-18 17:14 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 3 replies; 50+ messages in thread
From: Jean Louis @ 2020-12-17 4:34 UTC (permalink / raw)
To: steve-humphreys; +Cc: Help Gnu Emacs
> -*- lexical-binding: t; -*-
* steve-humphreys@gmx.com <steve-humphreys@gmx.com> [2020-12-17 03:26]:
> Let's introspect two questions.
>
> 1. In what simple circumstances would one use a "setq" in the body
> of a let?
Whenever I find myself in linear programming within a function and
need to change variable I will use setq. Some global variables are
rather set with setq:
(set-buffer buffer)
(setq header-line-format (concat buffer " ➜ Finish with `q' or `h'"))
(cf-org-view-mode)
(insert blob)
(setq org-hierarchical-todo-statistics nil)
(org-update-parent-todo-statistics)
(goto-char 1)
But I will often use it in construction of lists:
(defun rcd-cgi-parse-query-string (query-string)
"Parse QUERY-STRING that normally comes from the environment
variable `QUERY_STRING'. Return PLIST."
(let* ((query-string (url-unhex-string query-string))
(parts (split-string query-string "&"))
(length (length parts))
(plist '()))
(dolist (part parts plist)
(let* ((data (split-string part "="))
(prop (car data))
(val (cadr data)))
(setq plist (plist-put plist (intern prop) val))))))
(defun iota (count &optional start step)
"Return a list containing COUNT numbers, starting from START
and adding STEP each time. The default START is 0, the default
STEP is 1"
(let* ((start (if start start 0))
(step (if step step 1))
(last (+ start count))
(counter 0)
(list '())
(elt start))
(while (< counter count)
(push elt list)
(setq elt (+ elt step))
(setq counter (1+ counter)))
(reverse list)))
How I understand it is that `setq' I can freely use on variables
already defined with and within my `let' as then the variable
will not become global.
(defun my-fun ()
(let ((my-var nil))
(setq my-var 2)))
(my-fun)
my-var is not defined
(defun my-fun ()
(let ((my-var nil)))
(setq my-var 2))
(my-fun)
my-var is here defined as 2 and became global variable.
And each time that variable is already defined with `defvar' one
can then change it with setq.
Jean
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 4:34 ` Jean Louis
@ 2020-12-17 5:12 ` steve-humphreys
2020-12-19 6:06 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-17 7:31 ` steve-humphreys
2020-12-19 5:55 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 1 reply; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 5:12 UTC (permalink / raw)
To: Jean Louis; +Cc: Help Gnu Emacs
> How I understand it is that `setq' I can freely use on variables
> already defined with and within my `let' as then the variable
> will not become global.
>
> (defun my-fun ()
> (let ((my-var nil))
> (setq my-var 2)))
>
> (my-fun)
>
> my-var is not defined
Here the variable remains local. my-var does not become a global
variable because it is defined within the let. So one can use "set"
with variables defined in a "let" construct. I thought you could not
do that - call "setq" on a local variable defined in a "let" expression.
> (defun my-fun ()
> (let ((my-var nil)))
> (setq my-var 2))
>
> (my-fun)
>
> my-var is here defined as 2 and became global variable.
>
> And each time that variable is already defined with `defvar' one
> can then change it with setq.
And here "my-var" becames a global variable because my-var is
set using "setq" outside the "let" expression.
Thanks. Was not too difficult as I thought.
> Sent: Thursday, December 17, 2020 at 5:34 AM
> From: "Jean Louis" <bugs@gnu.support>
> To: steve-humphreys@gmx.com
> Cc: "Help Gnu Emacs" <help-gnu-emacs@gnu.org>
> Subject: Re: Understanding the "let" construct and the setting of variables
>
> > -*- lexical-binding: t; -*-
> * steve-humphreys@gmx.com <steve-humphreys@gmx.com> [2020-12-17 03:26]:
> > Let's introspect two questions.
> >
> > 1. In what simple circumstances would one use a "setq" in the body
> > of a let?
>
> Whenever I find myself in linear programming within a function and
> need to change variable I will use setq. Some global variables are
> rather set with setq:
>
> (set-buffer buffer)
> (setq header-line-format (concat buffer " ➜ Finish with `q' or `h'"))
> (cf-org-view-mode)
> (insert blob)
> (setq org-hierarchical-todo-statistics nil)
> (org-update-parent-todo-statistics)
> (goto-char 1)
>
> But I will often use it in construction of lists:
>
> (defun rcd-cgi-parse-query-string (query-string)
> "Parse QUERY-STRING that normally comes from the environment
> variable `QUERY_STRING'. Return PLIST."
> (let* ((query-string (url-unhex-string query-string))
> (parts (split-string query-string "&"))
> (length (length parts))
> (plist '()))
> (dolist (part parts plist)
> (let* ((data (split-string part "="))
> (prop (car data))
> (val (cadr data)))
> (setq plist (plist-put plist (intern prop) val))))))
>
>
> (defun iota (count &optional start step)
> "Return a list containing COUNT numbers, starting from START
> and adding STEP each time. The default START is 0, the default
> STEP is 1"
> (let* ((start (if start start 0))
> (step (if step step 1))
> (last (+ start count))
> (counter 0)
> (list '())
> (elt start))
> (while (< counter count)
> (push elt list)
> (setq elt (+ elt step))
> (setq counter (1+ counter)))
> (reverse list)))
>
> How I understand it is that `setq' I can freely use on variables
> already defined with and within my `let' as then the variable
> will not become global.
>
> (defun my-fun ()
> (let ((my-var nil))
> (setq my-var 2)))
>
> (my-fun)
>
> my-var is not defined
>
> (defun my-fun ()
> (let ((my-var nil)))
> (setq my-var 2))
>
> (my-fun)
>
> my-var is here defined as 2 and became global variable.
>
> And each time that variable is already defined with `defvar' one
> can then change it with setq.
>
> Jean
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 4:34 ` Jean Louis
2020-12-17 5:12 ` steve-humphreys
@ 2020-12-17 7:31 ` steve-humphreys
2020-12-19 5:55 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 0 replies; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 7:31 UTC (permalink / raw)
To: Jean Louis; +Cc: Help Gnu Emacs
Can you be so kind to help me output tim_out from the following
function. I do not know in which construct to insert the output.
If inside the "let" variable definition area, in the body of the
"let" construct , or if outside the "let".
Regards
(defun timfutur (tim tsk)
(let* ( (thr (/ tim 100))
(tmn (- tim (* thr 100)))
(tinc_mn (+ tmn tsk))
(tinc_hr (/ (+ tmn tsk) 60))
(tinc_mn (- tinc_mn (* tinc_hr 60)))
(thr_futur (* (+ thr tinc_hr) 100))
(tmn_futur tinc_mn)
(tim_out (+ thr_futur tmn_futur)) )
;; --- body of let ----
(message "tim_out: %d" tim_out) ))
> Sent: Thursday, December 17, 2020 at 5:34 AM
> From: "Jean Louis" <bugs@gnu.support>
> To: steve-humphreys@gmx.com
> Cc: "Help Gnu Emacs" <help-gnu-emacs@gnu.org>
> Subject: Re: Understanding the "let" construct and the setting of variables
>
> > -*- lexical-binding: t; -*-
> * steve-humphreys@gmx.com <steve-humphreys@gmx.com> [2020-12-17 03:26]:
> > Let's introspect two questions.
> >
> > 1. In what simple circumstances would one use a "setq" in the body
> > of a let?
>
> Whenever I find myself in linear programming within a function and
> need to change variable I will use setq. Some global variables are
> rather set with setq:
>
> (set-buffer buffer)
> (setq header-line-format (concat buffer " ➜ Finish with `q' or `h'"))
> (cf-org-view-mode)
> (insert blob)
> (setq org-hierarchical-todo-statistics nil)
> (org-update-parent-todo-statistics)
> (goto-char 1)
>
> But I will often use it in construction of lists:
>
> (defun rcd-cgi-parse-query-string (query-string)
> "Parse QUERY-STRING that normally comes from the environment
> variable `QUERY_STRING'. Return PLIST."
> (let* ((query-string (url-unhex-string query-string))
> (parts (split-string query-string "&"))
> (length (length parts))
> (plist '()))
> (dolist (part parts plist)
> (let* ((data (split-string part "="))
> (prop (car data))
> (val (cadr data)))
> (setq plist (plist-put plist (intern prop) val))))))
>
>
> (defun iota (count &optional start step)
> "Return a list containing COUNT numbers, starting from START
> and adding STEP each time. The default START is 0, the default
> STEP is 1"
> (let* ((start (if start start 0))
> (step (if step step 1))
> (last (+ start count))
> (counter 0)
> (list '())
> (elt start))
> (while (< counter count)
> (push elt list)
> (setq elt (+ elt step))
> (setq counter (1+ counter)))
> (reverse list)))
>
> How I understand it is that `setq' I can freely use on variables
> already defined with and within my `let' as then the variable
> will not become global.
>
> (defun my-fun ()
> (let ((my-var nil))
> (setq my-var 2)))
>
> (my-fun)
>
> my-var is not defined
>
> (defun my-fun ()
> (let ((my-var nil)))
> (setq my-var 2))
>
> (my-fun)
>
> my-var is here defined as 2 and became global variable.
>
> And each time that variable is already defined with `defvar' one
> can then change it with setq.
>
> Jean
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 2:49 ` steve-humphreys
@ 2020-12-17 7:58 ` Joost Kremers
2020-12-17 16:55 ` Drew Adams
0 siblings, 1 reply; 50+ messages in thread
From: Joost Kremers @ 2020-12-17 7:58 UTC (permalink / raw)
To: steve-humphreys; +Cc: help-gnu-emacs
On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> I ran the following
>
> ELISP> tima
> (lett 845 80)
> "tim_out: 1005"
>
> ELISP> tim
> *** Eval error *** Symbol’s value as variable is void: tim
>
> ELISP> (lett 845 90)
> "tim_out: 1015"
>
> ELISP> tim
> *** Eval error *** Symbol’s value as variable is void: tim
>
> So this is quite different from using "setq". The variable "tim" is
> not available to all of emacs.
Yes, indeed. Variables bound with `let` or `let*` only exist inside the `let`.
So as soon as you put the closing parenthesis matching the opening parenthesis
directly before the `let`, the variables go out of scope and no longer exist.
(There are actually a couple of subtleties involved that make this statement
less than universally true, but those issues shouldn't concern a beginner.)
--
Joost Kremers
Life has its moments
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 3:12 ` steve-humphreys
@ 2020-12-17 8:01 ` Joost Kremers
2020-12-17 8:31 ` steve-humphreys
0 siblings, 1 reply; 50+ messages in thread
From: Joost Kremers @ 2020-12-17 8:01 UTC (permalink / raw)
To: steve-humphreys; +Cc: help-gnu-emacs
On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> I want the function "lett" to return "tim_out". I understand that the last command
> is the output of the function. But should this be done in the binding part or in the
> body part of the "let". Or outside the "let".
If `message` is in the last form in the body of the `let`, the return value of
`message` is also the return value of `let`. If `let` is the last form in the
body of the function, its return value is the return value of the function.
`message` can also be outside the body of `let`, but in that case it cannot
refer to any of the variables bound in `let`, because they are then out of scope
and no longer exist.
> (defun lett (tim tsk)
>
> (let* ( (thr (/ tim 100))
> (tmn (- tim (* thr 100)))
>
> (tinc_mn (+ tmn tsk))
> (tinc_hr (/ (+ tmn tsk) 60))
> (tinc_mn (- tinc_mn (* tinc_hr 60)))
>
> (thr_futur (* (+ thr tinc_hr) 100))
> (tmn_futur tinc_mn)
> (tim_out (+ thr_futur tmn_futur)) )
> ;; --- body of let ----
> (message "tim_out: %d" tim_out) ))
--
Joost Kremers
Life has its moments
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 2:08 ` steve-humphreys
2020-12-17 3:12 ` steve-humphreys
@ 2020-12-17 8:10 ` Joost Kremers
2020-12-17 8:43 ` steve-humphreys
2020-12-18 20:39 ` Emanuel Berg via Users list for the GNU Emacs text editor
1 sibling, 2 replies; 50+ messages in thread
From: Joost Kremers @ 2020-12-17 8:10 UTC (permalink / raw)
To: steve-humphreys; +Cc: help-gnu-emacs
On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> Finally I got some useful information (ielm). Fantastic.
>
> ACCEPTED: Running function has created a global variable `tim` (plus all the other
> variables you've setq'ed), and since there are no packages or namespaces in
> Elisp, your variable is now available to all of Emacs.
>
> QUESTION: What happens if one does a "setq" on a variable defined in the binding part of the
> "let"? Can one do that?
Yes, inside the body of the `let`, you can.
> QUESTION: What goes in the body of a "let"? I would think I can use the variables defined within
> the binding section of "let".
Yes.
> QUESTION: Can one update a variable in the body of the "let" (the variable being defined within
> the binding section of "let").
Yes, with `setq`.
--
Joost Kremers
Life has its moments
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 8:01 ` Joost Kremers
@ 2020-12-17 8:31 ` steve-humphreys
2020-12-17 8:50 ` Joost Kremers
0 siblings, 1 reply; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 8:31 UTC (permalink / raw)
To: Joost Kremers; +Cc: help-gnu-emacs
> Sent: Thursday, December 17, 2020 at 9:01 AM
> From: "Joost Kremers" <joostkremers@fastmail.fm>
> To: steve-humphreys@gmx.com
> Cc: help-gnu-emacs@gnu.org
> Subject: Re: Understanding the "let" construct and the setting of variables
>
>
> On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> > I want the function "lett" to return "tim_out". I understand that the last command
> > is the output of the function. But should this be done in the binding part or in the
> > body part of the "let". Or outside the "let".
>
> If `message` is in the last form in the body of the `let`, the return value of
> `message` is also the return value of `let`. If `let` is the last form in the
> body of the function, its return value is the return value of the function.
I do not want the function to return the "message" (tah was for testing), but the
value of tim_out. How can one return a local variable?
> `message` can also be outside the body of `let`, but in that case it cannot
> refer to any of the variables bound in `let`, because they are then out of scope
> and no longer exist.
Understood. Thank you.
> > (defun lett (tim tsk)
> >
> > (let* ( (thr (/ tim 100))
> > (tmn (- tim (* thr 100)))
> >
> > (tinc_mn (+ tmn tsk))
> > (tinc_hr (/ (+ tmn tsk) 60))
> > (tinc_mn (- tinc_mn (* tinc_hr 60)))
> >
> > (thr_futur (* (+ thr tinc_hr) 100))
> > (tmn_futur tinc_mn)
> > (tim_out (+ thr_futur tmn_futur)) )
> > ;; --- body of let ----
> > (message "tim_out: %d" tim_out) ))
>
>
> --
> Joost Kremers
> Life has its moments
>
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 8:10 ` Joost Kremers
@ 2020-12-17 8:43 ` steve-humphreys
2020-12-17 8:56 ` Joost Kremers
2020-12-18 20:46 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 20:39 ` Emanuel Berg via Users list for the GNU Emacs text editor
1 sibling, 2 replies; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 8:43 UTC (permalink / raw)
To: Joost Kremers; +Cc: help-gnu-emacs
> Sent: Thursday, December 17, 2020 at 9:10 AM
> From: "Joost Kremers" <joostkremers@fastmail.fm>
> To: steve-humphreys@gmx.com
> Cc: help-gnu-emacs@gnu.org
> Subject: Re: Understanding the "let" construct and the setting of variables
>
>
> On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> > Finally I got some useful information (ielm). Fantastic.
> >
> > ACCEPTED: Running function has created a global variable `tim` (plus all the other
> > variables you've setq'ed), and since there are no packages or namespaces in
> > Elisp, your variable is now available to all of Emacs.
> >
> > QUESTION: What happens if one does a "setq" on a variable defined in the binding part of the
> > "let"? Can one do that?
>
> Yes, inside the body of the `let`, you can.
>
> > QUESTION: What goes in the body of a "let"? I would think I can use the variables defined within
> > the binding section of "let".
>
> Yes.
>
> > QUESTION: Can one update a variable in the body of the "let" (the variable being defined within
> > the binding section of "let").
>
> Yes, with `setq`.
My mistake was that I was trying the variables using (myvar value) in the body of "let", the
same way I was doing in the binding part. That was what confused me when others iterated that
"setq" makes the variables available ta all of emacs.
This gets me to "defvar". I have read that "setq" does net actually
make a variable. It is defvar that makes a variable available.
When reading the "Intro to Emacs Lisp", the focus is on using "setq".
Do the question really is this. What happens when one sets an object with "setq"
if elisp does not make a variable from the name?
> --
> Joost Kremers
> Life has its moments
>
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 8:31 ` steve-humphreys
@ 2020-12-17 8:50 ` Joost Kremers
0 siblings, 0 replies; 50+ messages in thread
From: Joost Kremers @ 2020-12-17 8:50 UTC (permalink / raw)
To: steve-humphreys; +Cc: help-gnu-emacs
On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> I do not want the function to return the "message" (tah was for testing), but the
> value of tim_out. How can one return a local variable?
`let` returns the return value of its last body form. So simply use your
variable as the last body form. :-)
```
(let ((some-var (calculate-some-value)))
(do-some-more-stuff-with some-var)
some-var)
```
--
Joost Kremers
Life has its moments
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 8:43 ` steve-humphreys
@ 2020-12-17 8:56 ` Joost Kremers
2020-12-18 20:48 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 20:46 ` Emanuel Berg via Users list for the GNU Emacs text editor
1 sibling, 1 reply; 50+ messages in thread
From: Joost Kremers @ 2020-12-17 8:56 UTC (permalink / raw)
To: steve-humphreys; +Cc: help-gnu-emacs
On Thu, Dec 17 2020, steve-humphreys@gmx.com wrote:
> This gets me to "defvar". I have read that "setq" does net actually
> make a variable. It is defvar that makes a variable available.
`defvar` creates a global variable, yes. `setq` creates a global variable if the
variable does not exist yet. So if you do:
```
(let ((a (some-value)))
(do-something)
(setq a (some-value-based-on a))
(do-something-else))
```
Then setq updates the local binding for `a`. If you use setq on a variable that
doesn't have a local binding (i.e., isn't bound in the let that contains the
setq), it creates a new, global binding.
> Do the question really is this. What happens when one sets an object with "setq"
> if elisp does not make a variable from the name?
Not sure I understand the question. With `setq`, two things can happen: either
there is already a binding for the variable, in which case `setq` updates the
binding (assigns a new value to the existing variable), or there is no such
binding (i.e., the variable doesn't exist), and in that case the variable is created.
--
Joost Kremers
Life has its moments
^ permalink raw reply [flat|nested] 50+ messages in thread
* RE: Understanding the "let" construct and the setting of variables
2020-12-17 7:58 ` Joost Kremers
@ 2020-12-17 16:55 ` Drew Adams
2020-12-17 20:11 ` steve-humphreys
0 siblings, 1 reply; 50+ messages in thread
From: Drew Adams @ 2020-12-17 16:55 UTC (permalink / raw)
To: Joost Kremers, steve-humphreys; +Cc: help-gnu-emacs
> Yes, indeed. Variables bound with `let` or `let*` only exist inside the
> `let`.
> So as soon as you put the closing parenthesis matching the opening
> parenthesis
> directly before the `let`, the variables go out of scope and no longer exist.
> (There are actually a couple of subtleties involved that make this statement
> less than universally true, but those issues shouldn't concern a beginner.)
This is not true of dynamically scoped, i.e. "special"
vars.
What is correct to say is that the let _binding_ of the
variable no longer exists, not that the variable itself
no longer exists.
In the case of a dynamic variable, it continues to exist.
And its binding from the let continues to exist as long
as the code in the let body is executing.
[Yes, some people will consider a let binding to create
a _new_ variable. In that sense you can say that that
var ceases to exist. But IMO that isn't as clear to
users as it is to distinguish the binding from the var.
And even if you use the words that way, you still need
to point out that the var continues to exist as long as
the code within the let body is executing (when the
binding is for a dynamic var).]
The best explanation of let binding in Elisp is in the
Common Lisp doc, IMO. In particular, CLTL2's explanation
of dynamic and lexical binding is quite clear. It applies
equally to Elisp.
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: RE: Understanding the "let" construct and the setting of variables
2020-12-17 16:55 ` Drew Adams
@ 2020-12-17 20:11 ` steve-humphreys
2020-12-17 21:57 ` Drew Adams
2020-12-17 22:35 ` Michael Heerdegen
0 siblings, 2 replies; 50+ messages in thread
From: steve-humphreys @ 2020-12-17 20:11 UTC (permalink / raw)
To: Drew Adams; +Cc: Joost Kremers, help-gnu-emacs
> Sent: Thursday, December 17, 2020 at 5:55 PM
> From: "Drew Adams" <drew.adams@oracle.com>
> To: "Joost Kremers" <joostkremers@fastmail.fm>, steve-humphreys@gmx.com
> Cc: help-gnu-emacs@gnu.org
> Subject: RE: Understanding the "let" construct and the setting of variables
>
> > Yes, indeed. Variables bound with `let` or `let*` only exist inside the
> > `let`.
> > So as soon as you put the closing parenthesis matching the opening
> > parenthesis
> > directly before the `let`, the variables go out of scope and no longer exist.
> > (There are actually a couple of subtleties involved that make this statement
> > less than universally true, but those issues shouldn't concern a beginner.)
>
> This is not true of dynamically scoped, i.e. "special"
> vars.
>
> What is correct to say is that the let _binding_ of the
> variable no longer exists, not that the variable itself
> no longer exists.
>
> In the case of a dynamic variable, it continues to exist.
> And its binding from the let continues to exist as long
> as the code in the let body is executing.
>
> [Yes, some people will consider a let binding to create
> a _new_ variable. In that sense you can say that that
> var ceases to exist. But IMO that isn't as clear to
> users as it is to distinguish the binding from the var.
> And even if you use the words that way, you still need
> to point out that the var continues to exist as long as
> the code within the let body is executing (when the
> binding is for a dynamic var).]
I would thing the variable has to be made somewhere.
In fact people talk about "unboundp".
> The best explanation of let binding in Elisp is in the
> Common Lisp doc, IMO. In particular, CLTL2's explanation
> of dynamic and lexical binding is quite clear. It applies
> equally to Elisp.
>
> https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html
>
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* RE: RE: Understanding the "let" construct and the setting of variables
2020-12-17 20:11 ` steve-humphreys
@ 2020-12-17 21:57 ` Drew Adams
2020-12-17 22:35 ` Michael Heerdegen
1 sibling, 0 replies; 50+ messages in thread
From: Drew Adams @ 2020-12-17 21:57 UTC (permalink / raw)
To: steve-humphreys; +Cc: Joost Kremers, help-gnu-emacs
> > What is correct to say is that the let _binding_ of the
> > variable no longer exists, not that the variable itself
> > no longer exists.
> >
> > In the case of a dynamic variable, it continues to exist.
> > And its binding from the let continues to exist as long
> > as the code in the let body is executing.
> >
> > [Yes, some people will consider a let binding to create
> > a _new_ variable. In that sense you can say that that
> > var ceases to exist. But IMO that isn't as clear to
> > users as it is to distinguish the binding from the var.
> > And even if you use the words that way, you still need
> > to point out that the var continues to exist as long as
> > the code within the let body is executing (when the
> > binding is for a dynamic var).]
>
> I would thing the variable has to be made somewhere.
What's your point? Yes, you can think of either a variable
being created or a binding being created. In the case of a
local variable the two amount to different ways of talking
about the same thing.
But in the case of a dynamic variable, it's clearer, and
more common, to talk about a new binding to the same var
being created, rather than a new variable being created.
In particular, a dynamic variable (its latest binding) can
be accessed outside the lexical scope of the let. It's
natural to think in terms of this in terms of the same var
being bound, rebound, etc. in different ways over time.
> In fact people talk about "unboundp".
An unbound variable is a free variable with respect to
some context. If a variable has no binding in any
context then it's free/unbound at the top level.
You can use `let' to bind a variable (dynamically or
lexically). A function parameter gets bound as a local
variable when the function is called. And `defvar' and
`setq' can assign a value to a variable - that assignment
is also a binding, of sorts.
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 20:11 ` steve-humphreys
2020-12-17 21:57 ` Drew Adams
@ 2020-12-17 22:35 ` Michael Heerdegen
2020-12-18 9:01 ` tomas
1 sibling, 1 reply; 50+ messages in thread
From: Michael Heerdegen @ 2020-12-17 22:35 UTC (permalink / raw)
To: help-gnu-emacs
steve-humphreys@gmx.com writes:
> I would thing the variable has to be made somewhere.
> In fact people talk about "unboundp".
A variable can be unbound. Would be hard to call `boundp' with a
variable that doesn't exist.
Michael.
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 22:35 ` Michael Heerdegen
@ 2020-12-18 9:01 ` tomas
2020-12-18 9:16 ` Michael Heerdegen
0 siblings, 1 reply; 50+ messages in thread
From: tomas @ 2020-12-18 9:01 UTC (permalink / raw)
To: help-gnu-emacs
[-- Attachment #1: Type: text/plain, Size: 798 bytes --]
On Thu, Dec 17, 2020 at 11:35:30PM +0100, Michael Heerdegen wrote:
> steve-humphreys@gmx.com writes:
>
> > I would thing the variable has to be made somewhere.
> > In fact people talk about "unboundp".
>
> A variable can be unbound. Would be hard to call `boundp' with a
> variable that doesn't exist.
But then, you don't call `boundp' on variables. You call it on symbols.
AFAIK (but I could be wrong, corrections welcome!) there's no explicit
notion of variable in Emacs Lisp, i.e. you cah't "have" a variable
object and manipulate it directly.
That doesn't mean they don't exist -- I fancy them living in the grey
area between symbols and bindings.
Again, the Elisp manual ("12 Variables" and, linked from there, "9
Symbols") makes for a good reading.
Cheers
- t
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 9:01 ` tomas
@ 2020-12-18 9:16 ` Michael Heerdegen
2020-12-18 20:55 ` Emanuel Berg via Users list for the GNU Emacs text editor
0 siblings, 1 reply; 50+ messages in thread
From: Michael Heerdegen @ 2020-12-18 9:16 UTC (permalink / raw)
To: help-gnu-emacs
<tomas@tuxteam.de> writes:
> > > I would thing the variable has to be made somewhere.
> > > In fact people talk about "unboundp".
> >
> > A variable can be unbound. Would be hard to call `boundp' with a
> > variable that doesn't exist.
>
> But then, you don't call `boundp' on variables. You call it on
> symbols.
Yes, `boundp' is even lexical scoping agnostic, and (boundp t) ==> t,
although `t' is not very...variable.
> AFAIK (but I could be wrong, corrections welcome!) there's no explicit
> notion of variable in Emacs Lisp, i.e. you cah't "have" a variable
> object and manipulate it directly.
>
> That doesn't mean they don't exist -- I fancy them living in the grey
> area between symbols and bindings.
Well said.
Regards,
Michael.
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:10 Understanding the "let" construct and the setting of variables steve-humphreys
2020-12-17 0:21 ` Joost Kremers
2020-12-17 0:25 ` steve-humphreys
@ 2020-12-18 15:33 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 18:12 ` Jean Louis
2 siblings, 1 reply; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-18 15:33 UTC (permalink / raw)
To: help-gnu-emacs
steve-humphreys wrote:
> This message is for showing some examples, of how to set and
> use variables in a "let", because people criticise using
> "setq". But discussion needs simple examples that would not
> overwhelm a relative beginner.
On the contrary, it is very simple!
0. you are writing a `defun'...
1. start with `let'
2. if isn't enough because computation builds upon
computation, which is very common, use `let*'.
And don't be afraid to use `let's simply for code clarity.
Break up computation into small steps. But also steps that
makes sense (for the human brain). Such steps, small that
makes sense, are the best.
3. if that isn't enough to use let/let* because several
functions need to access a variable, use `setq' at the base
level (i.e., first char of the line, or column 0) - not
that Elisp has only one level, really, which is why you
should use `setq' there to avoid confusion and errors.
Because everyone can see what is created by `setq', this
should be visible in the code style as well.
Note that just because it would seem that two functions
need access to the same variable, this actually doesn't
have to be the case at all! Think it thru one extra time
before you do it.
4. If a function uses a variable that has the character of an
option, i.e. you are likely to fiddle with it back and
forth, it can make sense to break it out and use a setq.
Then you can provide it will be available to the on-line
help and, if you like, you can provide it with a docstring.
When you later fiddle with it to get it just right this
will be less error prone than if it is embedded in the
function, because then to make it come to effect, you have
to re-eval the whole function.
5. If you write single function, only this function need
a state (a memory) you can use setq for that outside the
function. But you can also do that with properties, here
[last] is an example. Bind that to, say, `C-c j'. Now,
invoke with just C-c j. But with `C-u C-c j', you set the
state, or in this case the pad-col property, to a new value
(yeah, one would guess new, otherwise why do it?) So the
next time you invoke it with just C-c j what will happen
will act upon that new state. (TBH I don't know how well it
works - I just wrote it :) - but it seems to work, I just
tried it with this [1])
So use let, then let*, then setq outside of the functions and
when you do think twice what the reason is you have to do it,
and if there really inset some other way?
Note that it isn't wrong to use setq even inside of functions
when you know what you are doing and that's what you really
intend to do and there isn't any other way to do it. It is
just that 9/10 times, there is.
[1] https://dataswamp.org/~incal/conf/mpv/input.conf
(defun pad-to-col (&optional set-new-col)
(interactive "p")
(let*((plist (symbol-plist #'pad-to-col))
(prop 'pad-col)
(pad-col (or (plist-get plist prop) 0))
(beg-col (or (current-column) 4)) )
(if (and set-new-col (= 4 set-new-col))
(progn
(plist-put plist prop beg-col)
(message "pad col set: %s" beg-col) )
(let ((step (- pad-col beg-col)))
(when (> step 0)
(insert (make-string step ?\s))
(forward-line 1)
(forward-char beg-col) )))))
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:25 ` steve-humphreys
2020-12-17 0:35 ` steve-humphreys
2020-12-17 4:34 ` Jean Louis
@ 2020-12-18 17:14 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 17:48 ` tomas
2 siblings, 1 reply; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-18 17:14 UTC (permalink / raw)
To: help-gnu-emacs
steve-humphreys wrote:
> Let's introspect two questions.
>
> 1. In what simple circumstances would one use a "setq" in
> the body of a let?
When one wants to change a global variable that already exists
outside of the function.
Try to avoid this situation altogether but if it is there, it
is there I guess, and sure, you can set it with `setq' to
whatever you want :)
> 2. What simple option does one have that is more
> advantageous than using a "setq"?
Use `let' and/or `let*' for everything else...
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 17:14 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2020-12-18 17:48 ` tomas
0 siblings, 0 replies; 50+ messages in thread
From: tomas @ 2020-12-18 17:48 UTC (permalink / raw)
To: help-gnu-emacs
[-- Attachment #1: Type: text/plain, Size: 1045 bytes --]
On Fri, Dec 18, 2020 at 06:14:04PM +0100, Emanuel Berg via Users list for the GNU Emacs text editor wrote:
> steve-humphreys wrote:
>
> > Let's introspect two questions.
> >
> > 1. In what simple circumstances would one use a "setq" in
> > the body of a let?
>
> When one wants to change a global variable that already exists
> outside of the function.
Or a local, if that has been locally bound, e.g. by a let or
a function param:
(defun collatz-sequence (n) ; [1]
(while (> n 1)
(insert (format "%5d\n" n))
(setq n (if (= (mod n 2) 0) (/ n 2) (+ (* n 3) 1)))))
(collatz-sequence 11)
=>
11
34
17
52
26
13
40
20
10
5
16
8
4
2
Yeah, the 1 at the end is missing. Left as an exercise for
the reader :)
The setq in the function's last line modifies the n which
is local to the function, because it's in the parameter
list (which is roughly equivalent to a let list).
Cheers
[1] https://en.wikipedia.org/wiki/Collatz_conjecture
- t
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 15:33 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2020-12-18 18:12 ` Jean Louis
2020-12-18 18:20 ` Drew Adams
` (2 more replies)
0 siblings, 3 replies; 50+ messages in thread
From: Jean Louis @ 2020-12-18 18:12 UTC (permalink / raw)
To: help-gnu-emacs
* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2020-12-18 18:43]:
>
> 3. if that isn't enough to use let/let* because several
> functions need to access a variable, use `setq' at the base
> level (i.e., first char of the line, or column 0) - not
> that Elisp has only one level, really, which is why you
> should use `setq' there to avoid confusion and errors.
> Because everyone can see what is created by `setq', this
> should be visible in the code style as well.
>
> Note that just because it would seem that two functions
> need access to the same variable, this actually doesn't
> have to be the case at all! Think it thru one extra time
> before you do it.
Instructions like that belong on a website where they become easily
searchable for other users to understand it.
We could index all the mailing list easily and provide search engine
for this.
^ permalink raw reply [flat|nested] 50+ messages in thread
* RE: Understanding the "let" construct and the setting of variables
2020-12-18 18:12 ` Jean Louis
@ 2020-12-18 18:20 ` Drew Adams
2020-12-18 18:45 ` Jean Louis
2020-12-18 21:27 ` Christopher Dimech
2020-12-19 6:23 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 1 reply; 50+ messages in thread
From: Drew Adams @ 2020-12-18 18:20 UTC (permalink / raw)
To: Jean Louis, help-gnu-emacs
> Instructions like that belong on a website where they become easily
> searchable for other users to understand it.
>
> We could index all the mailing list easily and provide search engine
> for this.
https://lists.gnu.org/archive/html/help-gnu-emacs/
Searching there for "Instructions like that" I get:
https://lists.gnu.org/archive/cgi-bin/namazu.cgi?query=%22Instructions+like+that%22&submit=Search%21&idxname=help-gnu-emacs&max=20&result=normal&sort=score
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 18:20 ` Drew Adams
@ 2020-12-18 18:45 ` Jean Louis
2020-12-18 19:16 ` Drew Adams
0 siblings, 1 reply; 50+ messages in thread
From: Jean Louis @ 2020-12-18 18:45 UTC (permalink / raw)
To: Drew Adams; +Cc: help-gnu-emacs
* Drew Adams <drew.adams@oracle.com> [2020-12-18 21:23]:
> > Instructions like that belong on a website where they become easily
> > searchable for other users to understand it.
> >
> > We could index all the mailing list easily and provide search engine
> > for this.
>
> https://lists.gnu.org/archive/html/help-gnu-emacs/
>
> Searching there for "Instructions like that" I get:
>
> https://lists.gnu.org/archive/cgi-bin/namazu.cgi?query=%22Instructions+like+that%22&submit=Search%21&idxname=help-gnu-emacs&max=20&result=normal&sort=score
Maybe. But I have got a feeling that is unused search. What I was
meaning but did not express it that search should be exposed to
public.
I am not sure if that namazu search engine provides good relevancy:
I found this link:
https://lists.gnu.org/archive/cgi-bin/namazu.cgi?query=emacs+float+&submit=Search%21&idxname=help-gnu-emacs&max=20&result=normal&sort=score
Then I can see there: . Re: Inconsistency: sometimes an integer,
sometimes a float
and if I search for:
inconsistency sometime integer sometimes float
https://lists.gnu.org/archive/cgi-bin/namazu.cgi?query=inconsistency+sometime+integer+sometimes+float&submit=Search%21&idxname=help-gnu-emacs&max=20&result=normal&sort=score
small mistake with "sometime" instead of "sometimes" and I do not get
any result.
Great is to have search engine. But people are not there, they are on
Reddit, stackexchange.
Would this search engine offer various hyperlinks on pages like "last
searches" by using GET method, then global search engines would index
it better.
This way I never find Emacs mailing list as one of results when I
search something related to Emacs. I find other websites.
^ permalink raw reply [flat|nested] 50+ messages in thread
* RE: Understanding the "let" construct and the setting of variables
2020-12-18 18:45 ` Jean Louis
@ 2020-12-18 19:16 ` Drew Adams
2020-12-18 20:00 ` Jean Louis
0 siblings, 1 reply; 50+ messages in thread
From: Drew Adams @ 2020-12-18 19:16 UTC (permalink / raw)
To: Jean Louis; +Cc: help-gnu-emacs
> > https://lists.gnu.org/archive/html/help-gnu-emacs
>
> Maybe. But I have got a feeling that is unused search. What I was
> meaning but did not express it that search should be exposed to
> public.
How is it not exposed to the public?
Maybe you mean it isn't advertised as well as it could be?
Feel free to advertise it. And yes, Emacs itself could
advertise it by putting it in the Help menu.
I think you've already filed an enhancement request for
adding mailing lists to the Help menu, but if you haven't:
`M-x report-emacs-bug' is the way to do that.
> Great is to have search engine. But people are not there, they are on
> Reddit, stackexchange.
Feel free to point them from there to the mailing list
and its (searchable) archive.
> This way I never find Emacs mailing list as one of results when I
> search something related to Emacs. I find other websites.
Maybe someone else can help with that. I can't.
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 19:16 ` Drew Adams
@ 2020-12-18 20:00 ` Jean Louis
0 siblings, 0 replies; 50+ messages in thread
From: Jean Louis @ 2020-12-18 20:00 UTC (permalink / raw)
To: Drew Adams; +Cc: help-gnu-emacs
* Drew Adams <drew.adams@oracle.com> [2020-12-18 22:19]:
> > > https://lists.gnu.org/archive/html/help-gnu-emacs
> >
> > Maybe. But I have got a feeling that is unused search. What I was
> > meaning but did not express it that search should be exposed to
> > public.
>
> How is it not exposed to the public?
>
> Maybe you mean it isn't advertised as well as it could be?
> Feel free to advertise it. And yes, Emacs itself could
> advertise it by putting it in the Help menu.
Official Emacs website points out to various other official Emacs
related resources:
https://www.gnu.org/software/emacs/documentation.html
But who will watch the website? Just small number of actual
users. Emacs is by my feeling just installed as part of GNU/Linux
system by the OS package manager.
From Emacs itself it is harder to find Emacs website, I do not even
know how. How will users find mailing lists from within Emacs?
> I think you've already filed an enhancement request for
> adding mailing lists to the Help menu, but if you haven't:
> `M-x report-emacs-bug' is the way to do that.
Yes, who knows if it will be implemented, it requires consensus,
reviews, judgments, discussions.
> > Great is to have search engine. But people are not there, they are on
> > Reddit, stackexchange.
>
> Feel free to point them from there to the mailing list
> and its (searchable) archive.
A curated index that points to various messages and answers some
common questions is useful to be published on static pages as that
would be picked up by search engines.
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 0:21 ` Joost Kremers
2020-12-17 2:08 ` steve-humphreys
2020-12-17 2:49 ` steve-humphreys
@ 2020-12-18 20:33 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 0 replies; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-18 20:33 UTC (permalink / raw)
To: help-gnu-emacs
Joost Kremers wrote:
> I'm not sure what exactly you're asking, (I'm wondering if
> your message is complete or was accidentally sent before you
> finished it), but to understand the problem with `setq`,
> evaluate your function above in the `*scratch*` buffer.
> (Copy the function into the `*scratch*` buffer, put the
> cursor right after it and press `C-x C-e`; note that you
> need to add another closing parenthesis on the last line).
> That will define your function and make it available
> to Emacs.
>
> Then open a Lisp interaction buffer with `M-x ielm RET`.
> You'll get a buffer called `*ielm*` with a prompt where you
> can type Elisp expressions that get executed right away.
> Type `tim` (without parentheses) and hit RET. You should get
> a void variable error:
>
> *** Eval error *** Symbol’s value as variable is void:
> tim"
You (the OP) can also just keep it in the elisp-mode buffer
where it was written, eval it (as you say) and then just
invoke it interactively (with M-x) or from Lisp, to test it
that way. One way to do it from Lisp is again to stay in the
same file, just add a commented out line after the function
;; (some-function test-var-1 test-var-2)
and the eval that.
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 8:10 ` Joost Kremers
2020-12-17 8:43 ` steve-humphreys
@ 2020-12-18 20:39 ` Emanuel Berg via Users list for the GNU Emacs text editor
1 sibling, 0 replies; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-18 20:39 UTC (permalink / raw)
To: help-gnu-emacs
Joost Kremers wrote:
>> QUESTION: What happens if one does a "setq" on a variable
>> defined in the binding part of the "let"? Can one do that?
>
> Yes, inside the body of the `let`, you can.
You can, but it isn't optimal because if you make a typo you
will be unaware of it and instead a global variable will
silently be created. If it already exist, oh, my you will
modify that instead of the intended let binding variable.
So better to do all computation you reasonably can _before_
the let body, already in the varlist.
Use several steps with `let*' and add supposedly unnecessary
steps for clarity, better access and easier debug.
In the let body, optimally, all computation is already done.
There, you just _do_ whatever it is should happen, using the
values you already have for the purpose.
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 8:43 ` steve-humphreys
2020-12-17 8:56 ` Joost Kremers
@ 2020-12-18 20:46 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 21:07 ` Jean Louis
2020-12-18 22:31 ` tomas
1 sibling, 2 replies; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-18 20:46 UTC (permalink / raw)
To: help-gnu-emacs
steve-humphreys wrote:
> This gets me to "defvar". I have read that "setq" does net
> actually make a variable. It is defvar that makes a variable
> available. When reading the "Intro to Emacs Lisp", the focus
> is on using "setq".
`setq' is enough, it does the real job alright, but the
byte-compiler will complain if there isn't a `defvar'
before it.
Also with defvar you can set a default value and add
a docstring. None of that is mandatory and the default value
can even be confusing IMO.
Just think of defvar as a way of telling Emacs and everyone
else, "I intend to use a variable with this name."
This is enough, and always do it (_at least_ do that, of
course by all means set the default and add a docstring if
that fancies you), but always and at least do this:
(defvar some-var)
(setq some-var some-value)
That's enough. You have what you need and the byte-compiler
doesn't complain.
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 8:56 ` Joost Kremers
@ 2020-12-18 20:48 ` Emanuel Berg via Users list for the GNU Emacs text editor
0 siblings, 0 replies; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-18 20:48 UTC (permalink / raw)
To: help-gnu-emacs
Joost Kremers wrote:
> Not sure I understand the question. With `setq`, two things
> can happen: either there is already a binding for the
> variable, in which case `setq` updates the binding (assigns
> a new value to the existing variable), or there is no such
> binding (i.e., the variable doesn't exist), and in that case
> the variable is created.
That's right, so use `setq' to create and manipulate global
variables; inside functions, use `let/let*'.
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 9:16 ` Michael Heerdegen
@ 2020-12-18 20:55 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-19 2:17 ` Michael Heerdegen
0 siblings, 1 reply; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-18 20:55 UTC (permalink / raw)
To: help-gnu-emacs
Michael Heerdegen wrote:
> Yes, `boundp' is even lexical scoping agnostic, and (boundp
> t) ==> t, although `t' is not very...variable.
Try `defalias' 't to #'some-function...
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 1:20 ` steve-humphreys
@ 2020-12-18 20:58 ` Emanuel Berg via Users list for the GNU Emacs text editor
0 siblings, 0 replies; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-18 20:58 UTC (permalink / raw)
To: help-gnu-emacs
steve-humphreys wrote:
> This means that I can use the variables in the body of the
> "let".
... I mean, yeah, that's the purpose of `let'! That, and to do
computation already in the varlist, to prepare and adapt for
what should happen in the body.
Now we are talking normal everyday programming at a basic
level, or "lexical scope" to some people :)
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 20:46 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2020-12-18 21:07 ` Jean Louis
2020-12-18 22:31 ` tomas
1 sibling, 0 replies; 50+ messages in thread
From: Jean Louis @ 2020-12-18 21:07 UTC (permalink / raw)
To: help-gnu-emacs
* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2020-12-18 23:48]:
> (defvar some-var)
> (setq some-var some-value)
Instead I use (defvar some-var some-value "doc")
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 18:12 ` Jean Louis
2020-12-18 18:20 ` Drew Adams
@ 2020-12-18 21:27 ` Christopher Dimech
2020-12-19 6:23 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 0 replies; 50+ messages in thread
From: Christopher Dimech @ 2020-12-18 21:27 UTC (permalink / raw)
To: Jean Louis; +Cc: help-gnu-emacs
> Sent: Friday, December 18, 2020 at 7:12 PM
> From: "Jean Louis" <bugs@gnu.support>
> To: help-gnu-emacs@gnu.org
> Subject: Re: Understanding the "let" construct and the setting of variables
>
> * Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2020-12-18 18:43]:
> >
> > 3. if that isn't enough to use let/let* because several
> > functions need to access a variable, use `setq' at the base
> > level (i.e., first char of the line, or column 0) - not
> > that Elisp has only one level, really, which is why you
> > should use `setq' there to avoid confusion and errors.
> > Because everyone can see what is created by `setq', this
> > should be visible in the code style as well.
> >
> > Note that just because it would seem that two functions
> > need access to the same variable, this actually doesn't
> > have to be the case at all! Think it thru one extra time
> > before you do it.
>
> Instructions like that belong on a website where they become easily
> searchable for other users to understand it.
>
> We could index all the mailing list easily and provide search engine
> for this.
Right, we've got some real hot shit on this mailing list. Very good.
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 20:46 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 21:07 ` Jean Louis
@ 2020-12-18 22:31 ` tomas
1 sibling, 0 replies; 50+ messages in thread
From: tomas @ 2020-12-18 22:31 UTC (permalink / raw)
To: help-gnu-emacs
[-- Attachment #1: Type: text/plain, Size: 488 bytes --]
On Fri, Dec 18, 2020 at 09:46:38PM +0100, Emanuel Berg via Users list for the GNU Emacs text editor wrote:
> steve-humphreys wrote:
>
> > This gets me to "defvar" [...]
> Just think of defvar as a way of telling Emacs and everyone
> else, "I intend to use a variable with this name."
Especially the "everyone else" part. You use defvar especially
when you want your package's users "hey, here is a knob you
can tweak to adjust the package to your needs...".
Cheers
- t
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 20:55 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2020-12-19 2:17 ` Michael Heerdegen
2020-12-19 2:52 ` Drew Adams
2020-12-19 5:15 ` Stefan Monnier
0 siblings, 2 replies; 50+ messages in thread
From: Michael Heerdegen @ 2020-12-19 2:17 UTC (permalink / raw)
To: help-gnu-emacs
Emanuel Berg via Users list for the GNU Emacs text editor
<help-gnu-emacs@gnu.org> writes:
> Try `defalias' 't to #'some-function...
There is a sanity check in `fset' but it doesn't catch this case.
It would sometimes be cool if one could funbind some constants, e.g.
t -> (lambda (&rest _) t)
nil -> #'ignore
1 -> #'identity
but that would produce a big mess, it is probably no option in Emacs
Lisp.
Regards,
Michael.
^ permalink raw reply [flat|nested] 50+ messages in thread
* RE: Understanding the "let" construct and the setting of variables
2020-12-19 2:17 ` Michael Heerdegen
@ 2020-12-19 2:52 ` Drew Adams
2020-12-19 5:15 ` Stefan Monnier
1 sibling, 0 replies; 50+ messages in thread
From: Drew Adams @ 2020-12-19 2:52 UTC (permalink / raw)
To: Michael Heerdegen, help-gnu-emacs
> but that would produce a big mess, it is probably
> no option in Emacs Lisp.
There are of course innumerable other ways Elisp
lets you tie yourself in knots or shoot yourself
in the foot. It even excels at that.
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-19 2:17 ` Michael Heerdegen
2020-12-19 2:52 ` Drew Adams
@ 2020-12-19 5:15 ` Stefan Monnier
1 sibling, 0 replies; 50+ messages in thread
From: Stefan Monnier @ 2020-12-19 5:15 UTC (permalink / raw)
To: help-gnu-emacs
> t -> (lambda (&rest _) t)
(fset t (lambda (&rest _) t))
seems to work fine here.
> nil -> #'ignore
This one does signal an error in `fset`. We could lift this error of
course, but then we find other problems because nil is used as the
marker that a function is "unbound", so subsequent calls to nil
fail anyway.
> 1 -> #'identity
Here the problem is that 1 is not a symbol. You can do
(fset '\1 #'identity)
tho, after which
(\1 42)
returns 42.
Stefan
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 4:34 ` Jean Louis
2020-12-17 5:12 ` steve-humphreys
2020-12-17 7:31 ` steve-humphreys
@ 2020-12-19 5:55 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-19 6:49 ` Jean Louis
2 siblings, 1 reply; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-19 5:55 UTC (permalink / raw)
To: help-gnu-emacs
Jean Louis wrote:
> But I will often use it in construction of lists
I think you can avoid using `setq' with lists, strings etc in
loops by using `cl-loop' with accumulation.
In the docstring, it says:
[...]
Accumulation clauses:
collect/append/nconc/concat/vconcat/count/sum/maximize/minimize FORM
[into VAR]
Try it :)
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-17 5:12 ` steve-humphreys
@ 2020-12-19 6:06 ` Emanuel Berg via Users list for the GNU Emacs text editor
0 siblings, 0 replies; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-19 6:06 UTC (permalink / raw)
To: help-gnu-emacs
steve-humphreys wrote:
> Here the variable remains local. my-var does not become
> a global variable because it is defined within the let.
> So one can use "set" with variables defined in a "let"
> construct. I thought you could not do that - call "setq" on
> a local variable defined in a "let" expression.
But often it isn't needed.
>> (defun my-fun ()
>> (let ((my-var nil)))
>> (setq my-var 2))
>>
>> (my-fun)
>>
>> my-var is here defined as 2 and became global variable.
>>
>> And each time that variable is already defined with `defvar' one
>> can then change it with setq.
>
> And here "my-var" becames a global variable because my-var
> is set using "setq" outside the "let" expression.
Yes, but here lies the problem and danger with using `setq'
within `let/let*', because that will also create a global
variable if it isn't in the let varlist already.
Everything is global in Elisp BTW except the stuff you'll find
for example within special forms like `let'. That's another
reason you ought to use them as often as you can, to
encapsulate all the little pieces, to hide the machinery from
the rest of the world and only present a clean and
easily defined/understood interface.
f(x) = y
so tell everyone, give f x and you'll get y. But how that
happens, how y is computed from x, is f's business and there
is no need, actually it should be avoided, there is no need to
clutter the global space with stuff that only concerns f.
Note that this mathematical example doesn't have to be math.
It can be a Quake game, or whatever. Quake, which is based on
linear algebra and spatial geometry. OK, bad example.
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-18 18:12 ` Jean Louis
2020-12-18 18:20 ` Drew Adams
2020-12-18 21:27 ` Christopher Dimech
@ 2020-12-19 6:23 ` Emanuel Berg via Users list for the GNU Emacs text editor
2 siblings, 0 replies; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-19 6:23 UTC (permalink / raw)
To: help-gnu-emacs
Jean Louis (and I) wrote:
>> 3. if that isn't enough to use let/let* because several
>> functions need to access a variable, use `setq' at the
>> base level (i.e., first char of the line, or column 0) -
>> not that Elisp has only one level, really, which is why
That should be NOTE, not "not". By that I mean a file, even
a package does not have its own namespace. Everything defined
is accessible from everywhere.
>> you should use `setq' there to avoid confusion and
>> errors. Because everyone can see what is created by
>> `setq', this should be visible in the code style
>> as well.
By this I mean, do it like this:
(defvar some-var)
(setq some-var some-value)
Joe Elisp Hacker then immediately thinks, "alright, a global
var". And he'd be right!
But do it like this:
(defun some-function ()
(setq some-var some-value) )
it is "hm, is this a global variable? it could be, if the
function was called. was it? or did the programmer forgot to
put it in the let varlist? is it thus a bug? or is it defined
in some other file? or [etc]"
so to remove all doubt, create global vars like the first
example. And do this only when let for some specific reason
isn't enough.
> Instructions like that belong on a website where they become
> easily searchable for other users to understand it.
Yeah, but to be honest ... don't everyone know that you should
avoid global variables? I think that was among the first thing
I learned as a programmer at age 12 or something (and I was
truly a _horrible_ programmer then, and it didn't stop at 12 -
but yeah, how could one be anything else at that point...).
But everyone should understand it, really. It is just like
putting gear in a toolbox. One box for fishing gear and one
for bike repairs (yep, that'd be a big one). And nothing that
has to do with fishing or bikes just lying around on the
floor, for every goofball that treads it to trip on or pick up
and fiddle with...
> We could index all the mailing list easily and provide
> search engine for this.
Well, they are archived and searchable, of course! See:
http://lists.gnu.org/archive/html/help-gnu-emacs/
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-19 5:55 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2020-12-19 6:49 ` Jean Louis
2020-12-20 5:19 ` Emanuel Berg via Users list for the GNU Emacs text editor
0 siblings, 1 reply; 50+ messages in thread
From: Jean Louis @ 2020-12-19 6:49 UTC (permalink / raw)
To: help-gnu-emacs
* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2020-12-19 08:56]:
> Jean Louis wrote:
>
> > But I will often use it in construction of lists
>
> I think you can avoid using `setq' with lists, strings etc in
> loops by using `cl-loop' with accumulation.
I am avoiding cl functions by principle to make it easier. It does not
matter.
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: Understanding the "let" construct and the setting of variables
2020-12-19 6:49 ` Jean Louis
@ 2020-12-20 5:19 ` Emanuel Berg via Users list for the GNU Emacs text editor
0 siblings, 0 replies; 50+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2020-12-20 5:19 UTC (permalink / raw)
To: help-gnu-emacs
Jean Louis wrote:
>> I think you can avoid using `setq' with lists, strings etc
>> in loops by using `cl-loop' with accumulation.
>
> I am avoiding cl functions by principle to make it easier.
> It does not matter.
They are very useful. I've used 24 of them, 86 times :)
It is not really CL. cl-lib.el is in Elisp. So the cl- prefix
is nothing to be afraid of, on the contrary it's great
stuff :)
Some of the stuff I don't know why I used tho, cl-caddr for
example. Because there is a caddr, in subr.el...
cl-caddr
cl-case
cl-concatenate
cl-defun
cl-digit-char-p
cl-dolist
cl-find-if
cl-first
cl-gensym
cl-incf
cl-labels
cl-lib
cl-loop
cl-map
cl-mapcan
cl-mapcar
cl-position
cl-pushnew
cl-remove
cl-remove-if-not
cl-return
cl-set-exclusive-or
cl-sort
cl-subseq
--
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal
^ permalink raw reply [flat|nested] 50+ messages in thread
end of thread, other threads:[~2020-12-20 5:19 UTC | newest]
Thread overview: 50+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-17 0:10 Understanding the "let" construct and the setting of variables steve-humphreys
2020-12-17 0:21 ` Joost Kremers
2020-12-17 2:08 ` steve-humphreys
2020-12-17 3:12 ` steve-humphreys
2020-12-17 8:01 ` Joost Kremers
2020-12-17 8:31 ` steve-humphreys
2020-12-17 8:50 ` Joost Kremers
2020-12-17 8:10 ` Joost Kremers
2020-12-17 8:43 ` steve-humphreys
2020-12-17 8:56 ` Joost Kremers
2020-12-18 20:48 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 20:46 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 21:07 ` Jean Louis
2020-12-18 22:31 ` tomas
2020-12-18 20:39 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-17 2:49 ` steve-humphreys
2020-12-17 7:58 ` Joost Kremers
2020-12-17 16:55 ` Drew Adams
2020-12-17 20:11 ` steve-humphreys
2020-12-17 21:57 ` Drew Adams
2020-12-17 22:35 ` Michael Heerdegen
2020-12-18 9:01 ` tomas
2020-12-18 9:16 ` Michael Heerdegen
2020-12-18 20:55 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-19 2:17 ` Michael Heerdegen
2020-12-19 2:52 ` Drew Adams
2020-12-19 5:15 ` Stefan Monnier
2020-12-18 20:33 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-17 0:25 ` steve-humphreys
2020-12-17 0:35 ` steve-humphreys
2020-12-17 1:05 ` Joost Kremers
2020-12-17 1:20 ` steve-humphreys
2020-12-18 20:58 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-17 4:34 ` Jean Louis
2020-12-17 5:12 ` steve-humphreys
2020-12-19 6:06 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-17 7:31 ` steve-humphreys
2020-12-19 5:55 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-19 6:49 ` Jean Louis
2020-12-20 5:19 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 17:14 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 17:48 ` tomas
2020-12-18 15:33 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-18 18:12 ` Jean Louis
2020-12-18 18:20 ` Drew Adams
2020-12-18 18:45 ` Jean Louis
2020-12-18 19:16 ` Drew Adams
2020-12-18 20:00 ` Jean Louis
2020-12-18 21:27 ` Christopher Dimech
2020-12-19 6:23 ` Emanuel Berg via Users list for the GNU Emacs text editor
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).