From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Okam Newsgroups: gmane.emacs.help Subject: Re: How to extract bindings from `pcase-let*`? Date: Wed, 17 Mar 2021 01:33:46 +0000 Message-ID: References: <319f8b2c-7ffc-9a26-0b7b-fe488036c77e@protonmail.com> <3217e2b9-1b58-1984-ba0a-4526e76cfb4d@protonmail.com> Reply-To: Okam Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="28525"; mail-complaints-to="usenet@ciao.gmane.io" To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Wed Mar 17 02:34:33 2021 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lML4z-0007HW-Ks for geh-help-gnu-emacs@m.gmane-mx.org; Wed, 17 Mar 2021 02:34:33 +0100 Original-Received: from localhost ([::1]:44158 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lML4y-0004tW-NA for geh-help-gnu-emacs@m.gmane-mx.org; Tue, 16 Mar 2021 21:34:32 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:50918) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lML4T-0004r5-US for help-gnu-emacs@gnu.org; Tue, 16 Mar 2021 21:34:02 -0400 Original-Received: from mail-40133.protonmail.ch ([185.70.40.133]:62873) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lML4Q-0002zd-Qb for help-gnu-emacs@gnu.org; Tue, 16 Mar 2021 21:34:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail; t=1615944835; bh=wjQCktr+RY2+GdJqACyOUFAU0IpE7Fubox+FrNKSnDE=; h=Date:To:From:Reply-To:Subject:In-Reply-To:References:From; b=iaq5VVuypaIuXMbq5m4creAzmM3ohmEds3RisVyj+p6pTLMZqGUAVZgNHxdft40WF L2gfHa7wc4HzLtXEWAqSGzAQafs4DOpGRwEJV87xF3FTrfcUwb0NIFMt72SFV+7wN1 AtPtXkZ/PcNlyuxSBQkUsc2SsDuoyg6pjjMIzboo= In-Reply-To: Received-SPF: pass client-ip=185.70.40.133; envelope-from=okamsn@protonmail.com; helo=mail-40133.protonmail.ch X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "help-gnu-emacs" Xref: news.gmane.io gmane.emacs.help:128426 Archived-At: On 3/15/21 10:45 PM, Stefan Monnier wrote: > >> (pcase-let* ((`(let* ,temp-vars (let ,true-vars . ,_)) >> (macroexpand `(pcase-let* ((,var ,val)) ,var)))) >> (list temp-vars true-vars))) > > Indeed it's not reliable: for a case like > > (pcase-let (((or `(inorder ,x ,y) `(reverse ,y ,x)) FOO)) > (cons x y)) > > it will generate code comparable to > > (if (eq (car FOO) 'inorder) > (cons (nth 1 FOO) (nth 2 FOO)) > (cons (nth 2 FOO) (nth 1 FOO)) > > [ Just obfuscated with gensym'd vars and such ] > > And if you replace the trivial (cons x y) with something less trivial it > will turn into something comparable to: > > (let ((body (lambda (x y) ))) > (if (eq (car FOO) 'inorder) > (funcall body (nth 1 FOO) (nth 2 FOO)) > (funcall body (nth 2 FOO) (nth 1 FOO)))) > > so it's far from clear how to represent this kind of code in the form of > "a list of bindings that can be substituted into forms like `setq` or > `let*`" > > OTOH, I think `pcase.el` could offer a function which could take > a "buildbody" function as argument, where that buildbody would receive > something like the list (x y) and would be expected to return the > (lambda (x y) ) to use. So you could pass it a "= buildbody" > function which takes the list (x y) and returns something like > (lambda (tmp1 tmp2) (setq x tmp1 y tmp2)), which I expect would do more > or less what you want. > >> I am doing this to attempt to optionally use Pcase for destructuring in >> a macro that I am writing. > > `pcase-let` already does destructuring, so could you explain in a bit > more detail what kind of destructuring you're looking for (and why)? > > > Stefan > > I am writing a looping macro similar to `cl-loop`, and have allowed for destructuring in accumulation clauses. Here are some examples: ;; Summing the nth elements of arrays: ;; =3D> (8 10 12 14 16 18) (loopy (list (list-elem1 list-elem2) '(([1 2 3] [4 5 6]) ([7 8 9] [10 11 12]))) (sum [sum1 sum2 sum3] list-elem1) (sum [sum4 sum5 sum6] list-elem2)) ;; Or, more simply: ;; =3D> (8 10 12 14 16 18) (loopy (list list-elem '(([1 2 3] [4 5 6]) ([7 8 9] [10 11 12]))) (sum ([sum1 sum2 sum3] [sum4 sum5 sum6]) list-elem)) ;; Separate the elements of sub-list: ;; =3D> ((1 3) (2 4)) (loopy (list i '((1 2) (3 4))) (collect (elem1 elem2) i)) There is a built-in destructuring system for this in the macro, but a user requested a way to use other destructuring systems, such as Dash, Pcase, or `seq-let`. To do this for accumulation, I don't want to actually assign the values determined by Dash or Pcase to the variables named by the user. Instead, I want to accumulate those values into the named variables. Here is an example of the macro that I tested with Pcase (before I realized my mistake) ;; =3D> ((1 4) (3 6)) (loopy (flag pcase) (list elem '((1 (2 3)) (4 (5 6)))) (collect `(,a (,_ ,b)) elem)) in which the `collect` expression expands into something like (setq a (append a (list some-value-from-elem))) (setq b (append b (list some-other-value-from-elem))) where `some-value-from-elem` and `some-other-value-from-elem` are determined by Pcase, Dash, or other destructuring systems. Do you think that this is doable using Pcase? A link to the macro: https://github.com/okamsn/loopy