unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#59333: [PATCH] Define macro dlet*
@ 2022-11-17  7:13 daanturo
  2022-11-17  7:25 ` Eli Zaretskii
  2022-11-19  4:47 ` Jean Louis
  0 siblings, 2 replies; 10+ messages in thread
From: daanturo @ 2022-11-17  7:13 UTC (permalink / raw)
  To: 59333

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

--=-=-=
Content-Type: text/plain

Tags: patch


The dlet breakage comes as much surprise to me. There's not even a
single entry in NEWS that mentions it.

I would rather prefer b72f88518b89560accf740a4548368863e6238e0 be
reverted, though. But maybe that's fine if the majority of maintainers
agree with that change. But please mention similar breakages more
universally.



In GNU Emacs 29.0.50 (build 2, x86_64-pc-linux-gnu, GTK+ Version
3.24.34, cairo version 1.17.6) of 2022-11-13 built on dan-laptop
Repository revision: b806e8a8a2c7d01a18f11e6582961c42a9eecc01
Repository branch: makepkg
System Description: Arch Linux

Configured using:
'configure --sysconfdir=/etc --prefix=/usr --libexecdir=/usr/lib
--localstatedir=/var
'--program-transform-name=s/\([ec]tags\)/\1.emacs/' --with-json
--with-libsystemd --with-mailutils --with-modules --with-pgtk
--without-xaw3d --with-sound=alsa --with-xinput2 --with-xwidgets
--without-compress-install --with-native-compilation=aot
--with-tree-sitter 'CFLAGS=-march=native -O2 -pipe -fno-plt
-fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security
-fstack-clash-protection -fcf-protection'
LDFLAGS=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now'

--=-=-=--

-- 
Daanturo.

[-- Attachment #2: 0001-Define-macro-dlet-star.patch --]
[-- Type: text/x-patch, Size: 2801 bytes --]

From cf4dba3899eef0a88bf4032bec5cf45c56a77077 Mon Sep 17 00:00:00 2001
From: Daanturo <daanturo@gmail.com>
Date: Thu, 17 Nov 2022 13:57:20 +0700
Subject: [PATCH] Define macro dlet*

* lisp/subr.el: implementation.
* doc/lispref/variables.texi: documentation.
* etc/NEWS: announce it, also add dlet's non-backward compatible
breakage.
---
 doc/lispref/variables.texi |  8 ++++++++
 etc/NEWS                   | 10 ++++++++++
 lisp/subr.el               |  8 ++++++++
 3 files changed, 26 insertions(+)

diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index 7206f2acd2..c574ffaf09 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -303,6 +303,14 @@ Binding}), but it's impractical to @code{defvar} these variables.
 the forms, and then make the variables non-special again.
 @end defspec
 
+@defspec dlet* (bindings@dots{}) forms@dots{}
+This form is like @code{dlet}, but each valueform can refer to the
+symbols already bound previously, like what @code{let*} is to
+@code{let} (actually this is Emacs 28's old @code{dlet}, as from Emacs
+29 it no longer let bindings refer to the preceding symbols in this
+same form).
+@end defspec
+
 @defspec named-let name bindings &rest body
 This special form is a looping construct inspired from the
 Scheme language.  It is similar to @code{let}: It binds the variables in
diff --git a/etc/NEWS b/etc/NEWS
index 0b8f4539f9..1e9b1ce279 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2913,6 +2913,10 @@ when visiting JSON files.
 \f
 * Incompatible Lisp Changes in Emacs 29.1
 
++++
+** dlet now uses let internally instead of let*.
+---
+
 +++
 ** 'format-prompt' now uses 'substitute-command-keys'.
 This means that both the prompt and 'minibuffer-default-prompt-format'
@@ -3269,6 +3273,12 @@ The following generalized variables have been made obsolete:
 \f
 * Lisp Changes in Emacs 29.1
 
+
++++
+** New macro 'dlet*'.
+Like what 'let*' is to 'let', functionally identical to the old 'dlet'
+in Emacs 28.
+
 +++
 ** Interpreted closures are "safe for space".
 As was already the case for byte-compiled closures, instead of capturing
diff --git a/lisp/subr.el b/lisp/subr.el
index 6b83196d05..ddc48b554e 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2155,6 +2155,14 @@ all symbols are bound before any of the VALUEFORMs are evalled."
                binders)
      (let ,binders ,@body)))
 
+(defmacro dlet* (binders &rest body)
+  "Like `let*' but using dynamic scoping."
+  (declare (indent 1) (debug let))
+  `(let (_)
+     ,@(mapcar (lambda (binder)
+                 `(defvar ,(if (consp binder) (car binder) binder)))
+               binders)
+     (let ,binders ,@body)))
 
 (defmacro with-wrapper-hook (hook args &rest body)
   "Run BODY, using wrapper functions from HOOK with additional ARGS.
-- 
2.38.1


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

* bug#59333: [PATCH] Define macro dlet*
  2022-11-17  7:13 bug#59333: [PATCH] Define macro dlet* daanturo
@ 2022-11-17  7:25 ` Eli Zaretskii
  2022-11-17  7:40   ` Daan Ro
                     ` (2 more replies)
  2022-11-19  4:47 ` Jean Louis
  1 sibling, 3 replies; 10+ messages in thread
From: Eli Zaretskii @ 2022-11-17  7:25 UTC (permalink / raw)
  To: daanturo, Stefan Monnier, Mattias Engdegård; +Cc: 59333

> Date: Thu, 17 Nov 2022 14:13:35 +0700
> From: daanturo <daanturo@gmail.com>
> 
> The dlet breakage comes as much surprise to me. There's not even a
> single entry in NEWS that mentions it.

dlet was new in Emacs 28, and the change you mention was done before
Emacs 28 was released.  So NEWS just mentions the introduction of
dlet, and that is enough.

> I would rather prefer b72f88518b89560accf740a4548368863e6238e0 be
> reverted, though. But maybe that's fine if the majority of maintainers
> agree with that change. But please mention similar breakages more
> universally.

I can only understand the breakage if someone picked up dlet as
originally implemented on master, before Emacs 28 was released.  In
that case, it's the risk people take when they follow the development
code too closely.

As for the patch, I'd like to hear opinions about the need for dlet*.

Thanks.





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

* bug#59333: [PATCH] Define macro dlet*
  2022-11-17  7:25 ` Eli Zaretskii
@ 2022-11-17  7:40   ` Daan Ro
  2022-11-19  4:37     ` Jean Louis
  2022-11-17 13:22   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2022-11-19  4:28   ` Jean Louis
  2 siblings, 1 reply; 10+ messages in thread
From: Daan Ro @ 2022-11-17  7:40 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 59333

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

> dlet was new in Emacs 28, and the change you mention was done before
> Emacs 28 was released.  So NEWS just mentions the introduction of
> dlet, and that is enough.

Sorry it was my fault for not paying attention to the commit year (I thought
that was August this year).

Therefore reverting it now must not be an option.

But I think let* is more useful than let in general for programming, as it
let
us create successive bindings and transform the flow of data, like the
natural
flow of thought.

[-- Attachment #2: Type: text/html, Size: 569 bytes --]

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

* bug#59333: [PATCH] Define macro dlet*
  2022-11-17  7:25 ` Eli Zaretskii
  2022-11-17  7:40   ` Daan Ro
@ 2022-11-17 13:22   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2022-11-17 13:36     ` Mattias Engdegård
  2022-11-19  4:28   ` Jean Louis
  2 siblings, 1 reply; 10+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-11-17 13:22 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Mattias Engdegård, 59333, daanturo

> As for the patch, I'd like to hear opinions about the need for dlet*.

Currently I see very few uses of `dlet`, so adding `dlet*`
seems overkill.


        Stefan






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

* bug#59333: [PATCH] Define macro dlet*
  2022-11-17 13:22   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2022-11-17 13:36     ` Mattias Engdegård
  2022-11-25  0:14       ` Stefan Kangas
  0 siblings, 1 reply; 10+ messages in thread
From: Mattias Engdegård @ 2022-11-17 13:36 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Eli Zaretskii, 59333, daanturo

17 nov. 2022 kl. 14.22 skrev Stefan Monnier <monnier@iro.umontreal.ca>:

> Currently I see very few uses of `dlet`, so adding `dlet*`
> seems overkill.

I concur. (The proposed patch also appears incorrect, and lacks a test.)
Anyone really needing a `dlet*` macro can easily implement one in terms of `dlet`.






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

* bug#59333: [PATCH] Define macro dlet*
  2022-11-17  7:25 ` Eli Zaretskii
  2022-11-17  7:40   ` Daan Ro
  2022-11-17 13:22   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2022-11-19  4:28   ` Jean Louis
  2 siblings, 0 replies; 10+ messages in thread
From: Jean Louis @ 2022-11-19  4:28 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Mattias Engdegård, 59333, daanturo, Stefan Monnier

* Eli Zaretskii <eliz@gnu.org> [2022-11-17 10:27]:
> I can only understand the breakage if someone picked up dlet as
> originally implemented on master, before Emacs 28 was released.  In
> that case, it's the risk people take when they follow the development
> code too closely.

Since I found it volatile in development, I have renamed it in my
personal packages to `rcd-dlet'.

My packages are with lexical binding. `dlet' is inevitable part of
template interpolation which is used to generate thousands of Internet
pages, e-mails, and too many PDf documents.

hyperscope.el:3113:	 (text (rcd-dlet ((hs::id id)
hyperscope.el:4515:    (rcd-dlet ((rcd::lisp (rcd-db-get-entry "markuptypes" "markuptypes_textlisp" markup hs-db))
hyperscope.el:4526:  (rcd-dlet ((hs::id id)
hyperscope.el:4545:      (rcd-dlet ((hs::markup-id (hyperscope-markup-language id))
hyperscope.el:4571:    (rcd-dlet ((hs::markup-id (hyperscope-markup-language id))
hyperscope.el:5772:  (rcd-dlet ((hs::markup-id (hyperscope-markup-language id)) 
hyperscope.el:5830:	     ;; 					       (rcd-dlet ((hd::is id)) (rcd-template-eval text)))
hyperscope.el:6819:	    (rcd-dlet ((hyperscope::variables (make-hash-table)))
hyperscope.el:6958:	      (rcd-dlet ((wrs::variables (make-hash-table :test 'equal))
hyperscope.el:7014:	  (rcd-dlet ((wrs::title title)
hyperscope.el:7116:		   (asciidoc (rcd-dlet ((hs:id id)) (rcd-template-eval asciidoc '("X" "X") hash)))
rcd-cf.el:6898:    (rcd-dlet ((wrs::width width)
rcd-cf.el:7840:	     (message (rcd-dlet ((rcd::hello-name name))
rcd-cf.el:9151:  (rcd-dlet ((wrs-text text))
rcd-cf.el:9310:				(rcd-dlet ((wrs::related-pages related-pages)
rcd-cf.el:9335:    (rcd-dlet ((rcd::name name)
rcd-cf.el:9381:    (rcd-dlet ((wrs::id page-id)
rcd-cf.el:9426:      (rcd-dlet ((wrs::text (rcd-template-eval wrs::text '("X" "X") wrs::variables))
rcd-cf.el:9429:	(rcd-dlet ((wrs::template (gethash "templates_template" wrs::template))
rcd-cf.el:10850:    (rcd-dlet ((rcd::name name)
rcd-cf.el:10998:      (rcd-dlet ((rcd::hello-name "Jean"))
rcd-cf.el:12307:    (rcd-dlet ((rcd::text text))
rcd-cf.el:12328:       (cond (template (rcd-dlet ((wrs::text text)
rcd-mailing.el:211:		 (message (rcd-dlet ((wrs::text message)
rcd-mailing.el:256:	   (expanded-body (rcd-dlet ((hello-name hello-name)
rcd-mailing.el:261:	   (html (rcd-dlet ((wrs::text (rcd-db-markupconversions-do expanded-body markup-input markup-output-html))
rcd-utilities.el:191:(defmacro rcd-dlet (binders &rest body)
rcd-utilities.el:1881:  (rcd-dlet ((wrs-processor "asciidoctor"))

--
Jean

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

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





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

* bug#59333: [PATCH] Define macro dlet*
  2022-11-17  7:40   ` Daan Ro
@ 2022-11-19  4:37     ` Jean Louis
  0 siblings, 0 replies; 10+ messages in thread
From: Jean Louis @ 2022-11-19  4:37 UTC (permalink / raw)
  To: Daan Ro; +Cc: Eli Zaretskii, 59333

* Daan Ro <daanturo@gmail.com> [2022-11-17 10:42]:
> > dlet was new in Emacs 28, and the change you mention was done before
> > Emacs 28 was released.  So NEWS just mentions the introduction of
> > dlet, and that is enough.
> 
> Sorry it was my fault for not paying attention to the commit year (I thought
> that was August this year).
> 
> Therefore reverting it now must not be an option.
> 
> But I think let* is more useful than let in general for programming,
> as it let us create successive bindings and transform the flow of
> data, like the natural flow of thought.

In some cases I use `dlet' within my 'let*' to make certain
variables to be global as those variables are not found in the
main code, but in the external text. Those two functions are not
interchangeable for me. Replacing them does not work.

Example is below:

(let* ((text (rcd-dlet ((hs::id id)
			(hs::uuid (hyperscope-uuid id))) 
	       (rcd-template-eval text '("⟦" "⟧")))))
  (continue...))

There are three parts: main code, template and text. Main code
does the template interpolation by using text.

As text is separate from code and from the template, the main
code cannot know what exactly is evaluated during template
interpolation. Thus using lexical binding does not work well with
externally evaluated code.

--
Jean

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

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







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

* bug#59333: [PATCH] Define macro dlet*
  2022-11-17  7:13 bug#59333: [PATCH] Define macro dlet* daanturo
  2022-11-17  7:25 ` Eli Zaretskii
@ 2022-11-19  4:47 ` Jean Louis
  2022-11-19  5:29   ` daanturo
  1 sibling, 1 reply; 10+ messages in thread
From: Jean Louis @ 2022-11-19  4:47 UTC (permalink / raw)
  To: daanturo; +Cc: 59333

* daanturo <daanturo@gmail.com> [2022-11-17 10:16]:
> --=-=-=
> Content-Type: text/plain
> 
> Tags: patch
> 
> 
> The dlet breakage comes as much surprise to me. There's not even a
> single entry in NEWS that mentions it.

If I remember well, `dlet' was working just fine (as in the sense of
dlet*), and then because it was changed and made `dlet' behave not in
the sense of `dlet*', it did not work any more for me, so I have
renamed the old dlet, to my private function `rcd-dlet' to fix it's
behavior when developers changed the last line.

The last line of `dlet' is now:  (let ,binders ,@body))) while I need
it to be as below:      (let* ,binders ,@body)))

(defmacro rcd-dlet (binders &rest body)
  "Like `let*' but using dynamic scoping.

Argument BINDERS behaves similarly like `let' with the difference
that variables become global even under lexical scope.

Optional argument BODY will be executed."
  (declare (indent 1) (debug let))
  ;; (defvar FOO) only affects the current scope, but in order for
  ;; this not to affect code after the main `let' we need to create a new scope,
  ;; which is what the surrounding `let' is for.
  ;; FIXME: (let () ...) currently doesn't actually create a new scope,
  ;; which is why we use (let (_) ...).
  `(let (_)
     ,@(mapcar (lambda (binder)
                 `(defvar ,(if (consp binder) (car binder) binder)))
               binders)
     (let* ,binders ,@body)))


-- 
Jean

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

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





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

* bug#59333: [PATCH] Define macro dlet*
  2022-11-19  4:47 ` Jean Louis
@ 2022-11-19  5:29   ` daanturo
  0 siblings, 0 replies; 10+ messages in thread
From: daanturo @ 2022-11-19  5:29 UTC (permalink / raw)
  To: Jean Louis; +Cc: 59333

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

On @ 2022-11-17 13:36, Mattias Engdegård wrote:
> The proposed patch also appears incorrect

It was a mistake when I copying and pasting. This patch corrected that and
removed the erroneous breakage mention.


If there would ever be a vote to reduce the number of `let` variants to lighten
the maintenance burden, I bet that the `let*` ones will remain instead of the
versions without the ability to refer to prior bindings. As `let*` can cover
`let` but the reverse is impossible.

```emacs-lisp
(let* ((_a a)
       (a (+ 1 _a))
       (b (+ 2 _a))))
```

Therefore, in my opinion, new `XXXlet` macros variants should be defined like
`XXXlet*` instead, maybe with only `XXXlet*` without `XXXlet`, since we will
eventually need an asterisk version in the future anyway. (Also dash-like easy
destructuring is sweet if possible.)

Why do need to define (publicly) then maintain for eternity `letf`, `flet`,
`dlet`, `lexical-let`, `pcase-let`, `if-let`, `when-let`, etc. when only their
`*` versions should be exposed and encompass every use case just fine?

I think `and-let*` is the most sensible case here as it doesn't have a more
limited `and-let` version.

On 19/11/2022 11:47, Jean Louis wrote:
> * daanturo <daanturo@gmail.com> [2022-11-17 10:16]:
>> --=-=-=
>> Content-Type: text/plain
>>
>> Tags: patch
>>
>>
>> The dlet breakage comes as much surprise to me. There's not even a
>> single entry in NEWS that mentions it.
>>
>>
>> The last line of `dlet' is now:  (let ,binders ,@body))) while I need
>> it to be as below:      (let* ,binders ,@body))
>>
>>
-- 
Daanturo.

[-- Attachment #2: 0001-Define-macro-dlet-asterisk.patch --]
[-- Type: text/x-patch, Size: 2144 bytes --]

From 57fa015d03232e5517cb6d2082d24ef18ca88e24 Mon Sep 17 00:00:00 2001
From: Daanturo <daanturo@gmail.com>
Date: Sat, 19 Nov 2022 12:02:35 +0700
Subject: [PATCH] Define macro dlet*

* lisp/subr.el: implementation.
* doc/lispref/variables.texi: documentation.
* etc/NEWS: announce it.
---
 doc/lispref/variables.texi | 6 ++++++
 etc/NEWS                   | 5 +++++
 lisp/subr.el               | 8 ++++++++
 3 files changed, 19 insertions(+)

diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index 7206f2acd2..11a0f220ca 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -303,6 +303,12 @@ Local Variables
 the forms, and then make the variables non-special again.
 @end defspec
 
+@defspec dlet* (bindings@dots{}) forms@dots{}
+This form is like @code{dlet}, but each valueform can refer to the
+symbols already bound previously, like what @code{let*} is to
+@code{let}.
+@end defspec
+
 @defspec named-let name bindings &rest body
 This special form is a looping construct inspired from the
 Scheme language.  It is similar to @code{let}: It binds the variables in
diff --git a/etc/NEWS b/etc/NEWS
index 0b8f4539f9..11f9ccb26a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3269,6 +3269,11 @@ The following generalized variables have been made obsolete:
 \f
 * Lisp Changes in Emacs 29.1
 
+
++++
+** New macro 'dlet*'.
+Like what 'let*' is to 'let'.
+
 +++
 ** Interpreted closures are "safe for space".
 As was already the case for byte-compiled closures, instead of capturing
diff --git a/lisp/subr.el b/lisp/subr.el
index 6b83196d05..ecca52f99e 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2155,6 +2155,14 @@ dlet
                binders)
      (let ,binders ,@body)))
 
+(defmacro dlet* (binders &rest body)
+  "Like `let*' but using dynamic scoping."
+  (declare (indent 1) (debug let))
+  `(let (_)
+     ,@(mapcar (lambda (binder)
+                 `(defvar ,(if (consp binder) (car binder) binder)))
+               binders)
+     (let* ,binders ,@body)))
 
 (defmacro with-wrapper-hook (hook args &rest body)
   "Run BODY, using wrapper functions from HOOK with additional ARGS.
-- 
2.38.1


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

* bug#59333: [PATCH] Define macro dlet*
  2022-11-17 13:36     ` Mattias Engdegård
@ 2022-11-25  0:14       ` Stefan Kangas
  0 siblings, 0 replies; 10+ messages in thread
From: Stefan Kangas @ 2022-11-25  0:14 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: Eli Zaretskii, 59333, Stefan Monnier, daanturo

tags 59333 + wontfix
close 59333
thanks

Mattias Engdegård <mattiase@acm.org> writes:

> 17 nov. 2022 kl. 14.22 skrev Stefan Monnier <monnier@iro.umontreal.ca>:
>
>> Currently I see very few uses of `dlet`, so adding `dlet*`
>> seems overkill.
>
> I concur. (The proposed patch also appears incorrect, and lacks a test.)
> Anyone really needing a `dlet*` macro can easily implement one in terms of `dlet`.

So it sounds like this is not something that we don't want to do at this
time.  I'm therefore closing this bug.





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

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

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-17  7:13 bug#59333: [PATCH] Define macro dlet* daanturo
2022-11-17  7:25 ` Eli Zaretskii
2022-11-17  7:40   ` Daan Ro
2022-11-19  4:37     ` Jean Louis
2022-11-17 13:22   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-17 13:36     ` Mattias Engdegård
2022-11-25  0:14       ` Stefan Kangas
2022-11-19  4:28   ` Jean Louis
2022-11-19  4:47 ` Jean Louis
2022-11-19  5:29   ` daanturo

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

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).