unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#47261: Destructuring with Pcase without assigning values
@ 2021-03-19 13:47 Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2021-03-19 21:45 ` Stefan Monnier
  0 siblings, 1 reply; 7+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-03-19 13:47 UTC (permalink / raw)
  To: 47261; +Cc: monnier

X-Debbugs-Cc: monnier@iro.umontreal.ca

Hello.

For a Pcase pattern, it would be convenient to have Pcase destructure
the pattern and have a way to see what values Pcase would like to assign
to variables within the pattern.

This would allow one to know the variables found in the pattern and to
manipulate the values that Pcase would like to assign, instead of just
letting `pcase` assign them.

This was asked about on the Help mailing list:
https://lists.gnu.org/archive/html/help-gnu-emacs/2021-03/msg00089.html

Thank you.






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

* bug#47261: Destructuring with Pcase without assigning values
  2021-03-19 13:47 bug#47261: Destructuring with Pcase without assigning values Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2021-03-19 21:45 ` Stefan Monnier
  2021-04-17  1:24   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2022-06-24 18:36   ` Lars Ingebrigtsen
  0 siblings, 2 replies; 7+ messages in thread
From: Stefan Monnier @ 2021-03-19 21:45 UTC (permalink / raw)
  To: Okam; +Cc: 47261

> For a Pcase pattern, it would be convenient to have Pcase destructure
> the pattern and have a way to see what values Pcase would like to assign
> to variables within the pattern.
>
> This would allow one to know the variables found in the pattern and to
> manipulate the values that Pcase would like to assign, instead of just
> letting `pcase` assign them.

I massaged the code so that it now exports the following function:

    (defun pcase-compile-patterns (exp cases)
      "Compile the set of patterns in CASES.
    EXP is the expression that will be matched against the patterns.
    CASES is a list of elements (PAT . CODEGEN)
    where CODEGEN is a function that returns the code to use when
    PAT matches.  That code has to be in the form of a cons cell.
    
    CODEGEN will be called with at least 2 arguments, VARVALS and COUNT.
    VARVALS is a list of elements of the form (VAR VAL . RESERVED) where VAR
    is a variable bound by the pattern and VAL is a duplicable expression
    that returns the value this variable should be bound to.
    If the pattern PAT uses `or', CODEGEN may be called multiple times,
    in which case it may want to generate the code differently to avoid
    a potential code explosion.  For this reason the COUNT argument indicates
    how many time this CODEGEN is called."

The `pcase` macro itself uses this function, so it should hopefully be
"good enough", but let me know if it's causing you trouble.


        Stefan






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

* bug#47261: Destructuring with Pcase without assigning values
  2021-03-19 21:45 ` Stefan Monnier
@ 2021-04-17  1:24   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2021-04-17  3:22     ` Stefan Monnier
  2022-06-24 18:36   ` Lars Ingebrigtsen
  1 sibling, 1 reply; 7+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-04-17  1:24 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 47261

On 3/19/21 5:45 PM, Stefan Monnier wrote:
> I massaged the code so that it now exports the following function:
>
>      (defun pcase-compile-patterns (exp cases)
>        "Compile the set of patterns in CASES.
>      EXP is the expression that will be matched against the patterns.
>      CASES is a list of elements (PAT . CODEGEN)
>      where CODEGEN is a function that returns the code to use when
>      PAT matches.  That code has to be in the form of a cons cell.
>
>      CODEGEN will be called with at least 2 arguments, VARVALS and COUNT.
>      VARVALS is a list of elements of the form (VAR VAL . RESERVED) where VAR
>      is a variable bound by the pattern and VAL is a duplicable expression
>      that returns the value this variable should be bound to.
>      If the pattern PAT uses `or', CODEGEN may be called multiple times,
>      in which case it may want to generate the code differently to avoid
>      a potential code explosion.  For this reason the COUNT argument indicates
>      how many time this CODEGEN is called."
>
> The `pcase` macro itself uses this function, so it should hopefully be
> "good enough", but let me know if it's causing you trouble.
>
>
>          Stefan
>

This seems to work well for my use case. Thank you for making this change.

Are the variables always given in the order that they appear in the
pattern? If not, is finding elements of the form "(\, SYMBOL)" enough to
identify variables in a Pcase pattern?






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

* bug#47261: Destructuring with Pcase without assigning values
  2021-04-17  1:24   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2021-04-17  3:22     ` Stefan Monnier
       [not found]       ` <1dacded9-3e40-bc02-56c7-a157d739ffb7@protonmail.com>
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Monnier @ 2021-04-17  3:22 UTC (permalink / raw)
  To: Okam; +Cc: 47261

>> The `pcase` macro itself uses this function, so it should hopefully be
>> "good enough", but let me know if it's causing you trouble.
> This seems to work well for my use case. Thank you for making this change.

You're welcome.  It was actually a good change for the code's
readability as well.

> Are the variables always given in the order that they appear in the
> pattern?

I don't know.  Why?

> If not, is finding elements of the form "(\, SYMBOL)" enough to
> identify variables in a Pcase pattern?

No.  , is not even one of the core pcase patterns, it's only something
used within the ` pattern (which is not a core pattern either; it is
defined via `pcase-defmacro`).


        Stefan






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

* bug#47261: Fwd: bug#47261: Destructuring with Pcase without assigning values
       [not found]       ` <1dacded9-3e40-bc02-56c7-a157d739ffb7@protonmail.com>
@ 2021-04-19 22:06         ` Earl Hyatt via Bug reports for GNU Emacs, the Swiss army knife of text editors
       [not found]         ` <jwveef84hcl.fsf-monnier+emacs@gnu.org>
  1 sibling, 0 replies; 7+ messages in thread
From: Earl Hyatt via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-04-19 22:06 UTC (permalink / raw)
  To: 47261


For the record, I am forwarding this reply to the bug tracker. I forgot
to send the original message to the tracker.

-------- Forwarded Message --------
Subject: Re: bug#47261: Destructuring with Pcase without assigning values
Date: Sat, 17 Apr 2021 18:50:10 -0400
From: Okam <okamsn@protonmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>

On 4/16/21 11:22 PM, Stefan Monnier wrote:
>
>>> The `pcase` macro itself uses this function, so it should hopefully be
>>> "good enough", but let me know if it's causing you trouble.
>> This seems to work well for my use case. Thank you for making this change.
>
> You're welcome.  It was actually a good change for the code's
> readability as well.
>
>> Are the variables always given in the order that they appear in the
>> pattern?
>
> I don't know.  Why? >
>> If not, is finding elements of the form "(\, SYMBOL)" enough to
>> identify variables in a Pcase pattern?
>
> No.  , is not even one of the core pcase patterns, it's only something
> used within the ` pattern (which is not a core pattern either; it is
> defined via `pcase-defmacro`).
>
>
>          Stefan
>

In the `cl-loop`-like macro that I am writing, things are currently set
up so that variables being assigned values in accumulation clauses can
be automatically used as the return value of the macro.

      ;; => ((1 3 5) (2 4 6))
      (loopy (flag pcase)
             (list i '((1 2) (3 4) (5 6)))
             (collect `(,a ,b) i))

This behavior requires finding the variables in the correct order.

The getting of the variables used ("a" and "b" above) can be done when
using the new `pcase-compile-pattern`, if the variables are fed to the
CODEGEN argument in the order that they are written, or I can try to
find them manually, if possible.

If neither are possible, then I will just remove this behavior.

Thank you.






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

* bug#47261: Fwd: bug#47261: Destructuring with Pcase without assigning values
       [not found]           ` <4925d1a5-4669-8290-e534-1662f13ca183@protonmail.com>
@ 2021-04-19 22:10             ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 7+ messages in thread
From: Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-04-19 22:10 UTC (permalink / raw)
  To: 47261

For the record, I am forwarding this reply to the bug tracker. I forgot
to send the original message to the tracker.


-------- Forwarded Message --------
Subject: Re: bug#47261: Destructuring with Pcase without assigning values
Date: Sun, 18 Apr 2021 15:15:00 -0400
From: Okam <okamsn@protonmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>

On 4/17/21 7:37 PM, Stefan Monnier wrote:
>
>> In the `cl-loop`-like macro that I am writing, things are currently set
>> up so that variables being assigned values in accumulation clauses can
>> be automatically used as the return value of the macro.
>>
>>       ;; => ((1 3 5) (2 4 6))
>>       (loopy (flag pcase)
>>              (list i '((1 2) (3 4) (5 6)))
>>              (collect `(,a ,b) i))
>>
>> This behavior requires finding the variables in the correct order.
>>
>> The getting of the variables used ("a" and "b" above) can be done when
>> using the new `pcase-compile-pattern`, if the variables are fed to the
>> CODEGEN argument in the order that they are written, or I can try to
>> find them manually, if possible.
>
> I still don't understand.  AFAICT what the (collect `(,a ,b) i) above is
> expected to do is something more or less equivalent to:
>
>      (push (car i) a)
>      (push (cadr i) b)
>
> right?
>
> So a CODEGEN which does
>
>     (lambda (varvals _count &rest _)
>       (mapcar (lambda (varval)
>                 `(push ,(cadr varval) ,(car varval)))
>               varvals))
>
> should do the trick, regardless of the order in which the vars
> are passed.
>
> I think I'm still missing something in your explanation.
>
>
>          Stefan
>

What I mean to say is that, if possible, I would like to add the
variables in the pattern to a list of values to return.  This requires
identifying the symbols which represent the variables.

Using CODEGEN works for setting the values, yes, and is not sensitive to
the order in which it receives variables. However, I am currently using
the CODEGEN step to add the variables to a list of returned values,
since CODEGEN is already being given the symbol for each variable.

I am trying to have it so that these variables are listed in the return
value in the same order that they are listed in the pattern.

For example, this

      ;; => (4 6)
      (loopy (flag pcase)
             (list i '([1 2] [3 4]))
             (sum `[,sum1 ,sum2] i))

currently expands to

      (let ((sum2 0)
            (sum1 0))
        (let* ((list-108 '([1 2] [3 4]))
               (i nil))
          (cl-block nil
            (while (consp list-108)
              (setq i (car list-108))
              (if (vectorp i)
                  (let* ((x109 (length i)))
                    (if (eql x109 2)
                        (let* ((x110 (pcase--flip aref 0 i))
                               (x111 (pcase--flip aref 1 i)))
                          (progn
                            (setq sum2 (+ x111 sum2))
                            (setq sum1 (+ x110 sum1)))))))
              (setq list-108 (cdr list-108)))
            (list sum1 sum2))))

where `sum1` and `sum2` are in the same order that they appear in the
pattern.  This works with what I have tested, but I am unsure of whether
it is dependable.

So, I am asking whether the variables passed to CODEGEN can be relied on
to be in a particular order for destructuring patterns, or whether there
is a good way to find the variables and their order manually.

For example, for `seq-let`-like destructuring, my experience is that the
variables are given in the reverse order and that variables can be
identified as symbols that are not `&rest`.






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

* bug#47261: Destructuring with Pcase without assigning values
  2021-03-19 21:45 ` Stefan Monnier
  2021-04-17  1:24   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2022-06-24 18:36   ` Lars Ingebrigtsen
  1 sibling, 0 replies; 7+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-24 18:36 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Okam, 47261

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> I massaged the code so that it now exports the following function:
>
>     (defun pcase-compile-patterns (exp cases)
>       "Compile the set of patterns in CASES.

Skimming this thread, it seems like this fixed the request, so I'm
closing this bug report.  (The discussion then went on to discuss some
things related to this feature, but if I understood correctly, Earl
adjusted his code to fit it.)  If I misunderstood, please respond to the
debbugs address and we'll reopen.

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





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

end of thread, other threads:[~2022-06-24 18:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-19 13:47 bug#47261: Destructuring with Pcase without assigning values Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-03-19 21:45 ` Stefan Monnier
2021-04-17  1:24   ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-04-17  3:22     ` Stefan Monnier
     [not found]       ` <1dacded9-3e40-bc02-56c7-a157d739ffb7@protonmail.com>
2021-04-19 22:06         ` bug#47261: Fwd: " Earl Hyatt via Bug reports for GNU Emacs, the Swiss army knife of text editors
     [not found]         ` <jwveef84hcl.fsf-monnier+emacs@gnu.org>
     [not found]           ` <4925d1a5-4669-8290-e534-1662f13ca183@protonmail.com>
2021-04-19 22:10             ` Okam via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-24 18:36   ` Lars Ingebrigtsen

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