unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#49407: Request: Specify default values in `map-let` in Map.el
@ 2021-07-04 23:08 Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2021-07-15  8:51 ` Lars Ingebrigtsen
  2023-07-27  1:37 ` Earl Hyatt via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 18+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-07-04 23:08 UTC (permalink / raw)
  To: 49407

Hello,

`map-let` allows one to conveniently bind variables using `map-elt`, but
does not provide a way specify a default value if a key is missing.

With `map-elt`, one can use the optional third argument to specify this
value.  It would be good to have this in `map-let` as well.

For example, maybe it could look something like

     ;; As just a third value in the list:
     (let ((map '(:a 1 :b 2)))
       (map-let ((:a a)
                 (:b b)
                 (:c c 3))
           map
         (+ a b c)))

or

     ;; More like Common Lisp arg-list for `&key'.
     (let ((map '(:a 1 :b 2)))
       (map-let ((:a a)
                 (:b b)
                 (:c (c 3)))
           map
         (+ a b c)))

Please consider adding this feature.

Thank you.







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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2021-07-04 23:08 bug#49407: Request: Specify default values in `map-let` in Map.el Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2021-07-15  8:51 ` Lars Ingebrigtsen
  2021-07-16  1:45   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-21  2:56   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-27  1:37 ` Earl Hyatt via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 2 replies; 18+ messages in thread
From: Lars Ingebrigtsen @ 2021-07-15  8:51 UTC (permalink / raw)
  To: Okam; +Cc: Nicolas Petton, 49407

Okam <okamsn@protonmail.com> writes:

> `map-let` allows one to conveniently bind variables using `map-elt`, but
> does not provide a way specify a default value if a key is missing.
>
> With `map-elt`, one can use the optional third argument to specify this
> value.  It would be good to have this in `map-let` as well.
>
> For example, maybe it could look something like
>
>      ;; As just a third value in the list:
>      (let ((map '(:a 1 :b 2)))
>        (map-let ((:a a)
>                  (:b b)
>                  (:c c 3))
>            map
>          (+ a b c)))

Hm...  I guess that could be useful.  I've added Nicolas to the CCs;
perhaps he has an opinion here.

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





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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2021-07-15  8:51 ` Lars Ingebrigtsen
@ 2021-07-16  1:45   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-21  2:56   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 18+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-07-16  1:45 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Nicolas Petton, 49407

On 7/15/21 4:51 AM, Lars Ingebrigtsen wrote:
> Hm...  I guess that could be useful.  I've added Nicolas to the CCs;
> perhaps he has an opinion here.

If it helps, below is a version of the idea that I am using, specific to
plists:

(defmacro plist-bind (bindings plist &rest body)
   "Bind values in PLIST to variables in BINDINGS, surrounding BODY.

- PLIST is a property list.

- BINDINGS is of the form (KEY VAR KEY VAR ...).  VAR can
   optionally be a list of two elements: a variable name and a
   default value, similar to what one would use for expressing
   keyword parameters in `cl-defun' or `cl-destructuring-bind'.
   The default value is used /only/ when KEY is not found in
   PLIST.

- BODY is the same as in `let'.

This macro works the same as `cl-destructuring-bind', except for
the case when keys exist in PLIST that are not listed in
BINDINGS.  While `cl-destructuring-bind' would signal an error,
this macro simply ignores them."
   (declare (indent 2))
   (let ((value-holder (gensym "plist-let-"))
         (found-key (gensym "plist-prop-found-")))
     `(let* ((,value-holder ,plist)
             ,@(cl-loop for (key var . _) on bindings by #'cddr
                        if (consp var)
                        collect `(,(cl-first var)
                                  ;; Use `plist-member' instead of
`plist-get' to
                                  ;; allow giving `nil' as an argument
without
                                  ;; using the default value.
                                  (if-let ((,found-key (plist-member
,value-holder
                                                                     ,key)))
                                      (cl-second ,found-key)
                                    ,(cl-second var)))
                        else collect `(,var (plist-get ,value-holder
,key))))
        ,@body)))








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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2021-07-15  8:51 ` Lars Ingebrigtsen
  2021-07-16  1:45   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-07-21  2:56   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-22  1:48     ` Michael Heerdegen
  1 sibling, 1 reply; 18+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-21  2:56 UTC (permalink / raw)
  To: Lars Ingebrigtsen, Nicolas Petton; +Cc: 49407, Stefan Monnier

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

On 2021-07-15 08:51 UTC, Lars Ingebrigtsen wrote:
> Okam <okamsn@protonmail.com> writes:
> 
>> `map-let` allows one to conveniently bind variables using `map-elt`, but
>> does not provide a way specify a default value if a key is missing.
>>
>> With `map-elt`, one can use the optional third argument to specify this
>> value.  It would be good to have this in `map-let` as well.
>>
>> For example, maybe it could look something like
>>
>>       ;; As just a third value in the list:
>>       (let ((map '(:a 1 :b 2)))
>>         (map-let ((:a a)
>>                   (:b b)
>>                   (:c c 3))
>>             map
>>           (+ a b c)))
> 
> Hm...  I guess that could be useful.  I've added Nicolas to the CCs;
> perhaps he has an opinion here.
> 
> --
> (domestic pets only, the antidote for overdose, milk.)
>     bloggy blog: http://lars.ingebrigtsen.no

Hello,

I've written a patch and tests that would add an optional third argument 
for a default value. I also changed the documentation string for the 
pcase pattern, which said that unfound keys are ignored and won't cause 
the pattern to fail. That didn't seem true for patterns that didn't 
match nil. For example, this won't match:

(pcase '(:two 2)
   ((map (:two two 33)
         (:three `(,a . ,b)))
    (list two a b))
   (_ 'fail))

However, I have a question about avoiding using a lambda. I see that the 
pattern uses `pcase--flip`, which is "used internally to avoid (funcall 
(lambda ...) ...)". Why should lambda functions be avoided for this, and 
I should be using a custom helper function for this one pattern?

Thank you.


[-- Attachment #2: 0001-Allow-default-values-in-map-let-and-the-pcase-map-fo.patch --]
[-- Type: text/x-patch, Size: 6159 bytes --]

From 1dbb797a9a736fc81ad9f672da815e2510e7f31a Mon Sep 17 00:00:00 2001
From: Earl Hyatt <okamsn@protonmail.com>
Date: Thu, 20 Jul 2023 21:44:41 -0400
Subject: [PATCH] Allow default values in 'map-let' and the pcase 'map' form

* lisp/emacs-lisp/map.el (map-let, map)
(map--make-pcase-bindings): Add a third argument for specifying a
default value, like in 'map-elt'. (Bug#49407)

* lisp/emacs-lisp/map.el (map--make-pcase-bindings): Clarify that keys
that aren't found aren't ignored, they actually get the value
nil (unless the new default value is given). The overall pattern can
still fail to match if the sub-pattern for the unfound key doesn't
match nil.

* test/lisp/emacs-lisp/map-tests.el (test-map-let-default)
(test-map-plist-pcase-default, test-map-pcase-matches): Add tests,
including for the above item.
---
 lisp/emacs-lisp/map.el            | 31 ++++++++++++------
 test/lisp/emacs-lisp/map-tests.el | 52 +++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 10 deletions(-)

diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 7a48ba47434..7f127f312de 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -50,18 +50,23 @@ map
 
 ARGS is a list of elements to be matched in the map.
 
-Each element of ARGS can be of the form (KEY PAT), in which case KEY is
-evaluated and searched for in the map.  The match fails if for any KEY
-found in the map, the corresponding PAT doesn't match the value
-associated with the KEY.
+Each element of ARGS can be of the form (KEY PAT) or (KEY PAT DEFAULT),
+
+in which case KEY is evaluated and searched for in the map and
+DEFAULT is the evaluated value used if KEY is not found.  The
+match fails if for any KEY found in the map, the corresponding
+PAT doesn't match the value associated with the KEY.  The match
+fails if for any KEY not found in the map, the corresponding PAT
+doesn't match the DEFAULT value, if given.
 
 Each element can also be a SYMBOL, which is an abbreviation of
 a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  When SYMBOL
 is a keyword, it is an abbreviation of the form (:SYMBOL SYMBOL),
 useful for binding plist values.
 
-Keys in ARGS not found in the map are ignored, and the match doesn't
-fail."
+When no DEFAULT value is given, the default value for keys in
+ARGS not found in the map is nil, and the match doesn't fail so
+long at PAT, if given, matches nil."
   `(and (pred mapp)
         ,@(map--make-pcase-bindings args)))
 
@@ -71,12 +76,14 @@ map-let
 KEYS can be a list of symbols, in which case each element will be
 bound to the looked up value in MAP.
 
-KEYS can also be a list of (KEY VARNAME) pairs, in which case
-KEY is an unquoted form.
+KEYS can also be a list of (KEY VARNAME) pairs and
+\(KEY VARNAME DEFAULT) triples, in which case KEY is an
+unquoted form.
 
 MAP can be an alist, plist, hash-table, or array."
   (declare (indent 2)
-           (debug ((&rest &or symbolp ([form symbolp])) form body)))
+           (debug ((&rest &or symbolp ([form symbolp &optional form]))
+                   form body)))
   `(pcase-let ((,(map--make-pcase-patterns keys) ,map))
      ,@body))
 
@@ -599,7 +606,11 @@ map--make-pcase-bindings
   "Return a list of pcase bindings from ARGS to the elements of a map."
   (mapcar (lambda (elt)
             (cond ((consp elt)
-                   `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt)))
+                   (if (cddr elt)
+                       `(app (lambda (arg)
+                               (map-elt arg ,(car elt) ,(caddr elt)))
+                             ,(cadr elt))
+                     `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt))))
                   ((keywordp elt)
                    (let ((var (intern (substring (symbol-name elt) 1))))
                      `(app (pcase--flip map-elt ,elt) ,var)))
diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el
index 86c0e9e0503..42458fbfeb7 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -577,6 +577,13 @@ test-map-let
     (should (= b 2))
     (should-not c)))
 
+(ert-deftest test-map-let-default ()
+  (map-let (('foo a 3)
+            ('baz b 4))
+      '((foo . 1))
+    (should (= a 1))
+    (should (= b 4))))
+
 (ert-deftest test-map-merge ()
   "Test `map-merge'."
   (should (equal (sort (map-merge 'list '(a 1) '((b . 2) (c . 3))
@@ -617,6 +624,51 @@ test-map-plist-pcase
                      (list one two))
                    '(1 2)))))
 
+(ert-deftest test-map-plist-pcase-default ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase-let (((map (:two two 33)
+                                     (:three three 44))
+                                plist))
+                     (list two three))
+                   '(2 44)))))
+
+(ert-deftest test-map-pcase-matches ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 nil)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three 44))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 44)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) '(11 . 22)))
+                      (list two a b))
+                     (_ 'fail))
+                   '(2 11 22)))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) 44))
+                      (list two a b))
+                     (_ 'fail))))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) nil))
+                      (list two a b))
+                     (_ 'fail))))))
+
 (ert-deftest test-map-setf-alist-insert-key ()
   (let ((alist))
     (should (equal (setf (map-elt alist 'key) 'value)
-- 
2.34.1


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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-21  2:56   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-07-22  1:48     ` Michael Heerdegen
  2023-07-22 15:45       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-22 18:46       ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 18+ messages in thread
From: Michael Heerdegen @ 2023-07-22  1:48 UTC (permalink / raw)
  To: Okam; +Cc: Lars Ingebrigtsen, 49407, Nicolas Petton, Stefan Monnier

Okam <okamsn@protonmail.com> writes:

> I've written a patch and tests that would add an optional third
> argument for a default value.

Thank you.

> However, I have a question about avoiding using a lambda. I see that
> the pattern uses `pcase--flip`, which is "used internally to avoid
> (funcall (lambda ...) ...)". Why should lambda functions be avoided
> for this,

As far as I understand, to produce more efficient code.

> and I should be using a custom helper function for this one pattern?

Stefan, would you want to extend `pcase--flip' to more arguments to
support this case?


| diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
| index 7a48ba47434..7f127f312de 100644
| --- a/lisp/emacs-lisp/map.el
| +++ b/lisp/emacs-lisp/map.el
| @@ -50,18 +50,23 @@ map
|
|  ARGS is a list of elements to be matched in the map.
|
| -Each element of ARGS can be of the form (KEY PAT), in which case KEY is
| -evaluated and searched for in the map.  The match fails if for any KEY
| -found in the map, the corresponding PAT doesn't match the value
| -associated with the KEY.
| +Each element of ARGS can be of the form (KEY PAT) or (KEY PAT DEFAULT),
| +
| +in which case KEY is evaluated and searched for in the map and

That line break in the last sentence is somehow... broken.

| +DEFAULT is the evaluated value used if KEY is not found.  The
| +match fails if for any KEY found in the map, the corresponding
| +PAT doesn't match the value associated with the KEY.  The match
| +fails if for any KEY not found in the map, the corresponding PAT
| +doesn't match the DEFAULT value, if given.

Here is something grammatically not right in the last sentence.  And I
think we should say that that last case (PAT doesn't match DEFAULT) only
lets matching fail when the KEY is not found.


| -Keys in ARGS not found in the map are ignored, and the match doesn't
| -fail."
| +When no DEFAULT value is given, the default value for keys in
| +ARGS not found in the map is nil, and the match doesn't fail so
| +long at PAT, if given, matches nil."
|    `(and (pred mapp)
|          ,@(map--make-pcase-bindings args)))

Typo in doc ("at").  And can't we simply say that omitting DEFAULT is
equivalent to a DEFAULT of nil?

| @@ -599,7 +606,11 @@ map--make-pcase-bindings
|    "Return a list of pcase bindings from ARGS to the elements of a map."
|    (mapcar (lambda (elt)
|              (cond ((consp elt)
| -                   `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt)))
| +                   (if (cddr elt)
| +                       `(app (lambda (arg)
| +                               (map-elt arg ,(car elt) ,(caddr elt)))
| +                             ,(cadr elt))
| +                     `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt))))

If we don't extend `pcase--flip' to support this case, I think your
lambda would need to use an uninterned symbol as parameter to avoid
collisions with the involved expressions.


Michael.





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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-22  1:48     ` Michael Heerdegen
@ 2023-07-22 15:45       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-22 18:46       ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 18+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-22 15:45 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Okam, Lars Ingebrigtsen, 49407, Nicolas Petton

>> However, I have a question about avoiding using a lambda. I see that
>> the pattern uses `pcase--flip`, which is "used internally to avoid
>> (funcall (lambda ...) ...)". Why should lambda functions be avoided
>> for this,
> As far as I understand, to produce more efficient code.

Indeed.

>> and I should be using a custom helper function for this one pattern?
> Stefan, would you want to extend `pcase--flip' to more arguments to
> support this case?

Probably not worth it, no.


        Stefan






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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-22  1:48     ` Michael Heerdegen
  2023-07-22 15:45       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-07-22 18:46       ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-26  3:41         ` Michael Heerdegen
  1 sibling, 1 reply; 18+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-22 18:46 UTC (permalink / raw)
  To: Michael Heerdegen
  Cc: Lars Ingebrigtsen, 49407, Nicolas Petton, Stefan Monnier

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

On 2023-07-22 01:48 UTC, Michael Heerdegen wrote:
> 
> | diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
> | index 7a48ba47434..7f127f312de 100644
> | --- a/lisp/emacs-lisp/map.el
> | +++ b/lisp/emacs-lisp/map.el
> | @@ -50,18 +50,23 @@ map
> |
> |  ARGS is a list of elements to be matched in the map.
> |
> | -Each element of ARGS can be of the form (KEY PAT), in which case KEY is
> | -evaluated and searched for in the map.  The match fails if for any KEY
> | -found in the map, the corresponding PAT doesn't match the value
> | -associated with the KEY.
> | +Each element of ARGS can be of the form (KEY PAT) or (KEY PAT DEFAULT),
> | +
> | +in which case KEY is evaluated and searched for in the map and
> 
> That line break in the last sentence is somehow... broken.
> 
> | +DEFAULT is the evaluated value used if KEY is not found.  The
> | +match fails if for any KEY found in the map, the corresponding
> | +PAT doesn't match the value associated with the KEY.  The match
> | +fails if for any KEY not found in the map, the corresponding PAT
> | +doesn't match the DEFAULT value, if given.
> 
> Here is something grammatically not right in the last sentence.  And I
> think we should say that that last case (PAT doesn't match DEFAULT) only
> lets matching fail when the KEY is not found.
> 
> 
> | -Keys in ARGS not found in the map are ignored, and the match doesn't
> | -fail."
> | +When no DEFAULT value is given, the default value for keys in
> | +ARGS not found in the map is nil, and the match doesn't fail so
> | +long at PAT, if given, matches nil."
> |    `(and (pred mapp)
> |          ,@(map--make-pcase-bindings args)))
> 
> Typo in doc ("at").  And can't we simply say that omitting DEFAULT is
> equivalent to a DEFAULT of nil?
> 
> | @@ -599,7 +606,11 @@ map--make-pcase-bindings
> |    "Return a list of pcase bindings from ARGS to the elements of a map."
> |    (mapcar (lambda (elt)
> |              (cond ((consp elt)
> | -                   `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt)))
> | +                   (if (cddr elt)
> | +                       `(app (lambda (arg)
> | +                               (map-elt arg ,(car elt) ,(caddr elt)))
> | +                             ,(cadr elt))
> | +                     `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt))))
> 
> If we don't extend `pcase--flip' to support this case, I think your
> lambda would need to use an uninterned symbol as parameter to avoid
> collisions with the involved expressions.
> 
> 
> Michael.

Please see the attached file. I have re-worded the doc string and added 
a wrapper macro to re-order the arguments to `map-elt` for the `app` 
pattern.

[-- Attachment #2: v2-0001-Allow-default-values-in-map-let-and-the-pcase-map.patch --]
[-- Type: text/x-patch, Size: 6343 bytes --]

From 6cdf145fbc81c75c88c8f5e98450a30688d24901 Mon Sep 17 00:00:00 2001
From: Earl Hyatt <okamsn@protonmail.com>
Date: Thu, 20 Jul 2023 21:44:41 -0400
Subject: [PATCH v2] Allow default values in 'map-let' and the pcase 'map' form

* lisp/emacs-lisp/map.el (map-let, map)
(map--make-pcase-bindings): Add a third argument for specifying a
default value, like in 'map-elt'. (Bug#49407)

* lisp/emacs-lisp/map.el (map--make-pcase-bindings): Clarify that keys
that aren't found aren't ignored, they actually get the value
nil (unless the new default value is given). The overall pattern can
still fail to match if the sub-pattern for the unfound key doesn't
match nil.

* test/lisp/emacs-lisp/map-tests.el (test-map-let-default)
(test-map-plist-pcase-default, test-map-pcase-matches): Add tests,
including for the above item.
---
 lisp/emacs-lisp/map.el            | 40 ++++++++++++++++++------
 test/lisp/emacs-lisp/map-tests.el | 52 +++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 10 deletions(-)

diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 7a48ba47434..35b8998679a 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -50,18 +50,26 @@ map
 
 ARGS is a list of elements to be matched in the map.
 
-Each element of ARGS can be of the form (KEY PAT), in which case KEY is
-evaluated and searched for in the map.  The match fails if for any KEY
-found in the map, the corresponding PAT doesn't match the value
-associated with the KEY.
+Each element in ARGS can be of the form (KEY PAT) or (KEY PAT
+DEFAULT), where KEY is the key sought in the map, PAT is a
+`pcase' pattern, and DEFAULT is the default value to use if KEY
+isn't found.  Both KEY and DEFAULT are evaluated.  If DEFAULT
+isn't given, then nil is used.
 
 Each element can also be a SYMBOL, which is an abbreviation of
 a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  When SYMBOL
 is a keyword, it is an abbreviation of the form (:SYMBOL SYMBOL),
 useful for binding plist values.
 
-Keys in ARGS not found in the map are ignored, and the match doesn't
-fail."
+The match fails if:
+
+- KEY is found and PAT does not match the associated value
+
+- KEY is not found, DEFAULT is given, and PAT does not match
+  DEFAULT
+
+- KEY is not found, DEFAULT is not given, and PAT does not match
+  nil"
   `(and (pred mapp)
         ,@(map--make-pcase-bindings args)))
 
@@ -71,12 +79,14 @@ map-let
 KEYS can be a list of symbols, in which case each element will be
 bound to the looked up value in MAP.
 
-KEYS can also be a list of (KEY VARNAME) pairs, in which case
-KEY is an unquoted form.
+KEYS can also be a list of (KEY VARNAME) pairs and
+\(KEY VARNAME DEFAULT) triples, in which case KEY is an
+unquoted form.
 
 MAP can be an alist, plist, hash-table, or array."
   (declare (indent 2)
-           (debug ((&rest &or symbolp ([form symbolp])) form body)))
+           (debug ((&rest &or symbolp ([form symbolp &optional form]))
+                   form body)))
   `(pcase-let ((,(map--make-pcase-patterns keys) ,map))
      ,@body))
 
@@ -595,11 +605,21 @@ map-into
     (map-into \\='((1 . 3)) \\='(hash-table :test eql))"
   (map--into-hash map (cdr type)))
 
+(defmacro map--pcase-map-elt (key default map)
+  "A macro to make MAP the last argument to `map-elt'.
+
+This allows using default values for `map-elt', which can't be
+done using `pcase--flip'.
+
+KEY is the key sought in the map.  DEFAULT is the default value."
+  `(map-elt ,map ,key ,default))
+
 (defun map--make-pcase-bindings (args)
   "Return a list of pcase bindings from ARGS to the elements of a map."
   (mapcar (lambda (elt)
             (cond ((consp elt)
-                   `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt)))
+                   `(app (map--pcase-map-elt ,(car elt) ,(caddr elt))
+                         ,(cadr elt)))
                   ((keywordp elt)
                    (let ((var (intern (substring (symbol-name elt) 1))))
                      `(app (pcase--flip map-elt ,elt) ,var)))
diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el
index 86c0e9e0503..42458fbfeb7 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -577,6 +577,13 @@ test-map-let
     (should (= b 2))
     (should-not c)))
 
+(ert-deftest test-map-let-default ()
+  (map-let (('foo a 3)
+            ('baz b 4))
+      '((foo . 1))
+    (should (= a 1))
+    (should (= b 4))))
+
 (ert-deftest test-map-merge ()
   "Test `map-merge'."
   (should (equal (sort (map-merge 'list '(a 1) '((b . 2) (c . 3))
@@ -617,6 +624,51 @@ test-map-plist-pcase
                      (list one two))
                    '(1 2)))))
 
+(ert-deftest test-map-plist-pcase-default ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase-let (((map (:two two 33)
+                                     (:three three 44))
+                                plist))
+                     (list two three))
+                   '(2 44)))))
+
+(ert-deftest test-map-pcase-matches ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 nil)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three 44))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 44)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) '(11 . 22)))
+                      (list two a b))
+                     (_ 'fail))
+                   '(2 11 22)))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) 44))
+                      (list two a b))
+                     (_ 'fail))))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) nil))
+                      (list two a b))
+                     (_ 'fail))))))
+
 (ert-deftest test-map-setf-alist-insert-key ()
   (let ((alist))
     (should (equal (setf (map-elt alist 'key) 'value)
-- 
2.34.1


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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-22 18:46       ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-07-26  3:41         ` Michael Heerdegen
  2023-07-27  1:39           ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 18+ messages in thread
From: Michael Heerdegen @ 2023-07-26  3:41 UTC (permalink / raw)
  To: Okam; +Cc: Lars Ingebrigtsen, 49407, Nicolas Petton, Stefan Monnier

Okam <okamsn@protonmail.com> writes:

> Please see the attached file. I have re-worded the doc string and added
> a wrapper macro to re-order the arguments to `map-elt` for the `app`
> pattern.

Perfect!

Only one detail:

| @@ -71,12 +79,14 @@ map-let
|  KEYS can be a list of symbols, in which case each element will be
|  bound to the looked up value in MAP.
|
| -KEYS can also be a list of (KEY VARNAME) pairs, in which case
| -KEY is an unquoted form.
| +KEYS can also be a list of (KEY VARNAME) pairs and
| +\(KEY VARNAME DEFAULT) triples, in which case KEY is an
| +unquoted form.

Here you could also say that DEFAULT is an unquoted form.

The rest looks good to me.


Thanks,

Michael.





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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2021-07-04 23:08 bug#49407: Request: Specify default values in `map-let` in Map.el Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2021-07-15  8:51 ` Lars Ingebrigtsen
@ 2023-07-27  1:37 ` Earl Hyatt via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 18+ messages in thread
From: Earl Hyatt via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-27  1:37 UTC (permalink / raw)
  To: Michael Heerdegen
  Cc: Lars Ingebrigtsen, 49407, Nicolas Petton, Stefan Monnier

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

Michael Heerdegen wrote:
> Only one detail:
> 
> | @@ -71,12 +79,14 @@ map-let
> |  KEYS can be a list of symbols, in which case each element will be
> |  bound to the looked up value in MAP.
> |
> | -KEYS can also be a list of (KEY VARNAME) pairs, in which case
> | -KEY is an unquoted form.
> | +KEYS can also be a list of (KEY VARNAME) pairs and
> | +\(KEY VARNAME DEFAULT) triples, in which case KEY is an
> | +unquoted form.
> 
> Here you could also say that DEFAULT is an unquoted form.

I have made that change. Please see the attached file.

[-- Attachment #2: v3-0001-Allow-default-values-in-map-let-and-the-pcase-map.patch --]
[-- Type: text/x-patch, Size: 6585 bytes --]

From 99208ca640d4944c57082772702cb8534fe91d32 Mon Sep 17 00:00:00 2001
From: Earl Hyatt <okamsn@protonmail.com>
Date: Thu, 20 Jul 2023 21:44:41 -0400
Subject: [PATCH v3] Allow default values in 'map-let' and the pcase 'map' form

* lisp/emacs-lisp/map.el (map-let, map)
(map--make-pcase-bindings): Add a third argument for specifying a
default value, like in 'map-elt'. (Bug#49407)

* lisp/emacs-lisp/map.el (map--make-pcase-bindings): Clarify that keys
that aren't found aren't ignored, they actually get the value
nil (unless the new default value is given). The overall pattern can
still fail to match if the sub-pattern for the unfound key doesn't
match nil.

* test/lisp/emacs-lisp/map-tests.el (test-map-let-default)
(test-map-plist-pcase-default, test-map-pcase-matches): Add tests,
including for the above item.
---
 lisp/emacs-lisp/map.el            | 40 +++++++++++++++------
 test/lisp/emacs-lisp/map-tests.el | 59 +++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 7a48ba47434..feb903cf71f 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -50,18 +50,26 @@ map
 
 ARGS is a list of elements to be matched in the map.
 
-Each element of ARGS can be of the form (KEY PAT), in which case KEY is
-evaluated and searched for in the map.  The match fails if for any KEY
-found in the map, the corresponding PAT doesn't match the value
-associated with the KEY.
+Each element in ARGS can be of the form (KEY PAT) or (KEY PAT
+DEFAULT), where KEY is the key sought in the map, PAT is a
+`pcase' pattern, and DEFAULT is the default value to use if KEY
+isn't found.  Both KEY and DEFAULT are evaluated.  If DEFAULT
+isn't given, then nil is used.
 
 Each element can also be a SYMBOL, which is an abbreviation of
 a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  When SYMBOL
 is a keyword, it is an abbreviation of the form (:SYMBOL SYMBOL),
 useful for binding plist values.
 
-Keys in ARGS not found in the map are ignored, and the match doesn't
-fail."
+The match fails if:
+
+- KEY is found and PAT does not match the associated value
+
+- KEY is not found, DEFAULT is given, and PAT does not match
+  DEFAULT
+
+- KEY is not found, DEFAULT is not given, and PAT does not match
+  nil"
   `(and (pred mapp)
         ,@(map--make-pcase-bindings args)))
 
@@ -71,12 +79,14 @@ map-let
 KEYS can be a list of symbols, in which case each element will be
 bound to the looked up value in MAP.
 
-KEYS can also be a list of (KEY VARNAME) pairs, in which case
-KEY is an unquoted form.
+KEYS can also be a list of (KEY VARNAME) pairs and
+\(KEY VARNAME DEFAULT) triples, in which case KEY and
+DEFAULT are unquoted forms.
 
 MAP can be an alist, plist, hash-table, or array."
   (declare (indent 2)
-           (debug ((&rest &or symbolp ([form symbolp])) form body)))
+           (debug ((&rest &or symbolp ([form symbolp &optional form]))
+                   form body)))
   `(pcase-let ((,(map--make-pcase-patterns keys) ,map))
      ,@body))
 
@@ -595,11 +605,21 @@ map-into
     (map-into \\='((1 . 3)) \\='(hash-table :test eql))"
   (map--into-hash map (cdr type)))
 
+(defmacro map--pcase-map-elt (key default map)
+  "A macro to make MAP the last argument to `map-elt'.
+
+This allows using default values for `map-elt', which can't be
+done using `pcase--flip'.
+
+KEY is the key sought in the map.  DEFAULT is the default value."
+  `(map-elt ,map ,key ,default))
+
 (defun map--make-pcase-bindings (args)
   "Return a list of pcase bindings from ARGS to the elements of a map."
   (mapcar (lambda (elt)
             (cond ((consp elt)
-                   `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt)))
+                   `(app (map--pcase-map-elt ,(car elt) ,(caddr elt))
+                         ,(cadr elt)))
                   ((keywordp elt)
                    (let ((var (intern (substring (symbol-name elt) 1))))
                      `(app (pcase--flip map-elt ,elt) ,var)))
diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el
index 86c0e9e0503..2204743f794 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -577,6 +577,13 @@ test-map-let
     (should (= b 2))
     (should-not c)))
 
+(ert-deftest test-map-let-default ()
+  (map-let (('foo a 3)
+            ('baz b 4))
+      '((foo . 1))
+    (should (equal a 1))
+    (should (equal b 4))))
+
 (ert-deftest test-map-merge ()
   "Test `map-merge'."
   (should (equal (sort (map-merge 'list '(a 1) '((b . 2) (c . 3))
@@ -617,6 +624,58 @@ test-map-plist-pcase
                      (list one two))
                    '(1 2)))))
 
+(ert-deftest test-map-plist-pcase-default ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase-let (((map (:two two 33)
+                                     (:three three 44))
+                                plist))
+                     (list two three))
+                   '(2 44)))))
+
+(ert-deftest test-map-pcase-matches ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 nil)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three 44))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 44)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) '(11 . 22)))
+                      (list two a b))
+                     (_ 'fail))
+                   '(2 11 22)))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) 44))
+                      (list two a b))
+                     (_ 'fail))))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) nil))
+                      (list two a b))
+                     (_ 'fail))))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b)))
+                      (list two a b))
+                     (_ 'fail))))))
+
 (ert-deftest test-map-setf-alist-insert-key ()
   (let ((alist))
     (should (equal (setf (map-elt alist 'key) 'value)
-- 
2.34.1


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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-26  3:41         ` Michael Heerdegen
@ 2023-07-27  1:39           ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-28 18:02             ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 18+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-27  1:39 UTC (permalink / raw)
  To: Michael Heerdegen
  Cc: Lars Ingebrigtsen, 49407, Nicolas Petton, Stefan Monnier

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

Michael Heerdegen wrote:
 > Only one detail:
 >
 > | @@ -71,12 +79,14 @@ map-let
 > |  KEYS can be a list of symbols, in which case each element will be
 > |  bound to the looked up value in MAP.
 > |
 > | -KEYS can also be a list of (KEY VARNAME) pairs, in which case
 > | -KEY is an unquoted form.
 > | +KEYS can also be a list of (KEY VARNAME) pairs and
 > | +\(KEY VARNAME DEFAULT) triples, in which case KEY is an
 > | +unquoted form.
 >
 > Here you could also say that DEFAULT is an unquoted form.

I have made that change. Please see the attached file.

[-- Attachment #2: v3-0001-Allow-default-values-in-map-let-and-the-pcase-map.patch --]
[-- Type: text/x-patch, Size: 6585 bytes --]

From 99208ca640d4944c57082772702cb8534fe91d32 Mon Sep 17 00:00:00 2001
From: Earl Hyatt <okamsn@protonmail.com>
Date: Thu, 20 Jul 2023 21:44:41 -0400
Subject: [PATCH v3] Allow default values in 'map-let' and the pcase 'map' form

* lisp/emacs-lisp/map.el (map-let, map)
(map--make-pcase-bindings): Add a third argument for specifying a
default value, like in 'map-elt'. (Bug#49407)

* lisp/emacs-lisp/map.el (map--make-pcase-bindings): Clarify that keys
that aren't found aren't ignored, they actually get the value
nil (unless the new default value is given). The overall pattern can
still fail to match if the sub-pattern for the unfound key doesn't
match nil.

* test/lisp/emacs-lisp/map-tests.el (test-map-let-default)
(test-map-plist-pcase-default, test-map-pcase-matches): Add tests,
including for the above item.
---
 lisp/emacs-lisp/map.el            | 40 +++++++++++++++------
 test/lisp/emacs-lisp/map-tests.el | 59 +++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 7a48ba47434..feb903cf71f 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -50,18 +50,26 @@ map
 
 ARGS is a list of elements to be matched in the map.
 
-Each element of ARGS can be of the form (KEY PAT), in which case KEY is
-evaluated and searched for in the map.  The match fails if for any KEY
-found in the map, the corresponding PAT doesn't match the value
-associated with the KEY.
+Each element in ARGS can be of the form (KEY PAT) or (KEY PAT
+DEFAULT), where KEY is the key sought in the map, PAT is a
+`pcase' pattern, and DEFAULT is the default value to use if KEY
+isn't found.  Both KEY and DEFAULT are evaluated.  If DEFAULT
+isn't given, then nil is used.
 
 Each element can also be a SYMBOL, which is an abbreviation of
 a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  When SYMBOL
 is a keyword, it is an abbreviation of the form (:SYMBOL SYMBOL),
 useful for binding plist values.
 
-Keys in ARGS not found in the map are ignored, and the match doesn't
-fail."
+The match fails if:
+
+- KEY is found and PAT does not match the associated value
+
+- KEY is not found, DEFAULT is given, and PAT does not match
+  DEFAULT
+
+- KEY is not found, DEFAULT is not given, and PAT does not match
+  nil"
   `(and (pred mapp)
         ,@(map--make-pcase-bindings args)))
 
@@ -71,12 +79,14 @@ map-let
 KEYS can be a list of symbols, in which case each element will be
 bound to the looked up value in MAP.
 
-KEYS can also be a list of (KEY VARNAME) pairs, in which case
-KEY is an unquoted form.
+KEYS can also be a list of (KEY VARNAME) pairs and
+\(KEY VARNAME DEFAULT) triples, in which case KEY and
+DEFAULT are unquoted forms.
 
 MAP can be an alist, plist, hash-table, or array."
   (declare (indent 2)
-           (debug ((&rest &or symbolp ([form symbolp])) form body)))
+           (debug ((&rest &or symbolp ([form symbolp &optional form]))
+                   form body)))
   `(pcase-let ((,(map--make-pcase-patterns keys) ,map))
      ,@body))
 
@@ -595,11 +605,21 @@ map-into
     (map-into \\='((1 . 3)) \\='(hash-table :test eql))"
   (map--into-hash map (cdr type)))
 
+(defmacro map--pcase-map-elt (key default map)
+  "A macro to make MAP the last argument to `map-elt'.
+
+This allows using default values for `map-elt', which can't be
+done using `pcase--flip'.
+
+KEY is the key sought in the map.  DEFAULT is the default value."
+  `(map-elt ,map ,key ,default))
+
 (defun map--make-pcase-bindings (args)
   "Return a list of pcase bindings from ARGS to the elements of a map."
   (mapcar (lambda (elt)
             (cond ((consp elt)
-                   `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt)))
+                   `(app (map--pcase-map-elt ,(car elt) ,(caddr elt))
+                         ,(cadr elt)))
                   ((keywordp elt)
                    (let ((var (intern (substring (symbol-name elt) 1))))
                      `(app (pcase--flip map-elt ,elt) ,var)))
diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el
index 86c0e9e0503..2204743f794 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -577,6 +577,13 @@ test-map-let
     (should (= b 2))
     (should-not c)))
 
+(ert-deftest test-map-let-default ()
+  (map-let (('foo a 3)
+            ('baz b 4))
+      '((foo . 1))
+    (should (equal a 1))
+    (should (equal b 4))))
+
 (ert-deftest test-map-merge ()
   "Test `map-merge'."
   (should (equal (sort (map-merge 'list '(a 1) '((b . 2) (c . 3))
@@ -617,6 +624,58 @@ test-map-plist-pcase
                      (list one two))
                    '(1 2)))))
 
+(ert-deftest test-map-plist-pcase-default ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase-let (((map (:two two 33)
+                                     (:three three 44))
+                                plist))
+                     (list two three))
+                   '(2 44)))))
+
+(ert-deftest test-map-pcase-matches ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 nil)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three 44))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 44)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) '(11 . 22)))
+                      (list two a b))
+                     (_ 'fail))
+                   '(2 11 22)))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) 44))
+                      (list two a b))
+                     (_ 'fail))))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) nil))
+                      (list two a b))
+                     (_ 'fail))))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b)))
+                      (list two a b))
+                     (_ 'fail))))))
+
 (ert-deftest test-map-setf-alist-insert-key ()
   (let ((alist))
     (should (equal (setf (map-elt alist 'key) 'value)
-- 
2.34.1


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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-27  1:39           ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-07-28 18:02             ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-28 19:19               ` Eli Zaretskii
  2023-07-29  0:37               ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 18+ messages in thread
From: Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-28 18:02 UTC (permalink / raw)
  To: Michael Heerdegen
  Cc: Okam, Lars Ingebrigtsen, 49407, Nicolas Petton, Stefan Monnier

Okam via "Bug reports for GNU Emacs, the Swiss army knife of text editors" [2023-07-27 01:39 +0000] wrote:

> From 99208ca640d4944c57082772702cb8534fe91d32 Mon Sep 17 00:00:00 2001
> From: Earl Hyatt <okamsn@protonmail.com>

I think your past contributions were under "Earl Hyatt
<ej32u@protonmail.com>", right?  Is okamsn@protonmail.com your current
address?  Eli, does it make a difference for the CA, do we need to
update .mailmap, or anything like that?

> Date: Thu, 20 Jul 2023 21:44:41 -0400
> Subject: [PATCH v3] Allow default values in 'map-let' and the pcase 'map' form
>
> * lisp/emacs-lisp/map.el (map-let, map)
> (map--make-pcase-bindings): Add a third argument for specifying a
> default value, like in 'map-elt'. (Bug#49407)
>
> * lisp/emacs-lisp/map.el (map--make-pcase-bindings): Clarify that keys
> that aren't found aren't ignored, they actually get the value
> nil (unless the new default value is given). The overall pattern can
                                             ^^
                                             Two spaces here.

[...]

> +Each element in ARGS can be of the form (KEY PAT) or (KEY PAT
> +DEFAULT), where KEY is the key sought in the map, PAT is a
> +`pcase' pattern, and DEFAULT is the default value to use if KEY
> +isn't found.  Both KEY and DEFAULT are evaluated.  If DEFAULT
> +isn't given, then nil is used.

FWIW, the form/structure can be kept on a single line, and a couple of
passive voices avoided, by rewording as e.g.

  Each element of ARGS can be of the form (KEY PAT [DEFAULT]),
  which looks up KEY in the map and matches the associated value
  against `pcase' pattern PAT.  DEFAULT specifies the fallback
  value to use when KEY is not present in the map.  If omitted, it
  defaults to nil.  Both KEY and DEFAULT are evaluated.

> +The match fails if:
> +
> +- KEY is found and PAT does not match the associated value
> +
> +- KEY is not found, DEFAULT is given, and PAT does not match
> +  DEFAULT
> +
> +- KEY is not found, DEFAULT is not given, and PAT does not match
> +  nil"

I find this partly redundant/repetitive, since we already know that PAT
is meant to match either KEY's value (when found), or DEFAULT (which
defaults to nil).

What this doesn't make explicit (compared to the previous version) is
what happens when there are multiple ARGS; specifically, when one or
more of them don't match.

> +KEYS can also be a list of (KEY VARNAME) pairs and
> +\(KEY VARNAME DEFAULT) triples, in which case KEY and

This could also use (KEY VARNAME [DEFAULT]) syntax, if preferred.

Otherwise LGTM, thanks,

-- 
Basil





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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-28 18:02             ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-07-28 19:19               ` Eli Zaretskii
  2023-07-29  0:37               ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 18+ messages in thread
From: Eli Zaretskii @ 2023-07-28 19:19 UTC (permalink / raw)
  To: Basil L. Contovounesios
  Cc: michael_heerdegen, nicolas, okamsn, monnier, larsi, 49407

> Cc: Okam <okamsn@protonmail.com>, Lars Ingebrigtsen <larsi@gnus.org>,
>  49407@debbugs.gnu.org, Nicolas Petton <nicolas@petton.fr>,
>  Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Fri, 28 Jul 2023 20:02:08 +0200
> From:  "Basil L. Contovounesios" via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
> 
> Okam via "Bug reports for GNU Emacs, the Swiss army knife of text editors" [2023-07-27 01:39 +0000] wrote:
> 
> > From 99208ca640d4944c57082772702cb8534fe91d32 Mon Sep 17 00:00:00 2001
> > From: Earl Hyatt <okamsn@protonmail.com>
> 
> I think your past contributions were under "Earl Hyatt
> <ej32u@protonmail.com>", right?  Is okamsn@protonmail.com your current
> address?  Eli, does it make a difference for the CA, do we need to
> update .mailmap, or anything like that?

The CA record is up to date for Earl Hyatt.  No action is required.

etc/AUTHORS only mentions the name, not the email address, so no
action is needed there, either.





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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-28 18:02             ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-28 19:19               ` Eli Zaretskii
@ 2023-07-29  0:37               ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-30 13:53                 ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 18+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-29  0:37 UTC (permalink / raw)
  To: Basil L. Contovounesios, Michael Heerdegen
  Cc: Lars Ingebrigtsen, 49407, Nicolas Petton, Stefan Monnier

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

Basil L. Contovounesios wrote:
> Okam via "Bug reports for GNU Emacs, the Swiss army knife of text editors" [2023-07-27 01:39 +0000] wrote:
> 
>>  From 99208ca640d4944c57082772702cb8534fe91d32 Mon Sep 17 00:00:00 2001
>> From: Earl Hyatt <okamsn@protonmail.com>
> 
> I think your past contributions were under "Earl Hyatt
> <ej32u@protonmail.com>", right?  Is okamsn@protonmail.com your current
> address?  Eli, does it make a difference for the CA, do we need to
> update .mailmap, or anything like that?

Yes, I changed addresses. The mailmap makes it look like I used the old 
address in `git log`. Would it be OK to make it so that the old address 
shows as the new one instead?

>> Date: Thu, 20 Jul 2023 21:44:41 -0400
>> Subject: [PATCH v3] Allow default values in 'map-let' and the pcase 'map' form
>>
>> * lisp/emacs-lisp/map.el (map-let, map)
>> (map--make-pcase-bindings): Add a third argument for specifying a
>> default value, like in 'map-elt'. (Bug#49407)
>>
>> * lisp/emacs-lisp/map.el (map--make-pcase-bindings): Clarify that keys
>> that aren't found aren't ignored, they actually get the value
>> nil (unless the new default value is given). The overall pattern can
>                                               ^^
>                                               Two spaces here.

Fixed.

>> +Each element in ARGS can be of the form (KEY PAT) or (KEY PAT
>> +DEFAULT), where KEY is the key sought in the map, PAT is a
>> +`pcase' pattern, and DEFAULT is the default value to use if KEY
>> +isn't found.  Both KEY and DEFAULT are evaluated.  If DEFAULT
>> +isn't given, then nil is used.
> 
> FWIW, the form/structure can be kept on a single line, and a couple of
> passive voices avoided, by rewording as e.g.
> 
>    Each element of ARGS can be of the form (KEY PAT [DEFAULT]),
>    which looks up KEY in the map and matches the associated value
>    against `pcase' pattern PAT.  DEFAULT specifies the fallback
>    value to use when KEY is not present in the map.  If omitted, it
>    defaults to nil.  Both KEY and DEFAULT are evaluated.

I have changed it to this.

>> +The match fails if:
>> +
>> +- KEY is found and PAT does not match the associated value
>> +
>> +- KEY is not found, DEFAULT is given, and PAT does not match
>> +  DEFAULT
>> +
>> +- KEY is not found, DEFAULT is not given, and PAT does not match
>> +  nil"
> 
> I find this partly redundant/repetitive, since we already know that PAT
> is meant to match either KEY's value (when found), or DEFAULT (which
> defaults to nil).
> 
> What this doesn't make explicit (compared to the previous version) is
> what happens when there are multiple ARGS; specifically, when one or
> more of them don't match.

I changed it to "An element of ARGS fails to match if PAT does not match 
the associated value or the default value.  The overall pattern fails
to match if any element of ARGS fails to match." Does that work?

>> +KEYS can also be a list of (KEY VARNAME) pairs and
>> +\(KEY VARNAME DEFAULT) triples, in which case KEY and
> 
> This could also use (KEY VARNAME [DEFAULT]) syntax, if preferred.

Changed.

Thank you.

[-- Attachment #2: v4-0001-Allow-default-values-in-map-let-and-the-pcase-map.patch --]
[-- Type: text/x-patch, Size: 6529 bytes --]

From 74616d0717c520747328587cf1551399eb11a318 Mon Sep 17 00:00:00 2001
From: Earl Hyatt <okamsn@protonmail.com>
Date: Thu, 20 Jul 2023 21:44:41 -0400
Subject: [PATCH v4] Allow default values in 'map-let' and the pcase 'map' form

* lisp/emacs-lisp/map.el (map-let, map)
(map--make-pcase-bindings): Add a third argument for specifying a
default value, like in 'map-elt'. (Bug#49407)

* lisp/emacs-lisp/map.el (map--make-pcase-bindings): Clarify that keys
that aren't found aren't ignored, they actually get the value
nil (unless the new default value is given).  The overall pattern can
still fail to match if the sub-pattern for the unfound key doesn't
match nil.

* test/lisp/emacs-lisp/map-tests.el (test-map-let-default)
(test-map-plist-pcase-default, test-map-pcase-matches): Add tests,
including for the above item.
---
 lisp/emacs-lisp/map.el            | 33 +++++++++++------
 test/lisp/emacs-lisp/map-tests.el | 59 +++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 10 deletions(-)

diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 7a48ba47434..b55eb431668 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -50,18 +50,20 @@ map
 
 ARGS is a list of elements to be matched in the map.
 
-Each element of ARGS can be of the form (KEY PAT), in which case KEY is
-evaluated and searched for in the map.  The match fails if for any KEY
-found in the map, the corresponding PAT doesn't match the value
-associated with the KEY.
+Each element of ARGS can be of the form (KEY PAT [DEFAULT]),
+which looks up KEY in the map and matches the associated value
+against `pcase' pattern PAT.  DEFAULT specifies the fallback
+value to use when KEY is not present in the map.  If omitted, it
+defaults to nil.  Both KEY and DEFAULT are evaluated.
 
 Each element can also be a SYMBOL, which is an abbreviation of
 a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  When SYMBOL
 is a keyword, it is an abbreviation of the form (:SYMBOL SYMBOL),
 useful for binding plist values.
 
-Keys in ARGS not found in the map are ignored, and the match doesn't
-fail."
+An element of ARGS fails to match if PAT does not match the
+associated value or the default value.  The overall pattern fails
+to match if any element of ARGS fails to match."
   `(and (pred mapp)
         ,@(map--make-pcase-bindings args)))
 
@@ -71,12 +73,13 @@ map-let
 KEYS can be a list of symbols, in which case each element will be
 bound to the looked up value in MAP.
 
-KEYS can also be a list of (KEY VARNAME) pairs, in which case
-KEY is an unquoted form.
+KEYS can also be a list of (KEY VARNAME [DEFAULT]) sublists, in
+which case KEY and DEFAULT are unquoted forms.
 
 MAP can be an alist, plist, hash-table, or array."
   (declare (indent 2)
-           (debug ((&rest &or symbolp ([form symbolp])) form body)))
+           (debug ((&rest &or symbolp ([form symbolp &optional form]))
+                   form body)))
   `(pcase-let ((,(map--make-pcase-patterns keys) ,map))
      ,@body))
 
@@ -595,11 +598,21 @@ map-into
     (map-into \\='((1 . 3)) \\='(hash-table :test eql))"
   (map--into-hash map (cdr type)))
 
+(defmacro map--pcase-map-elt (key default map)
+  "A macro to make MAP the last argument to `map-elt'.
+
+This allows using default values for `map-elt', which can't be
+done using `pcase--flip'.
+
+KEY is the key sought in the map.  DEFAULT is the default value."
+  `(map-elt ,map ,key ,default))
+
 (defun map--make-pcase-bindings (args)
   "Return a list of pcase bindings from ARGS to the elements of a map."
   (mapcar (lambda (elt)
             (cond ((consp elt)
-                   `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt)))
+                   `(app (map--pcase-map-elt ,(car elt) ,(caddr elt))
+                         ,(cadr elt)))
                   ((keywordp elt)
                    (let ((var (intern (substring (symbol-name elt) 1))))
                      `(app (pcase--flip map-elt ,elt) ,var)))
diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el
index 86c0e9e0503..2204743f794 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -577,6 +577,13 @@ test-map-let
     (should (= b 2))
     (should-not c)))
 
+(ert-deftest test-map-let-default ()
+  (map-let (('foo a 3)
+            ('baz b 4))
+      '((foo . 1))
+    (should (equal a 1))
+    (should (equal b 4))))
+
 (ert-deftest test-map-merge ()
   "Test `map-merge'."
   (should (equal (sort (map-merge 'list '(a 1) '((b . 2) (c . 3))
@@ -617,6 +624,58 @@ test-map-plist-pcase
                      (list one two))
                    '(1 2)))))
 
+(ert-deftest test-map-plist-pcase-default ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase-let (((map (:two two 33)
+                                     (:three three 44))
+                                plist))
+                     (list two three))
+                   '(2 44)))))
+
+(ert-deftest test-map-pcase-matches ()
+  (let ((plist '(:two 2)))
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 nil)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three three 44))
+                      (list two three))
+                     (_ 'fail))
+                   '(2 44)))
+
+    (should (equal (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) '(11 . 22)))
+                      (list two a b))
+                     (_ 'fail))
+                   '(2 11 22)))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) 44))
+                      (list two a b))
+                     (_ 'fail))))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b) nil))
+                      (list two a b))
+                     (_ 'fail))))
+
+    (should (equal 'fail
+                   (pcase plist
+                     ((map (:two two 33)
+                           (:three `(,a . ,b)))
+                      (list two a b))
+                     (_ 'fail))))))
+
 (ert-deftest test-map-setf-alist-insert-key ()
   (let ((alist))
     (should (equal (setf (map-elt alist 'key) 'value)
-- 
2.34.1


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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-29  0:37               ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-07-30 13:53                 ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-31  4:02                   ` Michael Heerdegen
  2023-08-06 13:31                   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 18+ messages in thread
From: Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-30 13:53 UTC (permalink / raw)
  To: Okam
  Cc: Michael Heerdegen, Lars Ingebrigtsen, Nicolas Petton, 49407-done,
	Stefan Monnier

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

close 49407 30.1
quit

Okam [2023-07-29 00:37 +0000] wrote:
> Basil L. Contovounesios wrote:
>> Okam [2023-07-27 01:39 +0000] wrote:
>>> From: Earl Hyatt <okamsn@protonmail.com>
>> 
>> I think your past contributions were under "Earl Hyatt
>> <ej32u@protonmail.com>", right?  Is okamsn@protonmail.com your current
>> address?
>
> Yes, I changed addresses. The mailmap makes it look like I used the old 
> address in `git log`.

Oh, sorry, I actually didn't notice you had existing mailmap entries in
place.

> Would it be OK to make it so that the old address 
> shows as the new one instead?

Is okamsn@protonmail.com your canonical address?
If so, what we want is the following, right?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: mailmap.diff --]
[-- Type: text/x-diff, Size: 599 bytes --]

diff --git a/.mailmap b/.mailmap
index 8454eb9154c..0531cc0c290 100644
--- a/.mailmap
+++ b/.mailmap
@@ -51,8 +51,7 @@ David M. Koppelman <koppel@ece.lsu.edu>
 Deniz Dogan <deniz@dogan.se> <deniz.a.m.dogan@gmail.com>
 Dick R. Chiang <dick.r.chiang@gmail.com>
 Dick R. Chiang <dick.r.chiang@gmail.com> dickmao <none>
-Earl Hyatt <ej32u@protonmail.com>
-Earl Hyatt <ej32u@protonmail.com> <okamsn@protonmail.com>
+Earl Hyatt <okamsn@protonmail.com> <ej32u@protonmail.com>
 Edward M. Reingold <reingold@emr.cs.iit.edu>
 Eli Zaretskii <eliz@gnu.org> <eliz@is.elta.co.il>
 Emilio C. Lopes <eclig@gmx.net>

[-- Attachment #3: Type: text/plain, Size: 519 bytes --]


> I changed it to "An element of ARGS fails to match if PAT does not match 
> the associated value or the default value.  The overall pattern fails
> to match if any element of ARGS fails to match." Does that work?

WFM, thank you!  Installed and closing as done:

Allow default values in 'map-let' and the pcase 'map' form
19777b7c864 2023-07-30 15:20:27 +0200
https://git.sv.gnu.org/cgit/emacs.git/commit/?id=19777b7c864

I'll also bump the map.el Version header in a week or so if no-one beats
me to it.

-- 
Basil

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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-30 13:53                 ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-07-31  4:02                   ` Michael Heerdegen
  2023-08-08 12:41                     ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-08-06 13:31                   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 18+ messages in thread
From: Michael Heerdegen @ 2023-07-31  4:02 UTC (permalink / raw)
  To: 49407
  Cc: Basil L. Contovounesios, Nicolas Petton, Okam, Stefan Monnier,
	Lars Ingebrigtsen, 49407-done

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

"Basil L. Contovounesios" via "Bug reports for GNU Emacs, the Swiss army
knife of text editors" <bug-gnu-emacs@gnu.org> writes:

> WFM, thank you!  Installed and closing as done:
>
> Allow default values in 'map-let' and the pcase 'map' form
> 19777b7c864 2023-07-30 15:20:27 +0200
> https://git.sv.gnu.org/cgit/emacs.git/commit/?id=19777b7c864

Does this addition look appropriate?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Docstring-tweaks-in-map.el.patch --]
[-- Type: text/x-diff, Size: 2159 bytes --]

From b2b6f34c08c17a9411c4264ea500b434c833ec04 Mon Sep 17 00:00:00 2001
From: Michael Heerdegen <michael_heerdegen@web.de>
Date: Tue, 25 Jul 2023 20:38:46 +0200
Subject: [PATCH] ; Docstring tweaks in map.el

* lisp/emacs-lisp/map.el (pcase-defmacro) <map>:
(map-let): Mention 'map-elt' where equality predicates are explained.
Improve wording.
---
 lisp/emacs-lisp/map.el | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index b55eb431668..04c00a2e908 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -57,9 +57,10 @@ map
 defaults to nil.  Both KEY and DEFAULT are evaluated.

 Each element can also be a SYMBOL, which is an abbreviation of
-a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  When SYMBOL
-is a keyword, it is an abbreviation of the form (:SYMBOL SYMBOL),
-useful for binding plist values.
+a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  A keyword :FOO
+is an abbreviation of the form (:FOO FOO), useful for binding plist values.
+
+See `map-elt' for an explanation of the used equality tests.

 An element of ARGS fails to match if PAT does not match the
 associated value or the default value.  The overall pattern fails
@@ -70,13 +71,13 @@ map
 (defmacro map-let (keys map &rest body)
   "Bind the variables in KEYS to the elements of MAP then evaluate BODY.

-KEYS can be a list of symbols, in which case each element will be
-bound to the looked up value in MAP.
-
-KEYS can also be a list of (KEY VARNAME [DEFAULT]) sublists, in
-which case KEY and DEFAULT are unquoted forms.
+Elements of the list KEYS can be symbols, in which case each
+will be bound to the looked up value in MAP, or
+(KEY VARNAME [DEFAULT]) sublists where KEY and DEFAULT are
+unquoted forms.

-MAP can be an alist, plist, hash-table, or array."
+MAP can be an alist, plist, hash-table, or array.  See `map-elt'
+for an explanation of the used equality tests."
   (declare (indent 2)
            (debug ((&rest &or symbolp ([form symbolp &optional form]))
                    form body)))
--
2.30.2


[-- Attachment #3: Type: text/plain, Size: 295 bytes --]



If it's not clear: I changed :SYMBOL to :FOO because the original text
called SYMBOL a keyword and then used SYMBOL and :SYMBOL (although then
only :SYMBOL would be the keyword) - I found that confusing.  :KEYWORD
would also be confusing, so I went with the placeholder "FOO".

TIA,

Michael.

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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-30 13:53                 ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-07-31  4:02                   ` Michael Heerdegen
@ 2023-08-06 13:31                   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-08-08 12:46                     ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 18+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-08-06 13:31 UTC (permalink / raw)
  To: Basil L. Contovounesios
  Cc: Michael Heerdegen, Lars Ingebrigtsen, Nicolas Petton, 49407-done,
	Stefan Monnier

Basil L. Contovounesios wrote:
>> Would it be OK to make it so that the old address
>> shows as the new one instead?
> 
> Is okamsn@protonmail.com your canonical address?
> If so, what we want is the following, right?

Yes, thank you.

> 
>> I changed it to "An element of ARGS fails to match if PAT does not match
>> the associated value or the default value.  The overall pattern fails
>> to match if any element of ARGS fails to match." Does that work?
> 
> WFM, thank you!  Installed and closing as done:
> 
> Allow default values in 'map-let' and the pcase 'map' form
> 19777b7c864 2023-07-30 15:20:27 +0200
> https://git.sv.gnu.org/cgit/emacs.git/commit/?id=19777b7c864
> 
> I'll also bump the map.el Version header in a week or so if no-one beats
> me to it.

Thanks!







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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-07-31  4:02                   ` Michael Heerdegen
@ 2023-08-08 12:41                     ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 18+ messages in thread
From: Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-08-08 12:41 UTC (permalink / raw)
  To: Michael Heerdegen
  Cc: Okam, Lars Ingebrigtsen, 49407, Nicolas Petton, Stefan Monnier

Michael Heerdegen [2023-07-31 06:02 +0200] wrote:

> Does this addition look appropriate?

Reads fine to me, so AFAIC feel free to install.
Just a couple of thoughts inline:

> diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
> index b55eb431668..04c00a2e908 100644
> --- a/lisp/emacs-lisp/map.el
> +++ b/lisp/emacs-lisp/map.el
> @@ -57,9 +57,10 @@ map
>  defaults to nil.  Both KEY and DEFAULT are evaluated.
>
>  Each element can also be a SYMBOL, which is an abbreviation of
> -a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  When SYMBOL
> -is a keyword, it is an abbreviation of the form (:SYMBOL SYMBOL),
> -useful for binding plist values.
> +a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  A keyword :FOO
> +is an abbreviation of the form (:FOO FOO), useful for binding plist values.

If you prefer to keep the stronger connectedness(?) between the
sentences, and/or avoid introducing a metaname with no inherent meaning:

                                                      Specifically
  when SYMBOL is a keyword :KEY, it is an abbreviation of the
  form (:KEY KEY), which can be useful for binding plist values.

> +See `map-elt' for an explanation of the used equality tests.

s/used/relevant/ would avoid the passive voice, if you prefer.
Or 'for details on key lookup', or ...

[ Trying to get on Eli's non-naughty list. ]

> If it's not clear: I changed :SYMBOL to :FOO because the original text
> called SYMBOL a keyword and then used SYMBOL and :SYMBOL (although then
> only :SYMBOL would be the keyword) - I found that confusing.  :KEYWORD
> would also be confusing, so I went with the placeholder "FOO".

I'm confused, I thought FOO stood For Obfuscation Only ;).

Thanks,
-- 
Basil





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

* bug#49407: Request: Specify default values in `map-let` in Map.el
  2023-08-06 13:31                   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-08-08 12:46                     ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 18+ messages in thread
From: Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-08-08 12:46 UTC (permalink / raw)
  To: Okam
  Cc: Michael Heerdegen, Lars Ingebrigtsen, 49407, Nicolas Petton,
	Stefan Monnier

Okam [2023-08-06 13:31 +0000] wrote:
> Basil L. Contovounesios wrote:
>>> Would it be OK to make it so that the old address
>>> shows as the new one instead?
>> Is okamsn@protonmail.com your canonical address?
>> If so, what we want is the following, right?
>
> Yes, thank you.

Done:

; .mailmap: Flip entry.
91854ceaee3 2023-08-08 14:43:22 +0200
https://git.sv.gnu.org/cgit/emacs.git/commit/?id=91854ceaee3

Thanks,
-- 
Basil





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

end of thread, other threads:[~2023-08-08 12:46 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-04 23:08 bug#49407: Request: Specify default values in `map-let` in Map.el Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-07-15  8:51 ` Lars Ingebrigtsen
2021-07-16  1:45   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-07-21  2:56   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-07-22  1:48     ` Michael Heerdegen
2023-07-22 15:45       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-07-22 18:46       ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-07-26  3:41         ` Michael Heerdegen
2023-07-27  1:39           ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-07-28 18:02             ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-07-28 19:19               ` Eli Zaretskii
2023-07-29  0:37               ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-07-30 13:53                 ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-07-31  4:02                   ` Michael Heerdegen
2023-08-08 12:41                     ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-08-06 13:31                   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-08-08 12:46                     ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-07-27  1:37 ` Earl Hyatt via Bug reports for GNU Emacs, the Swiss army knife of text editors

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