GNU bug report logs - #43100
28.0.50; pcase not binding variables conditionally

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: emacs; Reported by: Pip Cet <pipcet@HIDDEN>; dated Sat, 29 Aug 2020 09:42:02 UTC; Maintainer for emacs is bug-gnu-emacs@HIDDEN.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 5 Sep 2020 14:37:36 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Sep 05 10:37:36 2020
Received: from localhost ([127.0.0.1]:43762 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kEZJv-0007KZ-M9
	for submit <at> debbugs.gnu.org; Sat, 05 Sep 2020 10:37:36 -0400
Received: from mail-ot1-f46.google.com ([209.85.210.46]:46996)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pipcet@HIDDEN>) id 1kEZJu-0007KN-16
 for 43100 <at> debbugs.gnu.org; Sat, 05 Sep 2020 10:37:34 -0400
Received: by mail-ot1-f46.google.com with SMTP id c10so8507930otm.13
 for <43100 <at> debbugs.gnu.org>; Sat, 05 Sep 2020 07:37:33 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc:content-transfer-encoding;
 bh=KoEvJTaciOlZwHYJzLNJXGVXlns5fQWePGI51mywaSA=;
 b=Jvjzq3yowCP7n3GhqDNvTZkjcAPrBaGzAFRjeiBFiSIaiCAuN8iCZwEmZyJMXbtO3G
 OoA7nDyeyFgYpijM+jp5UmDKC519zxcA/GCVQIssqkj9uLUkqOisGZ60FaoGYlt6xCzc
 SzH5ZS0ZPYnBrq8zXp31iqZVf7VlaH6kAuZ4YdzdWln2LY18bt8xmaaVo38QtkWeN7nQ
 23dHF+Q8ziT6Aco4hF1zPyxynJLwFG4f5szhL+e4vwLtvca3cIGxDOUgWZP78jd1Czpp
 IcU/OAFggGTh7cRpVVHFtNs+Bs6RXEiQNa8kkgUUwqqjFwU7KBvHTAH+pKDo/91hxwhI
 wKyg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc:content-transfer-encoding;
 bh=KoEvJTaciOlZwHYJzLNJXGVXlns5fQWePGI51mywaSA=;
 b=jG6es6tj9xYlatVUOQiLdV7k4q7CnQ8PvCDdedf25CqR7nqLhrgvXxSnGKqQbXhFte
 V+ofk4NmqCadb3+ejxekGkSNEFeukj+iCHEsffsymHuOEWuh2lqZYEtpR/qMeKA/Q7kL
 LjteoRr7QZ5vX/9tP8yCaQcbrm7YruMflzcFS0/7YXZl/kxcLUyueizP/RGO/8/kSRoO
 e2WCpPdF/XD4Rex+3Br/Wiw31hoc1PKEItEFPh2SAgA1QqoMVB7Hr+R70fpAGYNNdgwp
 ZHLo+ldwhq7dIgr+JYU/2L1Ds1+XeBfN0SgZvCVwCC2tnWxUR1EDX1li27oIqUMnkfTx
 x9wA==
X-Gm-Message-State: AOAM532gD3BgX7PsVTRYMY7LsN+7J/Mb31wIG8zwtq5BAdPzbdhSWf2q
 vYfWnt0IGHmUa/o8auA5AsDAJeiMCEsQUMNMi4c=
X-Google-Smtp-Source: ABdhPJyOtGkAh0NCWm0bViwZ1tHL3IrfP9NejaEig7Z3/lGWlkBMKOjQ6k/N6h1fQqUYnF/NiYRgSONhnj0sJYxp8Wo=
X-Received: by 2002:a9d:2c43:: with SMTP id f61mr9754529otb.154.1599316648114; 
 Sat, 05 Sep 2020 07:37:28 -0700 (PDT)
MIME-Version: 1.0
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
 <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
 <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
 <jwvpn791m8z.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBeXLHsbZtcWypng4+DpFtkXBs-+DTkCP3BSFRbThdJpQQ@HIDDEN>
 <jwvr1roysef.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBf8OVdK-JeQjCDjTsOjjO6kuwo+mjEeJ3-JB1d4hN1KYA@HIDDEN>
 <jwva6yatfzo.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBcMHZOnpRscxAmPOn3PaMDOGhzaNykgnrOvBtCeWUQ0Tw@HIDDEN>
 <jwveenknvw3.fsf-monnier+emacs@HIDDEN>
In-Reply-To: <jwveenknvw3.fsf-monnier+emacs@HIDDEN>
From: Pip Cet <pipcet@HIDDEN>
Date: Sat, 5 Sep 2020 14:36:50 +0000
Message-ID: <CAOqdjBdsFX0wZBCHy0yO2G7OWwUi+XDHKTLdKkSD95B-Y5Rb-Q@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
To: Stefan Monnier <monnier@HIDDEN>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 43100
Cc: Philipp Stephani <p.stephani2@HIDDEN>, 43100 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Wed, Sep 2, 2020 at 2:16 PM Stefan Monnier <monnier@HIDDEN> wr=
ote:
> >> I just want the complexity to be predictable without having to guess
> >> which optimization will be applicable.
> > So it's better to have a predictably-bad `append' rather than a
> > sometimes-bad one?
> In my book, yes.

That's a very unusual book! This isn't real-time programming or
crypto, so I fail to see the damage "faster is better" might cause
here.

> > But how does that affect ,@? We could make that predictably bad, too!
>
> I think the expectation (coming from the use of ,@ in non-patterns)
> would be that it is fairly cheap, but yes, I guess it's an option.
> Could be coupled with a warning when ,@ can be replaced by an efficient
> `. ,`.

I don't think we should warn about that; we should simply do the best
we can do, and warn the user when that's surprisingly bad (i.e. when
we have to iterate over the list building sublists).

> >> >> More specifically, I'd rather not choose a semantics that imposes
> >> >> duplicating the branch body, since we have no control over its size=
 and
> >> >> that can hence lead to potential code size explosion.
> >> > You're right, and it's a good thing that the duplication of the bran=
ch
> >> > body is a fixable implementation detail rather than something impose=
d
> >> > by the semantics.
> >> It's only fixable if you disregard the "more or less" above.
> >> I find it to be a pretty bad wrinkle in the semantics.
> > So setq the outer binding if it changed?
> Oh, yuck!  That'd be adding injury to insult.

Would work, though!

> >> >> The design of `pcase` assumes you want to optimize away the tests t=
hat
> >> >> are common to the various patterns.  That can't be done with dynami=
c
> >> >> patterns.
> >> > Or it's a bit more difficult, at least...
> >> I think it's more than "a bit more difficult", because deciding how to
> >> optimize the tests will almost always take significantly more time tha=
n
> >> just doing the tests.  So in order to do it dynamically and be useful,
> >> you still need to have 2 stages, where you optimize at one stage and
> >> then use the result several times later (to recoup the cost of the
> >> optimization).
> > Wait, I think there was a misunderstanding here. I don't mean that the
> > pcase pattern should depend structurally on let-bound variables
> > appearing in it. That does sound impossible to me (except with dynamic
> > scoping).
>
> To me "dynamic patterns" means patterns which are only know at run time
> because the pattern itself depends on a runtime value, as in something li=
ke:
>
>     (let ((pat (if FOO '(pred symbolp) '1)))
>       ...
>       (pcase V
>         ...
>         ((match pat) EXP)
>         ...))
>
> Not sure what you meant by it, then.

I didn't mean anything by "dynamic patterns" because I didn't use the term =
:-)

What I meant was using SYMBOL as short-hand for (pred (equal SYMBOL))
when it's not in a white-list of symbols to be bound instead of
compared. That was the intention of my example. I think dynamic
patterns, as you use the term, should be possible (IIUC, they're not,
with lexical binding), but punitively slow (I don't think we have to
worry about that last part...), but that's an entirely different
discussion.

> >> We have `help-function-arglist`, so it's not that hard.
> >> But it's not guaranteed to work.
> > Oh, thanks for pointing that out.  It's not very good, though, is it?
>
> It's good enough for `C-h o`.

C-h o says

(+ &rest NUMBERS-OR-MARKERS) and (1+ NUMBER)

help-function-arglist says

(&rest rest) and (arg1)

The latter is much less useful, IMHO.

> >> I'm sorry, I don't understand what those sexps (and their =C2=ABoption=
al"
> >> non-final parts=C2=BB) have to do with pcase's handling of `or` patter=
ns
> >> where the different branches don't bind the same set of variables.
> > Well, maybe I'm just missing an obvious way of doing it.
> Could be, but I have no idea what "it" is.

Matching something like Emacs defuns, which may have a docstring or
not, I'd like to do

`(defun ,symbol ,@(or `(,(and (pred stringp) docstring))) `())  . ,body)

It seems wasteful to have two almost-identical patterns to match the
variants, and I'd like docstring to have a useful default value.

> >> >> > disallowing the modification of name in X.
> >> >> That's rather hard to do (and I don't see what would be the benefit=
 here).
> >> > I meant adding a cautionary note about it in the documentation, not
> >> > actively preventing it.
> >> So we're replacing the current "don't do that" with another "don't do
> >> that", neither of which is detected by the byte-compiler?
> > Yes. Emacs Lisp isn't free of "don't do that"s, and reducing the
> > "don't do that" space drastically is better than pointing out the tiny
> > fraction of it which remains as evidence that we shouldn't do the
> > reduction in the first place.
>
> I don't see your proposal as reducing the "don't do that" space.

Currently, it's "don't bind variables only in some branches of a pcase
or". With my proposal, it's "feel free to bind variables only in some
branches of a pcase or, but don't modify them". It's a strict subset
relationship.

> >> >> The current implementation amounts to "we should signal an error bu=
t we
> >> >> don't bother doing so and just warn against it in the manual".
> >> >> Patch welcome ;-)
> >> > You mean a patch that would make pcase less powerful by making what =
I
> >> > want to do impossible rather than merely difficult?
> >> The way I see it, it would make what you want to do possible because
> >> what you suggest would merely give meaning to programs previously inva=
lid.
> >> In contrast, with the current behavior your proposal implies breaking
> >> backward compatibility.
> > I think what you mean is you'd rather break backward compatibility in
> > two steps rather than one, by first causing errors, then redefining
> > the new errors not to happen? Because if so, I totally agree.
>
> That's right.  The first (breaking) step would be "my fault" and would
> hence free you to do the second step without introducing
> incompatibilities ;-)

Hooray! Let's do that, then.

> > IOW, I'd like ` (as a pcase macro) to behave like ` already does:
> > constant-time `(,@l), linear-time `(,@l 3).
>
> I suggest you start with a `pip-backquote` pcase-macro and experiment
> with it, to see how useful it is.  You'll then presumably have more
> concrete examples to argue for the replacement of the current `
>
> > And, again, performance of ` is unpredictable unless you know the
> > details of the optimization. Should we get rid of ` next?

> AFAIK performance is O(N) where N is the number of cons cells in the
> output (minus those cons-cells which are preserved as-is, I guess but
> that doesn't make much of a difference).

It means (,@l) is O(1), but (,@l 3) is O(N).

> That seems quite different
> from going from O(1) to O(N=C2=B2).

So going from O(1) to O(N) is okay, but O(N^2) is not? I think it
would be okay to throw a "use append!" warning, or even an error, if
we encounter a situation in which there is more than one ,@ without a
maximum length (i.e. situations in which we fail to be O(N), given
constant-time predicates).

> >> But that presumes a C implementation of `pcase--check-length` since
> >> (< (length X) 4) can be a very bad idea when X is a long list.
> > Even a Lisp implementation that isn't a wrapper around (length X)
> > would avoid unnecessary predicates.
>
> Indeed.  I won't be the one writing the code which tries to guess when
> that's more efficient and when it's less efficient.

Hmm. After running some benchmarks, it seems like a C implementation
of check-length is slightly faster, a Lisp implementation of
check-length is slightly slower, there's less code (in terms of cons
cells) generated with check-length, but the bytecode looks better
without it. All that is without any predicates and in the case of a
matching pattern, so I'd say it's a wash then. In theory, of course,
it's easy to come up with an algorithm that uses both approaches to
achieve minimum complexity, but that's difficult to implement.

So my tentative proposal would be to use `append' or ,@ if you want
length reasoning, plain ` and , if you don't. It might be simpler
always to use it, but I don't want (pcase x (a b) (cons a b)) to emit
a function call.

> > (I think it's interesting that you can't evaluate "proper" pcase at
> > run time; at least, I don't see how you'd implement a pcase-dyn
> > function that evaluates its second argument etc. before interpreting
> > it. It's easy to do with dynamic binding. I think that's because our
> > implementation of lexical binding is too limited, but I'm not sure.)
>
> I don't understand what your `pcase-dyn` would be expected to do, so
> I don't know how dynamic scoping might coming into the picture.

It's what you called dynamic patterns above.

The problem is you cannot eval a pcase form and achieve lexical
binding of the variables used in the bindings. There's no
lexical-scoping equivalent of

(eval `(pcase ',exp ,bindings))

I expect you'll object that that's usually not what you want, anyway,
which is correct but leaves the unusual cases where you know that the
pcase will have been memoized and thus be fairly cheap.

> > The strong limitation is "you can only add new pcase patterns if they
> > have predictable complexity (in code size, run time, or memory usage,
> > presumably)".
>
> Not at all.  You can define any pcase pattern you like with
> `pcase-defmacro`, just like you can define any function or macro you
> like with `defun` and `defmacro`.

Well, I wish :-)

pcase-defmacro is limited to non-recursive patterns.

Thanks for clarifying that the kingdom of predictable complexity does
not extend to pcase-defmacro.

> > By solving polynomial roots? I think it's better to use
> > (pcase-defmacro * ...) for a Kleene star macro...which it turns out
> > isn't precisely trivial to implement with lexical scoping.
>
> Why would lexical scoping make a difference?

Because pcase patterns cannot be recursive (or can they?), but you can
recurse, given dynamic scoping, by eval'ing a pcase form.

By the way, I'm also quite confused by this comment:

;; - implement (not PAT).  This might require a significant redesign.

(pcase-defmacro not (pat)
  `(app (lambda (expval) (not (pcase expval (,pat t))))
        (pred identity)))

would work, wouldn't it? Or did I totally misunderstand what a pcase
not would be expected to do?




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 2 Sep 2020 14:17:04 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Sep 02 10:17:04 2020
Received: from localhost ([127.0.0.1]:60247 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kDTZP-0007vL-J7
	for submit <at> debbugs.gnu.org; Wed, 02 Sep 2020 10:17:04 -0400
Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:4434)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <monnier@HIDDEN>) id 1kDTZN-0007uh-9y
 for 43100 <at> debbugs.gnu.org; Wed, 02 Sep 2020 10:17:02 -0400
Received: from pmg2.iro.umontreal.ca (localhost.localdomain [127.0.0.1])
 by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id B96B68009D;
 Wed,  2 Sep 2020 10:16:55 -0400 (EDT)
Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1])
 by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id 8D2EC80712;
 Wed,  2 Sep 2020 10:16:53 -0400 (EDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca;
 s=mail; t=1599056213;
 bh=UvscrvNNuDHuYwcxzOEIPHrr5Ynjvy41LAk4H+SpEkU=;
 h=From:To:Cc:Subject:References:Date:In-Reply-To:From;
 b=R6EJ6UmfY8oornU/E7pISCOGy1uJO6F4dxZNgVXvHVTRzT/OvY0FaFmBv4oJ3XGoH
 p2mFlGQMu3lOZQ6S0s5x1kGBomdor5R7lqUfNTQHVmtHpM0aiXyF0i/dr43bkUDQ+G
 UxafZi2oLvoCVOA9XAoa7H6bcfrPrl4Yr8WsvMWSbLp5WbiW5EAD51lDN7b0jT80Td
 urDr0KvJ+Frs/gRfPYuT27PA+KLe8Ee99/+3H/FU9Rbk7Gt/jmESbAVG8JjNjLAjlc
 fPtwySiheCa3SilPdlRb+s3d+MrecS5pFev1Wjn7k5UJIs69mC1pv2AYLa904bn0Kz
 KemKCYMjSESCA==
Received: from alfajor (unknown [45.72.232.131])
 by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 5CF6112025D;
 Wed,  2 Sep 2020 10:16:53 -0400 (EDT)
From: Stefan Monnier <monnier@HIDDEN>
To: Pip Cet <pipcet@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
Message-ID: <jwveenknvw3.fsf-monnier+emacs@HIDDEN>
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
 <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
 <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
 <jwvpn791m8z.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBeXLHsbZtcWypng4+DpFtkXBs-+DTkCP3BSFRbThdJpQQ@HIDDEN>
 <jwvr1roysef.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBf8OVdK-JeQjCDjTsOjjO6kuwo+mjEeJ3-JB1d4hN1KYA@HIDDEN>
 <jwva6yatfzo.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBcMHZOnpRscxAmPOn3PaMDOGhzaNykgnrOvBtCeWUQ0Tw@HIDDEN>
Date: Wed, 02 Sep 2020 10:16:52 -0400
In-Reply-To: <CAOqdjBcMHZOnpRscxAmPOn3PaMDOGhzaNykgnrOvBtCeWUQ0Tw@HIDDEN>
 (Pip Cet's message of "Wed, 2 Sep 2020 08:38:22 +0000")
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-SPAM-INFO: Spam detection results:  0
 ALL_TRUSTED                -1 Passed through trusted hosts only via SMTP
 AWL -0.061 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DKIM_SIGNED               0.1 Message has a DKIM or DK signature,
 not necessarily valid
 DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature
 DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's
 domain
X-SPAM-LEVEL: 
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 43100
Cc: Philipp Stephani <p.stephani2@HIDDEN>, 43100 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

>> I just want the complexity to be predictable without having to guess
>> which optimization will be applicable.
> So it's better to have a predictably-bad `append' rather than a
> sometimes-bad one?

In my book, yes.

> But how does that affect ,@? We could make that predictably bad, too!

I think the expectation (coming from the use of ,@ in non-patterns)
would be that it is fairly cheap, but yes, I guess it's an option.
Could be coupled with a warning when ,@ can be replaced by an efficient
`. ,`.

>> >> More specifically, I'd rather not choose a semantics that imposes
>> >> duplicating the branch body, since we have no control over its size a=
nd
>> >> that can hence lead to potential code size explosion.
>> > You're right, and it's a good thing that the duplication of the branch
>> > body is a fixable implementation detail rather than something imposed
>> > by the semantics.
>> It's only fixable if you disregard the "more or less" above.
>> I find it to be a pretty bad wrinkle in the semantics.
> So setq the outer binding if it changed?

Oh, yuck!  That'd be adding injury to insult.

> Note that people also might expect
>
>     (pcase l (`(,a . ,b) (setq b a)))
>
> to modify l...

They might indeed.  But if so, they'll be disappointed ;-)

>> >> The design of `pcase` assumes you want to optimize away the tests that
>> >> are common to the various patterns.  That can't be done with dynamic
>> >> patterns.
>> > Or it's a bit more difficult, at least...
>> I think it's more than "a bit more difficult", because deciding how to
>> optimize the tests will almost always take significantly more time than
>> just doing the tests.  So in order to do it dynamically and be useful,
>> you still need to have 2 stages, where you optimize at one stage and
>> then use the result several times later (to recoup the cost of the
>> optimization).
> Wait, I think there was a misunderstanding here. I don't mean that the
> pcase pattern should depend structurally on let-bound variables
> appearing in it. That does sound impossible to me (except with dynamic
> scoping).

To me "dynamic patterns" means patterns which are only know at run time
because the pattern itself depends on a runtime value, as in something like:

    (let ((pat (if FOO '(pred symbolp) '1)))
      ...
      (pcase V
        ...
        ((match pat) EXP)
        ...))

Not sure what you meant by it, then.

>> > The difficult part, in fact, is deciding that we want the arglist to
>> > be part of the exposed function API: given an "arglist" function, the
>> > rest of the implementation seems unproblematic,
>> We have `help-function-arglist`, so it's not that hard.
>> But it's not guaranteed to work.
> Oh, thanks for pointing that out.  It's not very good, though, is it?

It's good enough for `C-h o`.

>> Lexical scoping fundamentally means that variables don't have names:
>> (lambda (x) x) and (lambda (y) y) should be indistinguishable (that's
>> what =CE=B1-renaming says, anyway).
> But they're not.

;-)

> I don't see why pcase-call should be in the "funcall" category of
> being unable to distinguish the two, rather than in the "equal"
> category of being able to.

The notion of equality between functions is pretty delicate (and this
fundamental problem was the original motivation for the development of
type classes, BTW).

>> I'm sorry, I don't understand what those sexps (and their =C2=ABoptional"
>> non-final parts=C2=BB) have to do with pcase's handling of `or` patterns
>> where the different branches don't bind the same set of variables.
> Well, maybe I'm just missing an obvious way of doing it.

Could be, but I have no idea what "it" is.

>> >> > disallowing the modification of name in X.
>> >> That's rather hard to do (and I don't see what would be the benefit h=
ere).
>> > I meant adding a cautionary note about it in the documentation, not
>> > actively preventing it.
>> So we're replacing the current "don't do that" with another "don't do
>> that", neither of which is detected by the byte-compiler?
> Yes. Emacs Lisp isn't free of "don't do that"s, and reducing the
> "don't do that" space drastically is better than pointing out the tiny
> fraction of it which remains as evidence that we shouldn't do the
> reduction in the first place.

I don't see your proposal as reducing the "don't do that" space.

>> >> The current implementation amounts to "we should signal an error but =
we
>> >> don't bother doing so and just warn against it in the manual".
>> >> Patch welcome ;-)
>> > You mean a patch that would make pcase less powerful by making what I
>> > want to do impossible rather than merely difficult?
>> The way I see it, it would make what you want to do possible because
>> what you suggest would merely give meaning to programs previously invali=
d.
>> In contrast, with the current behavior your proposal implies breaking
>> backward compatibility.
> I think what you mean is you'd rather break backward compatibility in
> two steps rather than one, by first causing errors, then redefining
> the new errors not to happen? Because if so, I totally agree.

That's right.  The first (breaking) step would be "my fault" and would
hence free you to do the second step without introducing
incompatibilities ;-)

> IOW, I'd like ` (as a pcase macro) to behave like ` already does:
> constant-time `(,@l), linear-time `(,@l 3).

I suggest you start with a `pip-backquote` pcase-macro and experiment
with it, to see how useful it is.  You'll then presumably have more
concrete examples to argue for the replacement of the current `=20

> And, again, performance of ` is unpredictable unless you know the
> details of the optimization. Should we get rid of ` next?

AFAIK performance is O(N) where N is the number of cons cells in the
output (minus those cons-cells which are preserved as-is, I guess but
that doesn't make much of a difference).  That seems quite different
from going from O(1) to O(N=C2=B2).

>> But that presumes a C implementation of `pcase--check-length` since
>> (< (length X) 4) can be a very bad idea when X is a long list.
> Even a Lisp implementation that isn't a wrapper around (length X)
> would avoid unnecessary predicates.

Indeed.  I won't be the one writing the code which tries to guess when
that's more efficient and when it's less efficient.

>> > It's strange to read quotes that yo
>> ...?
> Well, it's strange to read quotes that you only half-deleted from your
> email, Pip! (Sorry).

;-)

> (I think it's interesting that you can't evaluate "proper" pcase at
> run time; at least, I don't see how you'd implement a pcase-dyn
> function that evaluates its second argument etc. before interpreting
> it. It's easy to do with dynamic binding. I think that's because our
> implementation of lexical binding is too limited, but I'm not sure.)

I don't understand what your `pcase-dyn` would be expected to do, so
I don't know how dynamic scoping might coming into the picture.

> The strong limitation is "you can only add new pcase patterns if they
> have predictable complexity (in code size, run time, or memory usage,
> presumably)".

Not at all.  You can define any pcase pattern you like with
`pcase-defmacro`, just like you can define any function or macro you
like with `defun` and `defmacro`.

> By solving polynomial roots? I think it's better to use
> (pcase-defmacro * ...) for a Kleene star macro...which it turns out
> isn't precisely trivial to implement with lexical scoping.

Why would lexical scoping make a difference?


        Stefan





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 2 Sep 2020 08:39:08 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Sep 02 04:39:08 2020
Received: from localhost ([127.0.0.1]:58245 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kDOIN-0005On-HF
	for submit <at> debbugs.gnu.org; Wed, 02 Sep 2020 04:39:08 -0400
Received: from mail-oo1-f45.google.com ([209.85.161.45]:38681)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pipcet@HIDDEN>) id 1kDOIK-0005OH-P0
 for 43100 <at> debbugs.gnu.org; Wed, 02 Sep 2020 04:39:05 -0400
Received: by mail-oo1-f45.google.com with SMTP id z11so974069oon.5
 for <43100 <at> debbugs.gnu.org>; Wed, 02 Sep 2020 01:39:04 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc:content-transfer-encoding;
 bh=b470FM/TBZoOmtwxQOTr4Sv5vX3xvvw1o/uOBk+MqDY=;
 b=Xc8vsFJApCe4Z4R3xM22kFvceS3PDjozl5Z6YXppvjS0zJVOsaEg3Isjuq8AM8EzUd
 S0ufSvpZWNcMXZ/KhD9ctcSbxtx42GSWtvUfbdSMExi8KDFKTm21NtqWF8Hs5s0mpmxR
 dm5jDnL0qP4kHlBEFFkTe2KpS7B+0Kxkg/ehtpDNnRc6hayIVCyGHUM79OSrE+N21SEB
 q4bQiWntp0g3gUbasSvEZ7oqkYUhUt+WhI0YjG5Sr9WU6Ch7JLxdNWtH7uJSYuQsB1VG
 33r2GwM7w5pWOn7ZSuOzfJ+RF8Oq6ktOE/gykODwe8+Z8dq5aiE4DhxSaPknVp9ICHq3
 j1gQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc:content-transfer-encoding;
 bh=b470FM/TBZoOmtwxQOTr4Sv5vX3xvvw1o/uOBk+MqDY=;
 b=fqXUC+FfU4rgscBbvXYv3IW83++9lMDKh6CwkNbxcVcJMrhthp1sscLNRKacgGIGeO
 aP6qqhRI2CTkiRBTBDB99A4w0BklW5/o1oIXkbTV41ooSaOSz2zqhyGoFGeKdWsb7c8r
 c7k1pvAmSlAr1B0gaUzkSPjDkamzfq4V5FZ8QCMviqIRjGvroU/MXVe/q6fInc/+CCw0
 UiBJ+uYeIFaXkYv5Sbna6UqJ85i7h7b5hEOA9lFTIb8/PiBbxxYzDwWg5NDdtDoTEalf
 uBQLS65XAZagF+2tJ6QjlQidDIZHVndK11G7PX3cVTswwqZQpRwN77Nxanh5zdwiLdDO
 s7mA==
X-Gm-Message-State: AOAM5312FgcdX+kcrhvvlZ2OYWY8yK/6gu2cyqG7ODJdi6RgxhgUhhIc
 /4gi+lbYo1+mWUeQ5ebUDptT7gWY2Gz7oLrlhPA=
X-Google-Smtp-Source: ABdhPJyJzo3fdjuArdVP8I+XYafYsJBKdIfYdH0ix98wvlwArDsIsJqOR6VyGebcVNoKmHoVAT1cA4Ru6HRdMoZXiPM=
X-Received: by 2002:a4a:5a06:: with SMTP id v6mr4645821ooa.22.1599035938733;
 Wed, 02 Sep 2020 01:38:58 -0700 (PDT)
MIME-Version: 1.0
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
 <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
 <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
 <jwvpn791m8z.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBeXLHsbZtcWypng4+DpFtkXBs-+DTkCP3BSFRbThdJpQQ@HIDDEN>
 <jwvr1roysef.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBf8OVdK-JeQjCDjTsOjjO6kuwo+mjEeJ3-JB1d4hN1KYA@HIDDEN>
 <jwva6yatfzo.fsf-monnier+emacs@HIDDEN>
In-Reply-To: <jwva6yatfzo.fsf-monnier+emacs@HIDDEN>
From: Pip Cet <pipcet@HIDDEN>
Date: Wed, 2 Sep 2020 08:38:22 +0000
Message-ID: <CAOqdjBcMHZOnpRscxAmPOn3PaMDOGhzaNykgnrOvBtCeWUQ0Tw@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
To: Stefan Monnier <monnier@HIDDEN>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 43100
Cc: Philipp Stephani <p.stephani2@HIDDEN>, 43100 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Tue, Sep 1, 2020 at 3:12 AM Stefan Monnier <monnier@HIDDEN> wr=
ote:
> > So, as I half-expected, the reaction to "pcase isn't powerful enough"
> > is "let's make it less powerful" :-)
> Your words, not mine.

I'm glad you said that!

> BTW, you can get (more or less) the behavior you want with:
>
>     (pcase V
>       ((or (and (pred symbolp) (let name name)) name)
>        (let ((foo 'bar)) name)))

That's a good alternative.

> [ The "more or less" is because when V is a symbol, the `name` within
>   the body of the branch will not refer to the presumed surrounding
>   binding of `name` but to a new binding also called `name` which
>   temporarily hides the outer binding but is initialized to the same
>   value.  The difference only kicks in if one of those bindings is
>   mutated.  ]
>
> > Seriously, I get the impression you strongly feel pcase shouldn't be
> > (more) powerful, it should instead make non-explicit but fairly strong
> > complexity promises.
>
> I just want the complexity to be predictable without having to guess
> which optimization will be applicable.

So it's better to have a predictably-bad `append' rather than a
sometimes-bad one? But how does that affect ,@? We could make that
predictably bad, too!

> >> More specifically, I'd rather not choose a semantics that imposes
> >> duplicating the branch body, since we have no control over its size an=
d
> >> that can hence lead to potential code size explosion.
> > You're right, and it's a good thing that the duplication of the branch
> > body is a fixable implementation detail rather than something imposed
> > by the semantics.
>
> It's only fixable if you disregard the "more or less" above.
> I find it to be a pretty bad wrinkle in the semantics.

So setq the outer binding if it changed? Note that people also might expect

(pcase l (`(,a . ,b) (setq b a)))

to modify l...

> >> The design of `pcase` assumes you want to optimize away the tests that
> >> are common to the various patterns.  That can't be done with dynamic
> >> patterns.
> > Or it's a bit more difficult, at least...
> I think it's more than "a bit more difficult", because deciding how to
> optimize the tests will almost always take significantly more time than
> just doing the tests.  So in order to do it dynamically and be useful,
> you still need to have 2 stages, where you optimize at one stage and
> then use the result several times later (to recoup the cost of the
> optimization).

Wait, I think there was a misunderstanding here. I don't mean that the
pcase pattern should depend structurally on let-bound variables
appearing in it. That does sound impossible to me (except with dynamic
scoping).

> > The difficult part, in fact, is deciding that we want the arglist to
> > be part of the exposed function API: given an "arglist" function, the
> > rest of the implementation seems unproblematic,
>
> We have `help-function-arglist`, so it's not that hard.
> But it's not guaranteed to work.

Oh, thanks for pointing that out. It's not very good, though, is it?

> > though some workarounds for lexical binding are required (if nothing
> > else, this is an interesting exercise in how painful lexical binding
> > can be to work with).
>
> It's more of a philosophical issue.

Deciding whether to expose arglists for functions is, yes. That's what
I said above.

> Lexical scoping fundamentally means
> that variables don't have names: (lambda (x) x) and (lambda (y) y)
> should be indistinguishable (that's what =CE=B1-renaming says, anyway).

But they're not. (equal (lambda (x) x) (lambda (y) y)) returns nil. I
don't see why pcase-call should be in the "funcall" category of being
unable to distinguish the two, rather than in the "equal" category of
being able to.

> >> So it's more like my option of returning nil, except it would return
> >> the value of a surrounding `name` variable?  That could be done, but I=
'm
> >> not convinced it'd be more often useful.
> >
> > I started out with a fairly explicit practical problem: parsing GCC
> > machine descriptions, which are (essentially) sexps but have made the
> > mistake of having "optional" non-final parts, and I think it would be
> > great to express that in a pcase pattern, both for the obvious reasons
> > of legibility and for some non-obvious reasons of my own.
>
> I'm sorry, I don't understand what those sexps (and their =C2=ABoptional"
> non-final parts=C2=BB) have to do with pcase's handling of `or` patterns
> where the different branches don't bind the same set of variables.

Well, maybe I'm just missing an obvious way of doing it.

> >> > disallowing the modification of name in X.
> >> That's rather hard to do (and I don't see what would be the benefit he=
re).
> > I meant adding a cautionary note about it in the documentation, not
> > actively preventing it.
>
> So we're replacing the current "don't do that" with another "don't do
> that", neither of which is detected by the byte-compiler?

Yes. Emacs Lisp isn't free of "don't do that"s, and reducing the
"don't do that" space drastically is better than pointing out the tiny
fraction of it which remains as evidence that we shouldn't do the
reduction in the first place.

> I'd rather fix it "right" with something with a clean and
> simple semantics where the things you shouldn't do get properly flagged
> during compilation.

If you want clean and simple (lexical scoping) semantics and execute
user-provided code, you should probably call a user-provided lambda
rather than evaluating an expression in the first place?

> >> The current implementation amounts to "we should signal an error but w=
e
> >> don't bother doing so and just warn against it in the manual".
> >> Patch welcome ;-)
> > You mean a patch that would make pcase less powerful by making what I
> > want to do impossible rather than merely difficult?
>
> The way I see it, it would make what you want to do possible because
> what you suggest would merely give meaning to programs previously invalid=
.
> In contrast, with the current behavior your proposal implies breaking
> backward compatibility.

I think what you mean is you'd rather break backward compatibility in
two steps rather than one, by first causing errors, then redefining
the new errors not to happen? Because if so, I totally agree.

> >> >> I don't know of a simple implementation.
> >> > Here's my better-than-nothing attempt.  I don't think that's complex=
;
> >> > if anything, it's too trivial.
> >> So you give it a search-based semantics.
> > I don't think the semantics are at all unclear,
>
> You misunderstood: I definitely didn't mean "unclear" when wrote "search-=
based".
> The semantics are definitely clear.

Saying I give it search-based semantics implies there are other
semantics I could have chosen. Semantically, all I've done is decide,
probably incorrectly, that append should be biased towards shy
matching of the fist arguments (and that it only work on proper
lists).

> >> The problem with it for me is that if we turn
> >>
> >>     `(,a ,@b)
> >>
> >> into
> >>
> >>     (append `(,a) b)
> >
> > List-final ,@ is too special, IMHO, to be turned into an (append)
> > pattern at all.
>
> So you want some ,@ to be turned into `append` and some not?

As an implementation detail, yes. Just like ` does, by the way: `(,@l)
doesn't call `append' (it doesn't even check l is a list!), so why
should it behave differently when used as a pcase pattern?

IOW, I'd like ` (as a pcase macro) to behave like ` already does:
constant-time `(,@l), linear-time `(,@l 3).

> That's exactly what I don't want, since it makes the performance
> unpredictable unless you know the details of the optimization.

I'm not opposed to the idea that there should be a form that means
"use pcase to evaluate this, but throw an error if I messed up and
complexity is worse than O(f(n))". I just don't think it should be
(pcase ...), leaving the f to be determined by a human who's allowed
to know the expected complexity of pcase patterns (currently not
mentioned in the documentation), but isn't allowed to "know the
details of the optimization".

And, again, performance of ` is unpredictable unless you know the
details of the optimization. Should we get rid of ` next?

> >> the pcase match will take a lot more time than the equivalent
> >>     `(,a . ,b)
> >> Of course, you can try and handle these "easy" cases more efficiently,
> >> but then your ,@ will sometimes be very cheap and sometimes very
> >> expensive (depending on when an optimization can be applied), which
> >> I think is a misfeature (it's for this same reason that I dislike CL
> >> keyword arguments for functions).
> > I think it's an implementation detail.
>
> I don't want implementation details to choose between O(N) and O(1).
> This is the kind of "detail" that should be chosen by the author.

All powerful matching patterns I'm aware of have horrible worst-time
complexity which is reduced to acceptable complexity for most cases,
in practice. Take `equal', for example.

(let (r s)
  (dotimes (i 100)
    (setq r (cons r r))
    (setq s (cons s s))
    (benchmark 1 `(equal ',r ',s))))

What you're asking sounds to me like the equivalent of "I want a
compression algorithm to be as good as possible, but the size of the
decompressed data has to be predictable, even if I perform recursive
decompression of the output".

> > Some reasoning about the minimum and maximum length of sequences
> > matched by pcase patterns could help ordinary pcases, too, though:
>
> Potentially, of course.  There are many options when it comes to the
> actual code generated by `pcase`.

Precisely, including ones that reduce complexity. Somewhat
unpredictably. Which is why predictable performance is a bad thing to
demand of pcase patterns.

> > (pcase '(a b c d)
> >   (`(,a ,b ,c ,d) (list a b c d)))
> >
> > could call (pcase--check-length EXPVAL 4 4) rather than calling consp
> > four times, potentially descending into expensive predicates that are
> > unnecessary.
>
> But that presumes a C implementation of `pcase--check-length` since
> (< (length X) 4) can be a very bad idea when X is a long list.

Even a Lisp implementation that isn't a wrapper around (length X)
would avoid unnecessary predicates. That is the reason I wrote
pcase--check-length rather than (<=3D 4 (length EXPVAL) 4)...

> > It's strange to read quotes that yo
> ...?

Well, it's strange to read quotes that you only half-deleted from your
email, Pip! (Sorry).

> > Again, I think that's a fundamental difference between us when it
> > comes to the philosophy behind pcase.  If I understand you correctly,
> > you deliberately want to limit pcase, moving away from the intuitive
> > definition of it that I gave above, because there might be a situation
> > in which people expect better performance than our limited
> > implementation can give them. Is that correct?
>
> [ The intuitive definition you gave doesn't work for most of the core
>   patterns in `pcase` (e.g. `pred`, `app`, `let`, `guard`), so while
>   it's fine as a guiding intuition, it can't be used to really define
>   the intended semantics.  ]

You mean because "pred" isn't defined as a function, and "let" is
defined differently?

Because if I'm allowed to defmacro pred, it works perfectly well:

(defmacro pred (p)
  ``(pred ,p))

(defun equalish (a b)
  (... (pcase a (`(pred ,p) (funcall p b)))

with extra hygiene being required, of course, but there's no problem here.

> No, the problem is not really one of performance, but rather one of
> defining which variables are in scope within a branch such that a given
> branch always has the same set of bindings within its scope, no matter
> how the pattern was matched, which I think gives it a cleaner and
> simpler semantics.

Yes: calling lambdas gives cleaner and simpler semantics than
evaluating forms, which gives terser code and implies precisely the
unclean (but useful) semantics I want. pcase does the latter, implying
semantics which we can implement (more easily and cleanly using
dynamic bindings, for some reason), but choose not to. I'd like to
understand why!

> [ It is also linked to a potential problem of code size explosion,
>   admittedly.  ]

Let's be clear, though, that we're not talking about an explosion in
the number of conses used to express the pcase. It's only when the
code is byte compiled that an explosion potentially happens (and it's
easily fixable with dynamic binding, but not with lexical binding, as
far as I can see).

(I think it's interesting that you can't evaluate "proper" pcase at
run time; at least, I don't see how you'd implement a pcase-dyn
function that evaluates its second argument etc. before interpreting
it. It's easy to do with dynamic binding. I think that's because our
implementation of lexical binding is too limited, but I'm not sure.)

> > I think that's a weak reason for a strong limitation, but of course
> > those are subjective questions.
>
> I don't see what strong limitation you're referring to.  Having `name`
> get the value of a surrounding `name` instead of nil seems like a very
> minor issue and definitely not a "strong limitation".

The strong limitation is "you can only add new pcase patterns if they
have predictable complexity (in code size, run time, or memory usage,
presumably)". Taken at face value, that means no ,@, nothing
equal-based, no efficient joining of two pcase cases into one... and
no conditional binding of variables.

(IMHO, (pcase X (A B) (C D)) should be equivalent to (pcase X ((or
(and (let which-alternative 0) A) (and (let which-alternative 1) C))
(case which-alternative (0 B) (1 D)))), assuming "which-alternative"
is free in A, B, C, D.)

You're right, though, that it'll usually be possible to get the right
behavior using the "bind everything to nil" idea. I hadn't understood
you to be seriously proposing we implement that, but if you do I'll
prepare a patch.

> > For example, I don't expect (pcase 9 ((* x x) x)) to work,
>
> With an appropriate (pcase-defmacro * ...) you could definitely make it
> work.

By solving polynomial roots? I think it's better to use
(pcase-defmacro * ...) for a Kleene star macro...which it turns out
isn't precisely trivial to implement with lexical scoping.

Pip




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 1 Sep 2020 03:12:16 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Aug 31 23:12:16 2020
Received: from localhost ([127.0.0.1]:54384 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kCwiV-0006GE-PJ
	for submit <at> debbugs.gnu.org; Mon, 31 Aug 2020 23:12:16 -0400
Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:38203)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <monnier@HIDDEN>) id 1kCwiS-0006G1-OD
 for 43100 <at> debbugs.gnu.org; Mon, 31 Aug 2020 23:12:14 -0400
Received: from pmg3.iro.umontreal.ca (localhost [127.0.0.1])
 by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id 00360440982;
 Mon, 31 Aug 2020 23:12:07 -0400 (EDT)
Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1])
 by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id 25CC0440974;
 Mon, 31 Aug 2020 23:12:04 -0400 (EDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca;
 s=mail; t=1598929924;
 bh=DCdEyolyq9aa5hubzW4ZJy1RsTqh2AlSNBlOVyp/IE0=;
 h=From:To:Cc:Subject:References:Date:In-Reply-To:From;
 b=HFJ+8QN8l7W3YWTJ8vZoCke2JScP+FZdVzo6SJhKOPpmD2C9w8v5+MtxgJ2F8kN2s
 s6zXkOBbKzE0RMSGimiQd1WJQNt2cfpHrdqJxxyQOF44HCvPEFv6tDpRkhnVv3AqWp
 OhkNnVOTBoolB54468I9wTZmbp9F5f/jRV/sYIXMlvRsBw7ZcPPCrIQFS4qn3JXI4K
 x5vA0TMPgcFlLNsME4LRKYmDFrChcWJjH6Gpu8+RBi253wdTgz7em9o334bRvCgwAy
 3wRLvajpFmNEZ/2/hrkYWEmdWd7AsFsjO/LKCl2jYZAQIwJ4u+FhwuR3R3zwwWXgED
 whQWyDIj7vD1w==
Received: from alfajor (unknown [45.72.232.131])
 by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id E66A412078A;
 Mon, 31 Aug 2020 23:12:03 -0400 (EDT)
From: Stefan Monnier <monnier@HIDDEN>
To: Pip Cet <pipcet@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
Message-ID: <jwva6yatfzo.fsf-monnier+emacs@HIDDEN>
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
 <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
 <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
 <jwvpn791m8z.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBeXLHsbZtcWypng4+DpFtkXBs-+DTkCP3BSFRbThdJpQQ@HIDDEN>
 <jwvr1roysef.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBf8OVdK-JeQjCDjTsOjjO6kuwo+mjEeJ3-JB1d4hN1KYA@HIDDEN>
Date: Mon, 31 Aug 2020 23:12:02 -0400
In-Reply-To: <CAOqdjBf8OVdK-JeQjCDjTsOjjO6kuwo+mjEeJ3-JB1d4hN1KYA@HIDDEN>
 (Pip Cet's message of "Mon, 31 Aug 2020 19:32:43 +0000")
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-SPAM-INFO: Spam detection results:  0
 ALL_TRUSTED                -1 Passed through trusted hosts only via SMTP
 AWL -0.038 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DKIM_SIGNED               0.1 Message has a DKIM or DK signature,
 not necessarily valid
 DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature
 DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's
 domain
 T_FILL_THIS_FORM_SHORT   0.01 Fill in a short form with personal information
X-SPAM-LEVEL: 
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 43100
Cc: Philipp Stephani <p.stephani2@HIDDEN>, 43100 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

>> >> IIUC you want
>> >>
>> >>     (pcase V
>> >>       ((or (pred symbolp) name)
>> >>        (let ((foo 'bar)) name)))
>> >>
>> >> to behave like
>> >>
>> >>     (cond
>> >>      ((symbolp V) (let ((foo 'bar)) name))
>> >>      (t (let ((name V)) (let ((foo 'bar)) name))))
>> >>
>> >> ?
>> >
>> > Yes, that's correct. It's also how (pcase V ((or (pred symbolp) name)
>> > name) behaves...
>>
>> Indeed, but that's an accident.  Ideally it should either signal an
>> error at macro-expansion time, or return nil when V is a symbol.
> So, as I half-expected, the reaction to "pcase isn't powerful enough"
> is "let's make it less powerful" :-)

Your words, not mine.
BTW, you can get (more or less) the behavior you want with:

    (pcase V
      ((or (and (pred symbolp) (let name name)) name)
       (let ((foo 'bar)) name)))

[ The "more or less" is because when V is a symbol, the `name` within
  the body of the branch will not refer to the presumed surrounding
  binding of `name` but to a new binding also called `name` which
  temporarily hides the outer binding but is initialized to the same
  value.  The difference only kicks in if one of those bindings is
  mutated.  ]

> Seriously, I get the impression you strongly feel pcase shouldn't be
> (more) powerful, it should instead make non-explicit but fairly strong
> complexity promises.

I just want the complexity to be predictable without having to guess
which optimization will be applicable.  It's sometimes hard to satisfy
this desire, admittedly.  But note that it doesn't require the code to
be "efficient": your `append` very much satisfies my desire since its
complexity is very much predictable.

> I disagree: in practice, complexity promises and optimization based on
> them are often unnecessary. In fact, there's a Lisp tradition of using
> assq and memq rather than building ad-hoc hash tables, even though
> that often means run time is theoretically O(n^2) rather than O(n
> log(n)).

The complexity of `assq` is arguably bad, but it is very much predictable.

>> More specifically, I'd rather not choose a semantics that imposes
>> duplicating the branch body, since we have no control over its size and
>> that can hence lead to potential code size explosion.
> You're right, and it's a good thing that the duplication of the branch
> body is a fixable implementation detail rather than something imposed
> by the semantics.

It's only fixable if you disregard the "more or less" above.
I find it to be a pretty bad wrinkle in the semantics.

>> The design of `pcase` assumes you want to optimize away the tests that
>> are common to the various patterns.  That can't be done with dynamic
>> patterns.
> Or it's a bit more difficult, at least...

I think it's more than "a bit more difficult", because deciding how to
optimize the tests will almost always take significantly more time than
just doing the tests.  So in order to do it dynamically and be useful,
you still need to have 2 stages, where you optimize at one stage and
then use the result several times later (to recoup the cost of the
optimization).

> The difficult part, in fact, is deciding that we want the arglist to
> be part of the exposed function API: given an "arglist" function, the
> rest of the implementation seems unproblematic,

We have `help-function-arglist`, so it's not that hard.
But it's not guaranteed to work.

> though some workarounds for lexical binding are required (if nothing
> else, this is an interesting exercise in how painful lexical binding
> can be to work with).

It's more of a philosophical issue.  Lexical scoping fundamentally means
that variables don't have names: (lambda (x) x) and (lambda (y) y)
should be indistinguishable (that's what =CE=B1-renaming says, anyway).

Obviously, `help-function-arglist` begs to differ, but I like lexical
scoping so I'd rather we keep such exceptions to a minimum.

>> So it's more like my option of returning nil, except it would return
>> the value of a surrounding `name` variable?  That could be done, but I'm
>> not convinced it'd be more often useful.
>
> I started out with a fairly explicit practical problem: parsing GCC
> machine descriptions, which are (essentially) sexps but have made the
> mistake of having "optional" non-final parts, and I think it would be
> great to express that in a pcase pattern, both for the obvious reasons
> of legibility and for some non-obvious reasons of my own.

I'm sorry, I don't understand what those sexps (and their =C2=ABoptional"
non-final parts=C2=BB) have to do with pcase's handling of `or` patterns
where the different branches don't bind the same set of variables.

>> > disallowing the modification of name in X.
>> That's rather hard to do (and I don't see what would be the benefit here=
).
> I meant adding a cautionary note about it in the documentation, not
> actively preventing it.

So we're replacing the current "don't do that" with another "don't do
that", neither of which is detected by the byte-compiler?

I'd rather fix it "right" with something with a clean and
simple semantics where the things you shouldn't do get properly flagged
during compilation.

> If we had read-only bindings, pcase would probably use them,
> but we don't.

We could add them, tho (I think it would be technically fairly easy,
it's more a question of surface-language design, figuring out the right
color of the bikeshed and deciding whether it's really worth adding this
extra complexity into the language).  I love immutable variables as much
as the next guy, yet I have resisted the urge to add them to Elisp
so far.

>> The current implementation amounts to "we should signal an error but we
>> don't bother doing so and just warn against it in the manual".
>> Patch welcome ;-)
> You mean a patch that would make pcase less powerful by making what I
> want to do impossible rather than merely difficult?

The way I see it, it would make what you want to do possible because
what you suggest would merely give meaning to programs previously invalid.
In contrast, with the current behavior your proposal implies breaking
backward compatibility.

>> >> I don't know of a simple implementation.
>> > Here's my better-than-nothing attempt.  I don't think that's complex;
>> > if anything, it's too trivial.
>> So you give it a search-based semantics.
> I don't think the semantics are at all unclear,

You misunderstood: I definitely didn't mean "unclear" when wrote "search-ba=
sed".
The semantics are definitely clear.

>> The problem with it for me is that if we turn
>>
>>     `(,a ,@b)
>>
>> into
>>
>>     (append `(,a) b)
>
> List-final ,@ is too special, IMHO, to be turned into an (append)
> pattern at all.

So you want some ,@ to be turned into `append` and some not?
That's exactly what I don't want, since it makes the performance
unpredictable unless you know the details of the optimization.

>> the pcase match will take a lot more time than the equivalent
>>     `(,a . ,b)
>> Of course, you can try and handle these "easy" cases more efficiently,
>> but then your ,@ will sometimes be very cheap and sometimes very
>> expensive (depending on when an optimization can be applied), which
>> I think is a misfeature (it's for this same reason that I dislike CL
>> keyword arguments for functions).
> I think it's an implementation detail.

I don't want implementation details to choose between O(N) and O(1).
This is the kind of "detail" that should be chosen by the author.

> Some reasoning about the minimum and maximum length of sequences
> matched by pcase patterns could help ordinary pcases, too, though:

Potentially, of course.  There are many options when it comes to the
actual code generated by `pcase`.

> (pcase '(a b c d)
>   (`(,a ,b ,c ,d) (list a b c d)))
>
> could call (pcase--check-length EXPVAL 4 4) rather than calling consp
> four times, potentially descending into expensive predicates that are
> unnecessary.

But that presumes a C implementation of `pcase--check-length` since
(< (length X) 4) can be a very bad idea when X is a long list.

> It's strange to read quotes that yo

...?

> Again, I think that's a fundamental difference between us when it
> comes to the philosophy behind pcase.  If I understand you correctly,
> you deliberately want to limit pcase, moving away from the intuitive
> definition of it that I gave above, because there might be a situation
> in which people expect better performance than our limited
> implementation can give them. Is that correct?

[ The intuitive definition you gave doesn't work for most of the core
  patterns in `pcase` (e.g. `pred`, `app`, `let`, `guard`), so while
  it's fine as a guiding intuition, it can't be used to really define
  the intended semantics.  ]

No, the problem is not really one of performance, but rather one of
defining which variables are in scope within a branch such that a given
branch always has the same set of bindings within its scope, no matter
how the pattern was matched, which I think gives it a cleaner and
simpler semantics.

[ It is also linked to a potential problem of code size explosion,
  admittedly.  ]

> I think that's a weak reason for a strong limitation, but of course
> those are subjective questions.

I don't see what strong limitation you're referring to.  Having `name`
get the value of a surrounding `name` instead of nil seems like a very
minor issue and definitely not a "strong limitation".

> For example, I don't expect (pcase 9 ((* x x) x)) to work,

With an appropriate (pcase-defmacro * ...) you could definitely make it
work.  Not sure how useful it would be, but I'd have no problem with it:
just like `append` it doesn't impact the rest of `pcase` (and I presume
that it would come with a "predictably costly" complexity).


        Stefan





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 31 Aug 2020 19:33:30 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Aug 31 15:33:30 2020
Received: from localhost ([127.0.0.1]:53738 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kCpYX-0001EU-LU
	for submit <at> debbugs.gnu.org; Mon, 31 Aug 2020 15:33:30 -0400
Received: from mail-ot1-f46.google.com ([209.85.210.46]:43934)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pipcet@HIDDEN>) id 1kCpYU-0001EF-Jd
 for 43100 <at> debbugs.gnu.org; Mon, 31 Aug 2020 15:33:28 -0400
Received: by mail-ot1-f46.google.com with SMTP id v16so6361976otp.10
 for <43100 <at> debbugs.gnu.org>; Mon, 31 Aug 2020 12:33:26 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=OOxEnggrg5w3krgjf2IcUnPALzRdHZ7/QVxHdTs8oS4=;
 b=HW51mbI/rMzKIGOrH6U1DPhPkGTZarXoBAC9sPowHWxAPz/AP1nburmrr/59axW05J
 zuC8EbzK37jfAv8L5RS4cdQqUMd7o3l5nGSDxBmZyNgts6DVAPG18GXKQCjU0Y5Jqlcj
 yaLtXA1xeZGhmNW1JCjpORryZbbaXZfEc2foiNzTr2HWepPd7k33FU7FWxzJiA3HSBDK
 j0Au8vJuBxkOKkeW7VstWqkX0IV2WwxKQ54Oc70O4JcZEZQ81WCmGqRTLhzO2qSdRKml
 ipbjWJUoGPBibjMDYDuHt2FbeC0A/zgfs/TK5V4g5u1PwH5S58DdClHSZ/3NLzc3MZ5t
 BMhA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=OOxEnggrg5w3krgjf2IcUnPALzRdHZ7/QVxHdTs8oS4=;
 b=GWP7CuQMunbtVySsjD3tykasfhlEf0a5jqowyAGC3bd2tpq+eYkAt10+wcaIR/khgS
 L9OFOOPE9blNxCbvOUEVZmJnfB//PoiEJGLSOsCeBNGxjJFDDuIgS0gTTLcZDwcWptaQ
 yCCTWgUfrolaSje7lS4MJwi+79n+++WirJx681CpRbmG7t2phlCmDqMuN3k3SL8N1BqE
 GcNrd7Z3rdUZkaoYNUhuZbglgqqRrBNBeJjDVfxwnogLXMlxgRxFIJ7oYr5J/QcyDFLq
 K1u1LSKtCwqcRcw6CNGwj6oDB8lRF360xOHKXUc28p4Ac2sAFtjf1F7XyT5+SvmMYVKb
 yGBA==
X-Gm-Message-State: AOAM531wEVgHfhZQaawblX2IRrOyVdAIZ9ZUU+o6ScN4AuvroQxsUPUZ
 LzFQtnfqGt+89TCWsVfONiBs0bNYf9NZisYaZ4g=
X-Google-Smtp-Source: ABdhPJyFESWBl+QKFzmW/Pa5ZS+lcPw6YE3T9SMslk3E2mBL6KF7RhPc6Vtj9d9t3fh3ylser0xygCszTr+p/XmSSr8=
X-Received: by 2002:a9d:6d92:: with SMTP id x18mr1981049otp.287.1598902400698; 
 Mon, 31 Aug 2020 12:33:20 -0700 (PDT)
MIME-Version: 1.0
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
 <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
 <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
 <jwvpn791m8z.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBeXLHsbZtcWypng4+DpFtkXBs-+DTkCP3BSFRbThdJpQQ@HIDDEN>
 <jwvr1roysef.fsf-monnier+emacs@HIDDEN>
In-Reply-To: <jwvr1roysef.fsf-monnier+emacs@HIDDEN>
From: Pip Cet <pipcet@HIDDEN>
Date: Mon, 31 Aug 2020 19:32:43 +0000
Message-ID: <CAOqdjBf8OVdK-JeQjCDjTsOjjO6kuwo+mjEeJ3-JB1d4hN1KYA@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
To: Stefan Monnier <monnier@HIDDEN>
Content-Type: multipart/mixed; boundary="0000000000009fed8e05ae317999"
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 43100
Cc: Philipp Stephani <p.stephani2@HIDDEN>, 43100 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--0000000000009fed8e05ae317999
Content-Type: text/plain; charset="UTF-8"

Hello Stefan,

On Sun, Aug 30, 2020 at 6:07 PM Stefan Monnier <monnier@HIDDEN> wrote:
>
> >> IIUC you want
> >>
> >>     (pcase V
> >>       ((or (pred symbolp) name)
> >>        (let ((foo 'bar)) name)))
> >>
> >> to behave like
> >>
> >>     (cond
> >>      ((symbolp V) (let ((foo 'bar)) name))
> >>      (t (let ((name V)) (let ((foo 'bar)) name))))
> >>
> >> ?
> >
> > Yes, that's correct. It's also how (pcase V ((or (pred symbolp) name)
> > name) behaves...
>
> Indeed, but that's an accident.  Ideally it should either signal an
> error at macro-expansion time, or return nil when V is a symbol.

So, as I half-expected, the reaction to "pcase isn't powerful enough"
is "let's make it less powerful" :-)

Seriously, I get the impression you strongly feel pcase shouldn't be
(more) powerful, it should instead make non-explicit but fairly strong
complexity promises.

I disagree: in practice, complexity promises and optimization based on
them are often unnecessary. In fact, there's a Lisp tradition of using
assq and memq rather than building ad-hoc hash tables, even though
that often means run time is theoretically O(n^2) rather than O(n
log(n)).

> Since the current implementation doesn't go to the effort of doing
> either of those, we instead limit ourselves to recommend against using
> such patterns (IOW, "use at your own risks").

> >> I'd rather not go there
> > You'd rather have the behavior of (pcase V ((or pred symbolp) name)
> > EXPR) depend on the complexity of EXPR?
>
> More specifically, I'd rather not choose a semantics that imposes
> duplicating the branch body, since we have no control over its size and
> that can hence lead to potential code size explosion.

You're right, and it's a good thing that the duplication of the branch
body is a fixable implementation detail rather than something imposed
by the semantics.

> A code size explosion due to a particular implementation choice is
> undesirable, but a code size explosion imposed by the semantics is much
> more problematic.

Again, I don't think that's the case here.

> > I think it would be nice to have a lexical three-argument version of
> > pcase which specifies which variables are output values, treating the
> > remaining ones as input values, to make it easier to build
> > non-constant patterns.
>
> The design of `pcase` assumes you want to optimize away the tests that
> are common to the various patterns.  That can't be done with dynamic
> patterns.

Or it's a bit more difficult, at least...

> > IOW, if you want to call a function with arguments determined by
> > pcase-like patterns, why not introduce pcase-call so something like
> > the following would work:
> >
> > (defun f (hello world) (cons hello world))
> >
> > (let ((space " ") (hw "hello world"))
> >   (pcase-call 'f ((concat hello space world) hw)))
>
> How do you intend to implement this?

Proof-of-concept attached; I'm no longer sure I want to be able to say
(concat hello space world) rather than (concat hello (pred (equal
space)) world); it's inconsistent to use `equal' here rather than `eq'
for ordinary symbols (can't we at least use `eql'?), and I'm too
worried about adding an optional argument called `space' and changing
the interpretation of pcase-calls far away.

The difficult part, in fact, is deciding that we want the arglist to
be part of the exposed function API: given an "arglist" function, the
rest of the implementation seems unproblematic, though some
workarounds for lexical binding are required (if nothing else, this is
an interesting exercise in how painful lexical binding can be to work
with).

> > As for duplicating the body, that is an implementation detail. You can
> > easily avoid it by producing
> >
> > (let ((name name))
> >   (cond ((symbolp V) X)
> >     (progn (setq name V) X)))
>
> So it's more like my option of returning nil, except it would return
> the value of a surrounding `name` variable?  That could be done, but I'm
> not convinced it'd be more often useful.

I started out with a fairly explicit practical problem: parsing GCC
machine descriptions, which are (essentially) sexps but have made the
mistake of having "optional" non-final parts, and I think it would be
great to express that in a pcase pattern, both for the obvious reasons
of legibility and for some non-obvious reasons of my own.

> > disallowing the modification of name in X.
>
> That's rather hard to do (and I don't see what would be the benefit here).

I meant adding a cautionary note about it in the documentation, not
actively preventing it. If we had read-only bindings, pcase would
probably use them, but we don't.

> >> The "intended" behavior instead would be to behave like
> >>
> >>     (cond
> >>      ((symbolp V) (let ((name nil)) (let ((foo 'bar)) name)))
> >>      (t (let ((name V)) (let ((foo 'bar)) name))))
> >>
> >> That's already the behavior you get if you switch the two:
> >>
> >>     (macroexpand '(pcase V
> >>                     ((or (and (pred foo) name) (pred symbolp))
> >>                      (let ((foo 'bar)) name))))
> >>     =>
> >>     (let* ((pcase-0 (lambda (name) (let ((foo 'bar)) name))))
> >>       (cond ((foo V) (funcall pcase-0 V))
> >>             ((symbolp V) (funcall pcase-0 nil))
> >>             (t nil)))
> >
> > I don't see where the nil comes from, or why it's a useful choice for
> > a default value.
>
> It comes from the absence of a binding for `name` and was chosen because
> nil is the standard default value in Elisp.

Sorry, I meant I don't see anything in the pcase input that justifies
our using a nil value.

> It comes from this code in pcase.el:
>
>                     (let ((args (mapcar (lambda (pa)
>                                           (let ((v (assq (car pa) vars)))
>                                             (setq vars (delq v vars))
>                                             (cdr v)))
>                                         prevvars)))
>                       ;; If some of `vars' were not found in `prevvars', that's
>                       ;; OK it just means those vars aren't present in all
>                       ;; branches, so they can be used within the pattern
>                       ;; (e.g. by a `guard/let/pred') but not in the branch.
>                       ;; FIXME: But if some of `prevvars' are not in `vars' we
>                       ;; should remove them from `prevvars'!
>                       `(funcall ,res ,@args)))))))
>
> The computation of `args` searches in `vars` for the bindings expected
> by the branch (stored in `prevvars` the first time we encountered that
> branch).  The assq+cdr will return nil if a var from `prevvars` isn't
> found in `vars`.

Yes, it's the precise code I want to change.

> >> the fact that the behavior depends on the order of elements in `or` is
> >> an undesirable side effect of the implementation technique.
> > It also depends on the complexity of the branch.
> > It seems to me there are at least three consistent ways of behaving
> > (throw an error, bind name to nil, bind name to name), with an
> > inconsistent fourth way being what's currently implemented.
>
> The current implementation amounts to "we should signal an error but we
> don't bother doing so and just warn against it in the manual".
> Patch welcome ;-)

You mean a patch that would make pcase less powerful by making what I
want to do impossible rather than merely difficult?

> >> I don't know of a simple implementation.
> > Here's my better-than-nothing attempt.  I don't think that's complex;
> > if anything, it's too trivial.
>
> So you give it a search-based semantics.

I don't think the semantics are at all unclear, except for the greedy
vs shy question. The implementation could be very different, reasoning
about the length of sequences matched by pcase subpatterns, of course.

> The problem with it for me is that if we turn
>
>     `(,a ,@b)
>
> into
>
>     (append `(,a) b)

List-final ,@ is too special, IMHO, to be turned into an (append)
pattern at all.

> the pcase match will take a lot more time than the equivalent
>
>     `(,a . ,b)
>
> Of course, you can try and handle these "easy" cases more efficiently,
> but then your ,@ will sometimes be very cheap and sometimes very
> expensive (depending on when an optimization can be applied), which
> I think is a misfeature (it's for this same reason that I dislike CL
> keyword arguments for functions).

I think it's an implementation detail. Some reasoning about the
minimum and maximum length of sequences matched by pcase patterns
could help ordinary pcases, too, though:

(pcase '(a b c d)
  (`(,a ,b ,c ,d) (list a b c d)))

could call (pcase--check-length EXPVAL 4 4) rather than calling consp
four times, potentially descending into expensive predicates that are
unnecessary.
It's strange to read quotes that yo
In general, of course, multiple ,@s in the same list will be slow
because it's a difficult problem.

> I think it's fine to have such a search-based `append` (because it's
> "reliably expensive") but I'd rather not automatically use it for ,@

Again, I think that's a fundamental difference between us when it
comes to the philosophy behind pcase. If I understand you correctly,
you deliberately want to limit pcase, moving away from the intuitive
definition of it that I gave above, because there might be a situation
in which people expect better performance than our limited
implementation can give them. Is that correct?

I think that's a weak reason for a strong limitation, but of course
those are subjective questions. For example, I don't expect (pcase 9
((* x x) x)) to work, and the intuitive try-everything oracle would
work for it. In any case, if there is such a fundamental difference of
opinion, pcase simply isn't what I should be looking at.

> [ BTW, you don't need (nor want) `eval` in your definition.  ]

Thank you! Premature "optimization"...

Thanks again!

--0000000000009fed8e05ae317999
Content-Type: text/x-emacs-lisp; charset="US-ASCII"; name="pcall.el"
Content-Disposition: attachment; filename="pcall.el"
Content-Transfer-Encoding: base64
Content-ID: <f_keix5kit0>
X-Attachment-Id: f_keix5kit0

OzsgLSotIGxleGljYWwtYmluZGluZzogdDsgLSotCgooZGVmdW4gZiAoaGVsbG8gd29ybGQpCiAg
KGNvbnMgaGVsbG8gd29ybGQpKQoKKGRlZnVuIHBjYWxsLWNvbGxlY3Qtc3ltYm9scy0xIChleHBy
IHB1c2hlcikKICAoY29uZAogICAoKGNvbnNwIGV4cHIpCiAgICAocGNhbGwtY29sbGVjdC1zeW1i
b2xzLTEgKGNhciBleHByKSBwdXNoZXIpCiAgICAocGNhbGwtY29sbGVjdC1zeW1ib2xzLTEgKGNk
ciBleHByKSBwdXNoZXIpKQogICAoKHN5bWJvbHAgZXhwcikKICAgIChmdW5jYWxsIHB1c2hlciBl
eHByKSkpKQoKKGRlZnVuIHBjYWxsLWNvbGxlY3Qtc3ltYm9scyAoYmluZGluZ3MpCiAgKGxldCAo
bGlzdCkKICAgIChkb2xpc3QgKGJpbmRpbmcgYmluZGluZ3MpCiAgICAgIChwY2FsbC1jb2xsZWN0
LXN5bWJvbHMtMSBiaW5kaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGFtYmRh
ICh4KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodW5sZXNzIChtZW1xIHggbGlz
dCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocHVzaCB4IGxpc3QpKSkpKQog
ICAgbGlzdCkpCgooZGVmdW4gcGNhbGwtbWFrZS1lbnZpcm9ubWVudCAoc3ltcykKICAobGV0IChl
bnYpCiAgICAoZG9saXN0IChzeW0gc3ltcykKICAgICAgKHB1c2ggKGxpc3QgJ2NvbnMKICAgICAg
ICAgICAgICAgICAgKGxpc3QgJ3F1b3RlIHN5bSkKICAgICAgICAgICAgICAgICAgYChjb25kaXRp
b24tY2FzZSBlcnJvcgogICAgICAgICAgICAgICAgICAgICAgICxzeW0KICAgICAgICAgICAgICAg
ICAgICAgKHZvaWQtdmFyaWFibGUgKHB1c2ggJyxzeW0gdW5ib3VuZC1zeW1zKSkpKQogICAgICAg
ICAgICBlbnYpKQogICAgKGNvbnMgJ2xpc3QgKG5yZXZlcnNlIGVudikpKSkKCihkZWZ1biBwY2Fs
bGVyIChmdW5jIHBhdHMpCiAgKGxldCogKChhcmdsaXN0IChhcmdsaXN0IGZ1bmMpKQogICAgICAg
ICAoYXJnLXN5bWJvbHMgKHBjYWxsLWNvbGxlY3Qtc3ltYm9scyBhcmdsaXN0KSkpCiAgICBgKGxh
bWJkYSAoZW52IHZhbHMpCiAgICAgICAoZG9saXN0IChzeW0gJyxhcmdsaXN0KQogICAgICAgICA7
OyAoaWYgKGFzc3Egc3ltIGVudikKICAgICAgICAgOzsgICAgICh3YXJuICJzaGFkb3dpbmcgdmFy
aWFibGUgYmluZGluZyBmb3IgJVMiCiAgICAgICAgIDs7ICAgICAgICAgICBzeW0pKQogICAgICAg
ICAoc2V0cSBlbnYgKGFzc3EtZGVsZXRlLWFsbCBzeW0gZW52KSkpCiAgICAgICAoZXZhbCAnKGZp
bHRlcmVkLXBjYXNlIHZhbHMKICAgICAgICAgICAgICAgIChsYW1iZGEgKHgpCiAgICAgICAgICAg
ICAgICAgIChhc3NxIHggZW52KSkKICAgICAgICAgICAgICAgICgsKGxpc3QgJ1xgIChtYXBjYXIg
KGxhbWJkYSAoeCkgKGxpc3QgJ1wsIHgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICBwYXRzKSkKICAgICAgICAgICAgICAgICAoZnVuY2FsbCAnLGZ1bmMgLEBhcmdsaXN0KSkp
CiAgICAgICAgICAgICBlbnYpKSkpCgooZGVmdW4gYXJnbGlzdCAoZnVuYykKICAod2hpbGUgKGFu
ZCAoc3ltYm9scCBmdW5jKQoJICAgICAgKHNldHEgZnVuYyAoc3ltYm9sLWZ1bmN0aW9uIGZ1bmMp
KSkpCiAgKHBjYXNlIGZ1bmMKICAgICgob3IgYChsYW1iZGEgLGFyZ2xpc3QgLiAsYm9keSkKCSBg
KGNsb3N1cmUgLGxleGVudiAsYXJnbGlzdCAuICxib2R5KSkKICAgICBhcmdsaXN0KQogICAgKF8g
KGNkciAocmVhZAoJICAgICAoZG93bmNhc2UKCSAgICAgIChjYXIgKGhlbHAtc3BsaXQtZnVuZG9j
IChkb2N1bWVudGF0aW9uIGZ1bmMgdCkgZnVuYyB0KSkpKSkpKSkKCihkZWZtYWNybyBwY2FsbCAo
ZnVuYyAmcmVzdCBiaW5kaW5ncykKICAobGV0KiAoKHN5bXMgKHBjYWxsLWNvbGxlY3Qtc3ltYm9s
cyBiaW5kaW5ncykpCiAgICAgICAgIChlbnYgKHBjYWxsLW1ha2UtZW52aXJvbm1lbnQgc3ltcykp
CiAgICAgICAgIChwYXRzIChtYXBjYXIgIydjYXIgYmluZGluZ3MpKQogICAgICAgICAodmFscyAo
bWFwY2FyICMnY2FkciBiaW5kaW5ncykpKQogIGAobGV0ICgoZnVuYyAnLGZ1bmMpKQogICAgICh3
aGlsZSAoYW5kIChzeW1ib2xwIGZ1bmMpCgkgICAgICAgICAoc2V0cSBmdW5jIChzeW1ib2wtZnVu
Y3Rpb24gZnVuYykpKSkKICAgICAobGV0ICgocGNhbGxlciAoZnVuY2FsbCAjJ3BjYWxsZXIgZnVu
YyAnLHBhdHMpKSkKICAgICAgIChsZXQqICgodW5ib3VuZC1zeW1zIChsaXN0IG5pbCkpCiAgICAg
ICAgICAgICAgKGVudiAsZW52KQoJICAgICAgKHBjYXNlLS1lbnYgZW52KSkKICAgICAgICAgKGRv
bGlzdCAoc3ltIHVuYm91bmQtc3ltcykKICAgICAgICAgICAoc2V0cSBlbnYgKGFzc3EtZGVsZXRl
LWFsbCBzeW0gZW52KSkpCiAgICAgICAgIChmdW5jYWxsIHBjYWxsZXIgZW52IChsaXN0ICxAdmFs
cykpKSkpKSkKCihkZWZ1biBwY2FzZS0tZXhwYW5kIChleHAgY2FzZXMgZmlsdGVyKQogIDs7ICht
ZXNzYWdlICJwaWQ9JVMgKHBjYXNlLS1leHBhbmQgJVMgLi4uaGFzaD0lUykiCiAgOzsgICAgICAg
ICAgKGVtYWNzLXBpZCkgZXhwIChzeGhhc2ggY2FzZXMpKQogIChtYWNyb2V4cC1sZXQyIG1hY3Jv
ZXhwLWNvcHlhYmxlLXAgdmFsIGV4cAogICAgKGxldCogKChkZWZzICgpKQogICAgICAgICAgIChz
ZWVuICcoKSkKICAgICAgICAgICAoY29kZWdlbgogICAgICAgICAgICAobGFtYmRhIChjb2RlIHZh
cnMpCiAgICAgICAgICAgICAgKGxldCAoKHZhcnMgKHBjYXNlLS1mZ3JlcCB2YXJzIGNvZGUpKQog
ICAgICAgICAgICAgICAgICAgIChwcmV2IChhc3NxIGNvZGUgc2VlbikpKQogICAgICAgICAgICAg
ICAgKGlmIChub3QgcHJldikKICAgICAgICAgICAgICAgICAgICAobGV0ICgocmVzIChwY2FzZS1j
b2RlZ2VuIGNvZGUgdmFycykpKQogICAgICAgICAgICAgICAgICAgICAgKHB1c2ggKGxpc3QgY29k
ZSB2YXJzIHJlcykgc2VlbikKICAgICAgICAgICAgICAgICAgICAgIHJlcykKICAgICAgICAgICAg
ICAgICAgOzsgU2luY2Ugd2UgdXNlIGEgdHJlZS1iYXNlZCBwYXR0ZXJuIG1hdGNoaW5nCiAgICAg
ICAgICAgICAgICAgIDs7IHRlY2huaXF1ZSwgdGhlIGxlYXZlcyAodGhlIHBsYWNlcyB0aGF0IGNv
bnRhaW4gdGhlCiAgICAgICAgICAgICAgICAgIDs7IGNvZGUgdG8gcnVuIG9uY2UgYSBwYXR0ZXJu
IGlzIG1hdGNoZWQpIGNhbiBnZXQKICAgICAgICAgICAgICAgICAgOzsgY29waWVkIGEgdmVyeSBs
YXJnZSBudW1iZXIgb2YgdGltZXMsIHNvIHRvIGF2b2lkCiAgICAgICAgICAgICAgICAgIDs7IGNv
ZGUgZXhwbG9zaW9uLCB3ZSBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgaG93IG1hbnkKICAgICAgICAg
ICAgICAgICAgOzsgdGltZXMgd2UndmUgdXNlZCBlYWNoIGxlYWYgYW5kIG1vdmUgaXQKICAgICAg
ICAgICAgICAgICAgOzsgdG8gYSBzZXBhcmF0ZSBmdW5jdGlvbiBpZiB0aGF0IG51bWJlciBpcyB0
b28gaGlnaC4KICAgICAgICAgICAgICAgICAgOzsKICAgICAgICAgICAgICAgICAgOzsgV2UndmUg
YWxyZWFkeSB1c2VkIHRoaXMgYnJhbmNoLiAgU28gaXQgaXMgc2hhcmVkLgogICAgICAgICAgICAg
ICAgICAobGV0KiAoKGNvZGUgKGNhciBwcmV2KSkgICAgICAgICAoY2RycHJldiAoY2RyIHByZXYp
KQogICAgICAgICAgICAgICAgICAgICAgICAgKHByZXZ2YXJzIChjYXIgY2RycHJldikpICAoY2Rk
cnByZXYgKGNkciBjZHJwcmV2KSkKICAgICAgICAgICAgICAgICAgICAgICAgIChyZXMgKGNhciBj
ZGRycHJldikpKQogICAgICAgICAgICAgICAgICAgICh1bmxlc3MgKHN5bWJvbHAgcmVzKQogICAg
ICAgICAgICAgICAgICAgICAgOzsgVGhpcyBpcyB0aGUgZmlyc3QgcmVwZWF0LCBzbyB3ZSBoYXZl
IHRvIG1vdmUKICAgICAgICAgICAgICAgICAgICAgIDs7IHRoZSBicmFuY2ggdG8gYSBzZXBhcmF0
ZSBmdW5jdGlvbi4KICAgICAgICAgICAgICAgICAgICAgIChsZXQgKChic3ltCiAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgKG1ha2Utc3ltYm9sIChmb3JtYXQgInBjYXNlLSVkIiAobGVuZ3Ro
IGRlZnMpKSkpKQogICAgICAgICAgICAgICAgICAgICAgICAocHVzaCBgKCxic3ltIChsYW1iZGEg
LChtYXBjYXIgIydjYXIgcHJldnZhcnMpICxAY29kZSkpCiAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgIGRlZnMpCiAgICAgICAgICAgICAgICAgICAgICAgIChzZXRjYXIgcmVzICdmdW5jYWxs
KQogICAgICAgICAgICAgICAgICAgICAgICAoc2V0Y2RyIHJlcyAoY29ucyBic3ltIChtYXBjYXIg
IydjZHIgcHJldnZhcnMpKSkKICAgICAgICAgICAgICAgICAgICAgICAgKHNldGNhciAoY2RkciBw
cmV2KSBic3ltKQogICAgICAgICAgICAgICAgICAgICAgICAoc2V0cSByZXMgYnN5bSkpKQogICAg
ICAgICAgICAgICAgICAgIChzZXRxIHZhcnMgKGNvcHktc2VxdWVuY2UgdmFycykpCiAgICAgICAg
ICAgICAgICAgICAgKGxldCAoKGFyZ3MgKG1hcGNhciAobGFtYmRhIChwYSkKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxldCAoKHYgKGFzc3EgKGNhciBwYSkgdmFy
cykpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXRxIHZh
cnMgKGRlbHEgdiB2YXJzKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAoY2RyIHYpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBy
ZXZ2YXJzKSkpCiAgICAgICAgICAgICAgICAgICAgICA7OyBJZiBzb21lIG9mIGB2YXJzJyB3ZXJl
IG5vdCBmb3VuZCBpbiBgcHJldnZhcnMnLCB0aGF0J3MKICAgICAgICAgICAgICAgICAgICAgIDs7
IE9LIGl0IGp1c3QgbWVhbnMgdGhvc2UgdmFycyBhcmVuJ3QgcHJlc2VudCBpbiBhbGwKICAgICAg
ICAgICAgICAgICAgICAgIDs7IGJyYW5jaGVzLCBzbyB0aGV5IGNhbiBiZSB1c2VkIHdpdGhpbiB0
aGUgcGF0dGVybgogICAgICAgICAgICAgICAgICAgICAgOzsgKGUuZy4gYnkgYSBgZ3VhcmQvbGV0
L3ByZWQnKSBidXQgbm90IGluIHRoZSBicmFuY2guCiAgICAgICAgICAgICAgICAgICAgICA7OyBG
SVhNRTogQnV0IGlmIHNvbWUgb2YgYHByZXZ2YXJzJyBhcmUgbm90IGluIGB2YXJzJyB3ZQogICAg
ICAgICAgICAgICAgICAgICAgOzsgc2hvdWxkIHJlbW92ZSB0aGVtIGZyb20gYHByZXZ2YXJzJyEK
ICAgICAgICAgICAgICAgICAgICAgIGAoZnVuY2FsbCAscmVzICxAYXJncykpKSkpKSkKICAgICAg
ICAgICAodXNlZC1jYXNlcyAoKSkKICAgICAgICAgICAobWFpbgogICAgICAgICAgICAocGNhc2Ut
LXUKICAgICAgICAgICAgIChtYXBjYXIgKGxhbWJkYSAoY2FzZSkKICAgICAgICAgICAgICAgICAg
ICAgICBgKCwocGNhc2UtLW1hdGNoIHZhbCAocGNhc2UtLW1hY3JvZXhwYW5kIChjYXIgY2FzZSkp
KQogICAgICAgICAgICAgICAgICAgICAgICAgLChsYW1iZGEgKHZhcnMpCiAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAodW5sZXNzIChtZW1xIGNhc2UgdXNlZC1jYXNlcykKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgOzsgS2VlcCB0cmFjayBvZiB0aGUgY2FzZXMgdGhhdCBhcmUgdXNl
ZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHB1c2ggY2FzZSB1c2VkLWNhc2VzKSkK
ICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmdW5jYWxsCiAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgKGlmIChwY2FzZS0tc21hbGwtYnJhbmNoLXAgKGNkciBjYXNlKSkKICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgOzsgRG9uJ3QgYm90aGVyIHNoYXJpbmcgbXVsdGlwbGUK
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOzsgb2NjdXJyZW5jZXMgb2YgdGhpcyBs
ZWFmIHNpbmNlIGl0J3Mgc21hbGwuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChs
YW1iZGEgKGNvZGUgdmFycykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocGNh
c2UtY29kZWdlbiBjb2RlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgKHBjYXNlLS1mZ3JlcCB2YXJzIGNvZGUpKSkKICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIGNvZGVnZW4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNkciBjYXNl
KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcnMpKSkpCiAgICAgICAgICAgICAgICAg
ICAgIGNhc2VzKQogICAgICAgICAgICAgZmlsdGVyKSkpCiAgICAgIChkb2xpc3QgKGNhc2UgY2Fz
ZXMpCiAgICAgICAgKHVubGVzcyAob3IgKG1lbXEgY2FzZSB1c2VkLWNhc2VzKQogICAgICAgICAg
ICAgICAgICAgIChtZW1xIChjYXIgY2FzZSkgcGNhc2UtLWRvbnR3YXJuLXVwYXRzKSkKICAgICAg
ICAgIChtZXNzYWdlICJSZWR1bmRhbnQgcGNhc2UgcGF0dGVybjogJVMiIChjYXIgY2FzZSkpKSkK
ICAgICAgKG1hY3JvZXhwLWxldCogZGVmcyBtYWluKSkpKQoKKGRlZnZhciBwY2FzZS0tZW52IG5p
bCkKCihwY2FzZS1kZWZtYWNybyBjb25jYXQgKCZyZXN0IHBhdHRlcm5zKQogIChpZiBwYXR0ZXJu
cwogICAgICAobGV0KiAoKHBhdCAobGlzdCAnXGAgKGNvbnMgKGxpc3QgJ1wsIChjYXIgcGF0dGVy
bnMpKQoJCQkJICAobGlzdCAnXCwgKGNvbnMgJ2NvbmNhdAoJCQkJCQkgIChjZHIgcGF0dGVybnMp
KSkpKSkKCSAgICAgKGYgYChsYW1iZGEgKGwpCgkJICAgKGNhdGNoICdwY2FzZS0tY2FsbAoJCSAg
ICAgKGRvdGltZXMgKGkgKDErIChsZW5ndGggbCkpKQoJCSAgICAgICAobGV0KiAoKGxjIChjb25z
IChzZXEtc3Vic2VxIGwgMCBpKQoJCQkJCShzZXEtc3Vic2VxIGwgaSkpKSkKCQkJIChmaWx0ZXJl
ZC1wY2FzZSBsYwoJCQkgICAobGFtYmRhICh4KQoJCQkgICAgIChhc3NxIHggcGNhc2UtLWVudikp
CgkJCSAgICgscGF0ICh0aHJvdyAncGNhc2UtLWNhbGwgbGMpKSkpKSkpKSkKCWAoYXBwICxmICxw
YXQpKQogICAgYChwcmVkIHNlcS1lbXB0eS1wKSkpCgooZGVmbWFjcm8gZmlsdGVyZWQtcGNhc2Ug
KGV4cCBmaWx0ZXIgJnJlc3QgY2FzZXMpCiAgKGRlY2xhcmUgKGluZGVudCAxKSAoZGVidWcgKGZv
cm0gJnJlc3QgKHBjYXNlLVBBVCBib2R5KSkpKQogIChwY2FzZS0tZXhwYW5kIGV4cCBjYXNlcyBm
aWx0ZXIpKQoKKGRlZm1hY3JvIHBjYXNlIChleHAgJnJlc3QgY2FzZXMpCiAgIkV2YWx1YXRlIEVY
UCB0byBnZXQgRVhQVkFMOyB0cnkgcGFzc2luZyBjb250cm9sIHRvIG9uZSBvZiBDQVNFUy4KQ0FT
RVMgaXMgYSBsaXN0IG9mIGVsZW1lbnRzIG9mIHRoZSBmb3JtIChQQVRURVJOIENPREUuLi4pLgpG
b3IgdGhlIGZpcnN0IENBU0Ugd2hvc2UgUEFUVEVSTiBcIm1hdGNoZXNcIiBFWFBWQUwsCmV2YWx1
YXRlIGl0cyBDT0RFLi4uLCBhbmQgcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgbGFzdCBmb3JtLgpJ
ZiBubyBDQVNFIGhhcyBhIFBBVFRFUk4gdGhhdCBtYXRjaGVzLCByZXR1cm4gbmlsLgoKRWFjaCBQ
QVRURVJOIGV4cGFuZHMsIGluIGVzc2VuY2UsIHRvIGEgcHJlZGljYXRlIHRvIGNhbGwKb24gRVhQ
VkFMLiAgV2hlbiB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoYXQgY2FsbCBpcyBub24tbmlsLApQQVRU
RVJOIG1hdGNoZXMuICBQQVRURVJOIGNhbiB0YWtlIG9uZSBvZiB0aGUgZm9ybXM6CgogIF8gICAg
ICAgICAgICAgICAgbWF0Y2hlcyBhbnl0aGluZy4KICBcXD0nVkFMICAgICAgICAgICAgIG1hdGNo
ZXMgaWYgRVhQVkFMIGlzIGBlcXVhbCcgdG8gVkFMLgogIEtFWVdPUkQgICAgICAgICAgc2hvcnRo
YW5kIGZvciBcXD0nS0VZV09SRAogIElOVEVHRVIgICAgICAgICAgc2hvcnRoYW5kIGZvciBcXD0n
SU5URUdFUgogIFNUUklORyAgICAgICAgICAgc2hvcnRoYW5kIGZvciBcXD0nU1RSSU5HCiAgU1lN
Qk9MICAgICAgICAgICBtYXRjaGVzIGFueXRoaW5nIGFuZCBiaW5kcyBpdCB0byBTWU1CT0wuCiAg
ICAgICAgICAgICAgICAgICBJZiBhIFNZTUJPTCBpcyB1c2VkIHR3aWNlIGluIHRoZSBzYW1lIHBh
dHRlcm4KICAgICAgICAgICAgICAgICAgIHRoZSBzZWNvbmQgb2NjdXJyZW5jZSBiZWNvbWVzIGFu
IGBlcSd1YWxpdHkgdGVzdC4KICAocHJlZCBGVU4pICAgICAgIG1hdGNoZXMgaWYgRlVOIGNhbGxl
ZCBvbiBFWFBWQUwgcmV0dXJucyBub24tbmlsLgogIChhcHAgRlVOIFBBVCkgICAgbWF0Y2hlcyBp
ZiBGVU4gY2FsbGVkIG9uIEVYUFZBTCBtYXRjaGVzIFBBVC4KICAoZ3VhcmQgQk9PTEVYUCkgIG1h
dGNoZXMgaWYgQk9PTEVYUCBldmFsdWF0ZXMgdG8gbm9uLW5pbC4KICAobGV0IFBBVCBFWFBSKSAg
IG1hdGNoZXMgaWYgRVhQUiBtYXRjaGVzIFBBVC4KICAoYW5kIFBBVC4uLikgICAgIG1hdGNoZXMg
aWYgYWxsIHRoZSBwYXR0ZXJucyBtYXRjaC4KICAob3IgUEFULi4uKSAgICAgIG1hdGNoZXMgaWYg
YW55IG9mIHRoZSBwYXR0ZXJucyBtYXRjaGVzLgoKRlVOIGluIGBwcmVkJyBhbmQgYGFwcCcgY2Fu
IHRha2Ugb25lIG9mIHRoZSBmb3JtczoKICBTWU1CT0wgIG9yICAobGFtYmRhIEFSR1MgQk9EWSkK
ICAgICBjYWxsIGl0IHdpdGggb25lIGFyZ3VtZW50CiAgKEYgQVJHMSAuLiBBUkduKQogICAgIGNh
bGwgRiB3aXRoIEFSRzEuLkFSR24gYW5kIEVYUFZBTCBhcyBuKzEndGggYXJndW1lbnQKCkZVTiwg
Qk9PTEVYUCwgRVhQUiwgYW5kIHN1YnNlcXVlbnQgUEFUIGNhbiByZWZlciB0byB2YXJpYWJsZXMK
Ym91bmQgZWFybGllciBpbiB0aGUgcGF0dGVybiBieSBhIFNZTUJPTCBwYXR0ZXJuLgoKQWRkaXRp
b25hbCBwYXR0ZXJucyBjYW4gYmUgZGVmaW5lZCB1c2luZyBgcGNhc2UtZGVmbWFjcm8nLgoKU2Vl
IEluZm8gbm9kZSBgKGVsaXNwKSBQYXR0ZXJuLU1hdGNoaW5nIENvbmRpdGlvbmFsJyBpbiB0aGUK
RW1hY3MgTGlzcCBtYW51YWwgZm9yIG1vcmUgaW5mb3JtYXRpb24gYW5kIGV4YW1wbGVzLiIKICAo
ZGVjbGFyZSAoaW5kZW50IDEpIChkZWJ1ZyAoZm9ybSAmcmVzdCAocGNhc2UtUEFUIGJvZHkpKSkp
CiAgOzsgV2Ugd2FudCB0byB1c2UgYSB3ZWFrIGhhc2ggdGFibGUgYXMgYSBjYWNoZSwgYnV0IHRo
ZSBrZXkgd2lsbCB1bmF2b2lkYWJseQogIDs7IGJlIGJhc2VkIG9uIGBleHAnIGFuZCBgY2FzZXMn
LCB5ZXQgYGNhc2VzJyBpcyBhIGZyZXNoIG5ldyBsaXN0IGVhY2ggdGltZQogIDs7IHdlJ3JlIGNh
bGxlZCBzbyBpdCdsbCBiZSBpbW1lZGlhdGVseSBHQydkLiAgU28gd2UgdXNlIChjYXIgY2FzZXMp
IGFzIGtleQogIDs7IHdoaWNoIGRvZXMgY29tZSBzdHJhaWdodCBmcm9tIHRoZSBzb3VyY2UgY29k
ZSBhbmQgc2hvdWxkIGhlbmNlIG5vdCBiZSBHQydkCiAgOzsgc28gZWFzaWx5LgogIChsZXQgKChk
YXRhIChnZXRoYXNoIChjYXIgY2FzZXMpIHBjYXNlLS1tZW1vaXplKSkKICAgICAgICAoZmlsdGVy
IG5pbCkpCiAgICA7OyBkYXRhID0gKEVYUCBDQVNFUyAuIEVYUEFOU0lPTikKICAgIChpZiAoYW5k
IChlcXVhbCBleHAgKGNhciBkYXRhKSkgKGVxdWFsIGNhc2VzIChjYWRyIGRhdGEpKSkKICAgICAg
ICA7OyBXZSBoYXZlIHRoZSByaWdodCBleHBhbnNpb24uCiAgICAgICAgKGNkZHIgZGF0YSkKICAg
ICAgOzsgKHdoZW4gKGdldGhhc2ggKGNhciBjYXNlcykgcGNhc2UtLW1lbW9pemUtMSkKICAgICAg
OzsgICAobWVzc2FnZSAicGNhc2UtbWVtb2l6ZSBmYWlsZWQgYmVjYXVzZSBvZiB3ZWFrIGtleSEh
IikpCiAgICAgIDs7ICh3aGVuIChnZXRoYXNoIChjYXIgY2FzZXMpIHBjYXNlLS1tZW1vaXplLTIp
CiAgICAgIDs7ICAgKG1lc3NhZ2UgInBjYXNlLW1lbW9pemUgZmFpbGVkIGJlY2F1c2Ugb2YgZXEg
dGVzdCBvbiAlUyIKICAgICAgOzsgICAgICAgICAgICAoY2FyIGNhc2VzKSkpCiAgICAgIDs7ICh3
aGVuIGRhdGEKICAgICAgOzsgICAobWVzc2FnZSAicGNhc2UtbWVtb2l6ZTogZXF1YWwgZmlyc3Qg
YnJhbmNoLCB5ZXQgZGlmZmVyZW50IikpCiAgICAgIChsZXQgKChleHBhbnNpb24gKHBjYXNlLS1l
eHBhbmQgZXhwIGNhc2VzIGZpbHRlcikpKQogICAgICAgIChwdXRoYXNoIChjYXIgY2FzZXMpIGAo
LGV4cCAsY2FzZXMgLEBleHBhbnNpb24pIHBjYXNlLS1tZW1vaXplKQogICAgICAgIDs7IChwdXRo
YXNoIChjYXIgY2FzZXMpIGAoLGV4cCAsY2FzZXMgLEBleHBhbnNpb24pIHBjYXNlLS1tZW1vaXpl
LTEpCiAgICAgICAgOzsgKHB1dGhhc2ggKGNhciBjYXNlcykgYCgsZXhwICxjYXNlcyAsQGV4cGFu
c2lvbikgcGNhc2UtLW1lbW9pemUtMikKICAgICAgICBleHBhbnNpb24pKSkpCgooZGVmdW4gcGNh
c2UtLXUgKGJyYW5jaGVzIGZpbHRlcikKICAiRXhwYW5kIG1hdGNoZXIgZm9yIHJ1bGVzIEJSQU5D
SEVTLgpFYWNoIEJSQU5DSCBoYXMgdGhlIGZvcm0gKE1BVENIIENPREUgLiBWQVJTKSB3aGVyZQpD
T0RFIGlzIHRoZSBjb2RlIGdlbmVyYXRvciBmb3IgdGhhdCBicmFuY2guClZBUlMgaXMgdGhlIHNl
dCBvZiB2YXJzIGFscmVhZHkgYm91bmQgYnkgZWFybGllciBtYXRjaGVzLgpNQVRDSCBpcyB0aGUg
cGF0dGVybiB0aGF0IG5lZWRzIHRvIGJlIG1hdGNoZWQsIG9mIHRoZSBmb3JtOgogIChtYXRjaCBW
QVIgLiBQQVQpCiAgKGFuZCBNQVRDSCAuLi4pCiAgKG9yIE1BVENIIC4uLikiCiAgKHdoZW4gKHNl
dHEgYnJhbmNoZXMgKGRlbHEgbmlsIGJyYW5jaGVzKSkKICAgIChsZXQqICgoY2FyYnJhbmNoIChj
YXIgYnJhbmNoZXMpKQogICAgICAgICAgIChtYXRjaCAoY2FyIGNhcmJyYW5jaCkpIChjZGFyYnJh
bmNoIChjZHIgY2FyYnJhbmNoKSkKICAgICAgICAgICAoY29kZSAoY2FyIGNkYXJicmFuY2gpKQog
ICAgICAgICAgICh2YXJzIChjZHIgY2RhcmJyYW5jaCkpKQogICAgICAocGNhc2UtLXUxIChsaXN0
IG1hdGNoKSBjb2RlIHZhcnMgKGNkciBicmFuY2hlcykgZmlsdGVyKSkpKQoKKGRlZnVuIHBjYXNl
LS11MSAobWF0Y2hlcyBjb2RlIHZhcnMgcmVzdCBmaWx0ZXIpCiAgIlJldHVybiBjb2RlIHRoYXQg
cnVucyBDT0RFICh3aXRoIFZBUlMpIGlmIE1BVENIRVMgbWF0Y2guCk90aGVyd2lzZSwgaXQgZGVm
ZXJzIHRvIFJFU1Qgd2hpY2ggaXMgYSBsaXN0IG9mIGJyYW5jaGVzIG9mIHRoZSBmb3JtClwoRUxT
RS1NQVRDSCBFTFNFLUNPREUgLiBFTFNFLVZBUlMpLiIKICA7OyBEZXBlbmRpbmcgb24gdGhlIG9y
ZGVyIGluIHdoaWNoIHdlIGNob29zZSB0byBjaGVjayBlYWNoIG9mIHRoZSBNQVRDSEVTLAogIDs7
IHRoZSByZXN1bHRpbmcgdHJlZSBtYXkgYmUgc21hbGxlciBvciBiaWdnZXIuICBTbyBpbiBnZW5l
cmFsLCB3ZSdkIHdhbnQKICA7OyB0byBiZSBjYXJlZnVsIHRvIGNob3NlIHRoZSAib3B0aW1hbCIg
b3JkZXIuICBCdXQgcHJlZGljYXRlCiAgOzsgcGF0dGVybnMgbWFrZSB0aGlzIGhhcmRlciBiZWNh
dXNlIHRoZXkgY3JlYXRlIGRlcGVuZGVuY2llcwogIDs7IGJldHdlZW4gbWF0Y2hlcy4gIFNvIHdl
IGRvbid0IGJvdGhlciB0cnlpbmcgdG8gcmVvcmRlciBhbnl0aGluZy4KICAoY29uZAogICAoKG51
bGwgbWF0Y2hlcykgKGZ1bmNhbGwgY29kZSB2YXJzKSkKICAgKChlcSA6cGNhc2UtLWZhaWwgKGNh
ciBtYXRjaGVzKSkgKHBjYXNlLS11IHJlc3QgZmlsdGVyKSkKICAgKChlcSA6cGNhc2UtLXN1Y2Nl
ZWQgKGNhciBtYXRjaGVzKSkKICAgIChwY2FzZS0tdTEgKGNkciBtYXRjaGVzKSBjb2RlIHZhcnMg
cmVzdCBmaWx0ZXIpKQogICAoKGVxICdhbmQgKGNhYXIgbWF0Y2hlcykpCiAgICAocGNhc2UtLXUx
IChhcHBlbmQgKGNkYXIgbWF0Y2hlcykgKGNkciBtYXRjaGVzKSkgY29kZSB2YXJzIHJlc3QKICAg
ICAgICAgICAgICAgZmlsdGVyKSkKICAgKChlcSAnb3IgKGNhYXIgbWF0Y2hlcykpCiAgICAobGV0
KiAoKGFsdHMgKGNkYXIgbWF0Y2hlcykpCiAgICAgICAgICAgKHZhciAoaWYgKGVxIChjYWFyIGFs
dHMpICdtYXRjaCkgKGNhZHIgKGNhciBhbHRzKSkpKQogICAgICAgICAgIChzaW1wbGVzICcoKSkg
KG90aGVycyAnKCkpIChtZW0tZnVuICdtZW1xKSkKICAgICAgKHdoZW4gdmFyCiAgICAgICAgKGRv
bGlzdCAoYWx0IGFsdHMpCiAgICAgICAgICAoaWYgKGFuZCAoZXEgKGNhciBhbHQpICdtYXRjaCkg
KGVxIHZhciAoY2FkciBhbHQpKQogICAgICAgICAgICAgICAgICAgKGxldCAoKHVwYXQgKGNkZHIg
YWx0KSkpCiAgICAgICAgICAgICAgICAgICAgIChlcSAoY2FyLXNhZmUgdXBhdCkgJ3F1b3RlKSkp
CiAgICAgICAgICAgICAgKGxldCAoKHZhbCAoY2FkciAoY2RkciBhbHQpKSkpCiAgICAgICAgICAg
ICAgICAoY29uZCAoKGludGVnZXJwIHZhbCkKICAgICAgICAgICAgICAgICAgICAgICAod2hlbiAo
ZXEgbWVtLWZ1biAnbWVtcSkKICAgICAgICAgICAgICAgICAgICAgICAgIChzZXRxIG1lbS1mdW4g
J21lbXFsKSkpCiAgICAgICAgICAgICAgICAgICAgICAoKG5vdCAoc3ltYm9scCB2YWwpKQogICAg
ICAgICAgICAgICAgICAgICAgIChzZXRxIG1lbS1mdW4gJ21lbWJlcikpKQogICAgICAgICAgICAg
ICAgKHB1c2ggdmFsIHNpbXBsZXMpKQogICAgICAgICAgICAocHVzaCBhbHQgb3RoZXJzKSkpKQog
ICAgICAoY29uZAogICAgICAgKChudWxsIGFsdHMpIChlcnJvciAiUGxlYXNlIGF2b2lkIGl0Iikg
KHBjYXNlLS11IHJlc3QgZmlsdGVyKSkKICAgICAgIDs7IFllcywgd2UgY2FuIHVzZSBgbWVtcWwn
IChvciBgbWVtYmVyJykhCiAgICAgICAoKD4gKGxlbmd0aCBzaW1wbGVzKSAxKQogICAgICAgIChw
Y2FzZS0tdTEgKGNvbnMgYChtYXRjaCAsdmFyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgIC4gKHByZWQgKHBjYXNlLS1mbGlwICxtZW0tZnVuICcsc2ltcGxlcykpKQogICAgICAgICAg
ICAgICAgICAgICAgICAgKGNkciBtYXRjaGVzKSkKICAgICAgICAgICAgICAgICAgIGNvZGUgdmFy
cwogICAgICAgICAgICAgICAgICAgKGlmIChudWxsIG90aGVycykgcmVzdAogICAgICAgICAgICAg
ICAgICAgICAoY29ucyAoY29ucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBjYXNlLS1h
bmQgKGlmIChjZHIgb3RoZXJzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgIChjb25zICdvciAobnJldmVyc2Ugb3RoZXJzKSkKICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgKGNhciBvdGhlcnMpKQogICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgKGNkciBtYXRjaGVzKSkKICAgICAgICAgICAgICAgICAgICAgICAg
ICAgIChjb25zIGNvZGUgdmFycykpCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3QpKQog
ICAgICAgICAgICAgICAgICAgZmlsdGVyKSkKICAgICAgICh0CiAgICAgICAgKHBjYXNlLS11MSAo
Y29ucyAocG9wIGFsdHMpIChjZHIgbWF0Y2hlcykpIGNvZGUgdmFycwogICAgICAgICAgICAgICAg
ICAgKGlmIChudWxsIGFsdHMpIChwcm9nbiAoZXJyb3IgIlBsZWFzZSBhdm9pZCBpdCIpIHJlc3Qp
CiAgICAgICAgICAgICAgICAgICAgIChjb25zIChjb25zCiAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAocGNhc2UtLWFuZCAoaWYgKGNkciBhbHRzKQogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIChjb25zICdvciBhbHRzKSAoY2FyIGFsdHMpKQogICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNkciBtYXRjaGVzKSkKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIChjb25zIGNvZGUgdmFycykpCiAgICAgICAgICAgICAgICAgICAgICAg
ICAgIHJlc3QpKQogICAgICAgICAgICAgICAgICAgZmlsdGVyKSkpKSkKICAgKChlcSAnbWF0Y2gg
KGNhYXIgbWF0Y2hlcykpCiAgICAobGV0KiAoKHBvcG1hdGNoZXMgKHBvcCBtYXRjaGVzKSkKICAg
ICAgICAgICAoX29wIChjYXIgcG9wbWF0Y2hlcykpICAgICAgKGNkcnBvcG1hdGNoZXMgKGNkciBw
b3BtYXRjaGVzKSkKICAgICAgICAgICAoc3ltIChjYXIgY2RycG9wbWF0Y2hlcykpCiAgICAgICAg
ICAgKHVwYXQgKGNkciBjZHJwb3BtYXRjaGVzKSkpCiAgICAgIChjb25kCiAgICAgICAoKG1lbXEg
dXBhdCAnKHQgXykpCiAgICAgICAgKGxldCAoKGNvZGUgKHBjYXNlLS11MSBtYXRjaGVzIGNvZGUg
dmFycyByZXN0IGZpbHRlcikpKQogICAgICAgICAgKGlmIChlcSB1cGF0ICdfKSBjb2RlCiAgICAg
ICAgICAgIChtYWNyb2V4cC0td2Fybi1hbmQtcmV0dXJuCiAgICAgICAgICAgICAiUGF0dGVybiB0
IGlzIGRlcHJlY2F0ZWQuICBVc2UgYF8nIGluc3RlYWQiCiAgICAgICAgICAgICBjb2RlKSkpKQog
ICAgICAgKChlcSB1cGF0ICdwY2FzZS0tZG9udGNhcmUpIDpwY2FzZS0tZG9udGNhcmUpCiAgICAg
ICAoKG1lbXEgKGNhci1zYWZlIHVwYXQpICcoZ3VhcmQgcHJlZCkpCiAgICAgICAgKGlmIChlcSAo
Y2FyIHVwYXQpICdwcmVkKSAocGNhc2UtLW1hcmstdXNlZCBzeW0pKQogICAgICAgIChsZXQqICgo
c3BsaXRyZXN0CiAgICAgICAgICAgICAgICAocGNhc2UtLXNwbGl0LXJlc3QKICAgICAgICAgICAg
ICAgICBzeW0gKGxhbWJkYSAocGF0KSAocGNhc2UtLXNwbGl0LXByZWQgdmFycyB1cGF0IHBhdCkp
IHJlc3QpKQogICAgICAgICAgICAgICAodGhlbi1yZXN0IChjYXIgc3BsaXRyZXN0KSkKICAgICAg
ICAgICAgICAgKGVsc2UtcmVzdCAoY2RyIHNwbGl0cmVzdCkpKQogICAgICAgICAgKHBjYXNlLS1p
ZiAoaWYgKGVxIChjYXIgdXBhdCkgJ3ByZWQpCiAgICAgICAgICAgICAgICAgICAgICAgICAocGNh
c2UtLWZ1bmNhbGwgKGNhZHIgdXBhdCkgc3ltIHZhcnMpCiAgICAgICAgICAgICAgICAgICAgICAg
KHBjYXNlLS1ldmFsIChjYWRyIHVwYXQpIHZhcnMpKQogICAgICAgICAgICAgICAgICAgICAocGNh
c2UtLXUxIG1hdGNoZXMgY29kZSB2YXJzIHRoZW4tcmVzdCBmaWx0ZXIpCiAgICAgICAgICAgICAg
ICAgICAgIChwY2FzZS0tdSBlbHNlLXJlc3QgZmlsdGVyKSkpKQogICAgICAgKChhbmQgKHN5bWJv
bHAgdXBhdCkgdXBhdCkKICAgICAgICAocGNhc2UtLW1hcmstdXNlZCBzeW0pCiAgICAgICAgKGNv
bmQKICAgICAgICAgKChhbmQgZmlsdGVyIChmdW5jYWxsIGZpbHRlciB1cGF0KSkKICAgICAgICAg
IChwY2FzZS0tdTEgKGNvbnMgYChtYXRjaCAsc3ltIC4gKHByZWQgKGxhbWJkYSAoeCkgKGVxdWFs
ICwoY2RyIChmdW5jYWxsIGZpbHRlciB1cGF0KSkgeCkpKSkKICAgICAgICAgICAgICAgICAgICAg
ICAgICAgbWF0Y2hlcykKICAgICAgICAgICAgICAgICAgICAgY29kZSB2YXJzIHJlc3QgZmlsdGVy
KSkKICAgICAgICAgKChub3QgKGFzc3EgdXBhdCB2YXJzKSkKICAgICAgICAgIChwY2FzZS0tdTEg
bWF0Y2hlcyBjb2RlIChjb25zIChjb25zIHVwYXQgc3ltKSB2YXJzKSByZXN0IGZpbHRlcikpCiAg
ICAgICAgICg7OyBOb24tbGluZWFyIHBhdHRlcm4uICBUdXJuIGl0IGludG8gYW4gYGVxJyB0ZXN0
LgogICAgICAgICAgKHBjYXNlLS11MSAoY29ucyBgKG1hdGNoICxzeW0gLiAocHJlZCAoZXEgLChj
ZHIgKGFzc3EgdXBhdCB2YXJzKSkpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hl
cykKICAgICAgICAgICAgICAgICAgICAgY29kZSB2YXJzIHJlc3QgZmlsdGVyKSkpKQogICAgICAg
KChlcSAoY2FyLXNhZmUgdXBhdCkgJ2xldCkKICAgICAgICA7OyBBIHVwYXQgb2YgdGhlIGZvcm0g
KGxldCBWQVIgRVhQKS4KICAgICAgICA7OyAocGNhc2UtLXUxIG1hdGNoZXMgY29kZQogICAgICAg
IDs7ICAgICAgICAgICAgKGNvbnMgKGNvbnMgKG50aCAxIHVwYXQpIChudGggMiB1cGF0KSkgdmFy
cykgcmVzdCkKICAgICAgICAobWFjcm9leHAtbGV0MgogICAgICAgICAgICBtYWNyb2V4cC1jb3B5
YWJsZS1wIHN5bQogICAgICAgICAgICAocGNhc2UtLWV2YWwgKG50aCAyIHVwYXQpIHZhcnMpCiAg
ICAgICAgICAocGNhc2UtLXUxIChjb25zIChwY2FzZS0tbWF0Y2ggc3ltIChudGggMSB1cGF0KSkg
bWF0Y2hlcykKICAgICAgICAgICAgICAgICAgICAgY29kZSB2YXJzIHJlc3QgZmlsdGVyKSkpCiAg
ICAgICAoKGVxIChjYXItc2FmZSB1cGF0KSAnYXBwKQogICAgICAgIDs7IEEgdXBhdCBvZiB0aGUg
Zm9ybSAoYXBwIEZVTiBQQVQpCiAgICAgICAgKHBjYXNlLS1tYXJrLXVzZWQgc3ltKQogICAgICAg
IChsZXQqICgoZnVuIChudGggMSB1cGF0KSkKICAgICAgICAgICAgICAgKG5zeW0gKGdlbnN5bSAi
eCIpKQogICAgICAgICAgICAgICAoYm9keQogICAgICAgICAgICAgICAgOzsgV2UgZG9uJ3QgY2hh
bmdlIGBtYXRjaGVzJyB0byByZXVzZSB0aGUgbmV3bHkgY29tcHV0ZWQgdmFsdWUsCiAgICAgICAg
ICAgICAgICA7OyBiZWNhdXNlIHdlIGFzc3VtZSB0aGVyZSBzaG91bGRuJ3QgYmUgc3VjaCByZWR1
bmRhbmN5IGluIHRoZXJlLgogICAgICAgICAgICAgICAgKHBjYXNlLS11MSAoY29ucyAocGNhc2Ut
LW1hdGNoIG5zeW0gKG50aCAyIHVwYXQpKSBtYXRjaGVzKQogICAgICAgICAgICAgICAgICAgICAg
ICAgICBjb2RlIHZhcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBjYXNlLS1hcHAtc3Vi
c3QtcmVzdCByZXN0IHN5bSBmdW4gbnN5bSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxh
bWJkYSAoeCkgKGFuZCAobm90IChlcSB4IG5zeW0pKSkgKGFuZCBmaWx0ZXIgKGZ1bmNhbGwgZmls
dGVyIHgpKSkpKSkKICAgICAgICAgIChpZiAobm90IChnZXQgbnN5bSAncGNhc2UtdXNlZCkpCiAg
ICAgICAgICAgICAgYm9keQogICAgICAgICAgICAobWFjcm9leHAtbGV0KgogICAgICAgICAgICAg
YCgoLG5zeW0gLChwY2FzZS0tZnVuY2FsbCBmdW4gc3ltIHZhcnMpKSkKICAgICAgICAgICAgIGJv
ZHkpKSkpCiAgICAgICAoKGVxIChjYXItc2FmZSB1cGF0KSAncXVvdGUpCiAgICAgICAgKHBjYXNl
LS1tYXJrLXVzZWQgc3ltKQogICAgICAgIChsZXQqICgodmFsIChjYWRyIHVwYXQpKQogICAgICAg
ICAgICAgICAoc3BsaXRyZXN0IChwY2FzZS0tc3BsaXQtcmVzdAogICAgICAgICAgICAgICAgICAg
ICAgICAgICBzeW0gKGxhbWJkYSAocGF0KSAocGNhc2UtLXNwbGl0LWVxdWFsIHZhbCBwYXQpKSBy
ZXN0KSkKICAgICAgICAgICAgICAgKHRoZW4tcmVzdCAoY2FyIHNwbGl0cmVzdCkpCiAgICAgICAg
ICAgICAgIChlbHNlLXJlc3QgKGNkciBzcGxpdHJlc3QpKSkKICAgICAgICAgIChwY2FzZS0taWYg
KGNvbmQKICAgICAgICAgICAgICAgICAgICAgICgobnVsbCB2YWwpIGAobnVsbCAsc3ltKSkKICAg
ICAgICAgICAgICAgICAgICAgICgoaW50ZWdlcnAgdmFsKSBgKGVxbCAsc3ltICx2YWwpKQogICAg
ICAgICAgICAgICAgICAgICAgKChzeW1ib2xwIHZhbCkKICAgICAgICAgICAgICAgICAgICAgICAo
aWYgKHBjYXNlLS1zZWxmLXF1b3RpbmctcCB2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgICAg
IGAoZXEgLHN5bSAsdmFsKQogICAgICAgICAgICAgICAgICAgICAgICAgYChlcSAsc3ltICcsdmFs
KSkpCiAgICAgICAgICAgICAgICAgICAgICAodCBgKGVxdWFsICxzeW0gJyx2YWwpKSkKICAgICAg
ICAgICAgICAgICAgICAgKHBjYXNlLS11MSBtYXRjaGVzIGNvZGUgdmFycyB0aGVuLXJlc3QgZmls
dGVyKQogICAgICAgICAgICAgICAgICAgICAocGNhc2UtLXUgZWxzZS1yZXN0IGZpbHRlcikpKSkK
ICAgICAgICgoZXEgKGNhci1zYWZlIHVwYXQpICdub3QpCiAgICAgICAgOzsgRklYTUU6IFRoZSBp
bXBsZW1lbnRhdGlvbiBiZWxvdyBpcyBuYWl2ZSBhbmQgcmVzdWx0cyBpbgogICAgICAgIDs7IGlu
ZWZmaWNpZW50IGNvZGUuCiAgICAgICAgOzsgVG8gbWFrZSBpdCB3b3JrIHJpZ2h0LCB3ZSB3b3Vs
ZCBuZWVkIHRvIHR1cm4gcGNhc2UtLXUxJ3MKICAgICAgICA7OyBgY29kZScgYW5kIGB2YXJzJyBp
bnRvIGEgc2luZ2xlIGFyZ3VtZW50IG9mIHRoZSBzYW1lIGZvcm0gYXMKICAgICAgICA7OyBgcmVz
dCcuICBXZSB3b3VsZCBhbHNvIG5lZWQgdG8gc3BsaXQgdGhpcyBuZXcgYHRoZW4tcmVzdCcgYXJn
dW1lbnQKICAgICAgICA7OyBmb3IgZXZlcnkgdGVzdCAoY3VycmVudGx5IHdlIGRvbid0IGJvdGhl
ciB0byBkbyBpdCBzaW5jZQogICAgICAgIDs7IGl0J3Mgb25seSB1c2VmdWwgZm9yIG9kZCBwYXR0
ZXJucyBsaWtlIChhbmQgYChQQVQxIC4gUEFUMikKICAgICAgICA7OyBgKFBBVDMgLiBQQVQ0KSkg
d2hpY2ggdGhlIHByb2dyYW1tZXIgY2FuIGVhc2lseSByZXdyaXRlCiAgICAgICAgOzsgdG8gdGhl
IG1vcmUgZWZmaWNpZW50IGAoLChhbmQgUEFUMSBQQVQzKSAuICwoYW5kIFBBVDIgUEFUNCkpKS4K
ICAgICAgICAocGNhc2UtLXUxIGAoKG1hdGNoICxzeW0gLiAsKGNhZHIgdXBhdCkpKQogICAgICAg
ICAgICAgICAgICAgOzsgRklYTUU6IFRoaXMgY29kZWdlbiBpcyBub3QgY2FyZWZ1bCB0byBzaGFy
ZSBpdHMKICAgICAgICAgICAgICAgICAgIDs7IGNvZGUgaWYgdXNlZCBzZXZlcmFsIHRpbWVzOiBj
b2RlIGJsb3cgdXAgaXMgbGlrZWx5LgogICAgICAgICAgICAgICAgICAgKGxhbWJkYSAoX3ZhcnMp
CiAgICAgICAgICAgICAgICAgICAgIDs7IGB2YXJzJyB3aWxsIGxpa2VseSBjb250YWluIGJpbmRp
bmdzIHdoaWNoIGFyZQogICAgICAgICAgICAgICAgICAgICA7OyBub3QgYWx3YXlzIGF2YWlsYWJs
ZSBpbiBvdGhlciBwYXRocyB0bwogICAgICAgICAgICAgICAgICAgICA7OyBgcmVzdCcsIHNvIHRo
ZXJlJyBubyBwb2ludCB0cnlpbmcgdG8gcGFzcwogICAgICAgICAgICAgICAgICAgICA7OyB0aGVt
IGRvd24uCiAgICAgICAgICAgICAgICAgICAgIChwY2FzZS0tdSByZXN0IGZpbHRlcikpCiAgICAg
ICAgICAgICAgICAgICB2YXJzCiAgICAgICAgICAgICAgICAgICAobGlzdCBgKChhbmQgLiAsbWF0
Y2hlcykgLGNvZGUgLiAsdmFycykpCiAgICAgICAgICAgICAgICAgICBmaWx0ZXIpKQogICAgICAg
KHQgKGVycm9yICJVbmtub3duIHBhdHRlcm4gYCVTJyIgdXBhdCkpKSkpCiAgICh0IChlcnJvciAi
SW5jb3JyZWN0IE1BVENIICVTIiAoY2FyIG1hdGNoZXMpKSkpKQoKKGxldCAoKHNwYWNlICIgIikp
CiAgKHBjYWxsIGYgKChjb25jYXQgaGVsbG8gc3BhY2Ugd29ybGQpICJoZWxsbyB3b3JsZCIpKSkK
CihkZWZ1biBwY2FzZS0tbGVuZ3RoIChwYXR0ZXJuKQogICAgKHNldHEgcGF0dGVybiAocGNhc2Ut
LW1hY3JvZXhwYW5kIHBhdHRlcm4pKQogICAgKHBjYXNlIHBhdHRlcm4KICAgICAgKGAocHJlZCBu
dWxsKSAoY29ucyAwIDApKQogICAgICAoYCduaWwgKGNvbnMgMCAwKSkKICAgICAgKGAocHJlZCBj
b25zcCkgKGNvbnMgMSAxLjBlK0lORikpCiAgICAgIChgKGFwcCBjZHIgLHBhdHRlcm4pCiAgICAg
ICAobGV0ICgobGVuZ3RoIChwY2FzZS0tbGVuZ3RoIHBhdHRlcm4pKSkKCSAoaWYgKD4gKGNhciBs
ZW5ndGgpIDApCgkgICAgIChjb25zICgxKyAoY2FyIGxlbmd0aCkpICgxKyAoY2RyIGxlbmd0aCkp
KQoJICAgKGNvbnMgMCAoMSsgKGNkciBsZW5ndGgpKSkpKSkKICAgICAgKGAob3IgLiAscGF0dGVy
bnMpCiAgICAgICAobGV0ICgoaW5mIDApCgkgICAgIChzdXAgMS4wZStJTkYpKQoJIChkb2xpc3Qg
KHBhdHRlcm4gcGF0dGVybnMpCgkgICAobGV0KiAoKGlzIChwY2FzZS0tbGVuZ3RoIHBhdHRlcm4p
KQoJCSAgKGkgKGNhciBpcykpCgkJICAocyAoY2RyIGlzKSkpCgkgICAgIChzZXRxIGluZiAobWlu
IGluZiBpKSkKCSAgICAgKHNldHEgc3VwIChtYXggc3VwIHMpKSkpCgkgKGNvbnMgaW5mIHN1cCkp
KQogICAgICAoYChhbmQgLiAscGF0dGVybnMpCiAgICAgICAobGV0ICgoaW5mIDApCgkgICAgIChz
dXAgMS4wZStJTkYpKQoJIChkb2xpc3QgKHBhdHRlcm4gcGF0dGVybnMpCgkgICAobGV0KiAoKGlz
IChwY2FzZS0tbGVuZ3RoIHBhdHRlcm4pKQoJCSAgKGkgKGNhciBpcykpCgkJICAocyAoY2RyIGlz
KSkpCgkgICAgIChzZXRxIGluZiAobWF4IGluZiBpKSkKCSAgICAgKHNldHEgc3VwIChtaW4gc3Vw
IHMpKSkpCgkgKGNvbnMgaW5mIHN1cCkpKQogICAgICAoXyAoY29ucyAwIDEuMGUrSU5GKSkpKQoK
KHBjYXNlLWRlZm1hY3JvIG5vdCAocGF0KQogIGAoYXBwIChsYW1iZGEgKGV4cHZhbCkgKG5vdCAo
cGNhc2UgZXhwdmFsICgscGF0IHQpKSkpCiAgICAgICAgKHByZWQgaWRlbnRpdHkpKSkK
--0000000000009fed8e05ae317999--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 30 Aug 2020 18:07:59 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sun Aug 30 14:07:59 2020
Received: from localhost ([127.0.0.1]:50712 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kCRkF-000131-FM
	for submit <at> debbugs.gnu.org; Sun, 30 Aug 2020 14:07:59 -0400
Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:52442)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <monnier@HIDDEN>) id 1kCRkD-00012m-2v
 for 43100 <at> debbugs.gnu.org; Sun, 30 Aug 2020 14:07:58 -0400
Received: from pmg2.iro.umontreal.ca (localhost.localdomain [127.0.0.1])
 by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id 0EE8080B69;
 Sun, 30 Aug 2020 14:07:51 -0400 (EDT)
Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1])
 by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id D69498066B;
 Sun, 30 Aug 2020 14:07:48 -0400 (EDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca;
 s=mail; t=1598810868;
 bh=dVo02K/GJSZKK0+eG6fgaUVb47Yhg/ndzsvRMUils0I=;
 h=From:To:Cc:Subject:References:Date:In-Reply-To:From;
 b=cemW9EOLMRQ8a54JT8aMV0UgvhUgOD3pJnHthJopMqoTL5bz/YRHQm5UszRfoxvou
 jZukgbvQ6CgXd/lQiuRm6c7Vrq9xNgnFq71a/1+Q0Go75omat2mMoEFvChmURPul0A
 lIrLWw0ljsUQ/cTfHuKQr2pDlnGVmd/mJMEFTe8v88oTv1r9QQgw2JJMoXwtGg+vS3
 IaorihiIdKmQT1U0uRv7cK+uB3I5E9r5wWw4akqcAO24MME5u9Yi1a5b/g550sZd4j
 P+VfnBhJlwFl0pPdAqM+xJBgNDqojE0aK5UUZaIXJlWaL0ge58eYHEAyvHWLDySfRE
 O40OW2LWtX+kg==
Received: from alfajor (unknown [45.72.232.131])
 by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id A3BF4120535;
 Sun, 30 Aug 2020 14:07:48 -0400 (EDT)
From: Stefan Monnier <monnier@HIDDEN>
To: Pip Cet <pipcet@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
Message-ID: <jwvr1roysef.fsf-monnier+emacs@HIDDEN>
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
 <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
 <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
 <jwvpn791m8z.fsf-monnier+emacs@HIDDEN>
 <CAOqdjBeXLHsbZtcWypng4+DpFtkXBs-+DTkCP3BSFRbThdJpQQ@HIDDEN>
Date: Sun, 30 Aug 2020 14:07:47 -0400
In-Reply-To: <CAOqdjBeXLHsbZtcWypng4+DpFtkXBs-+DTkCP3BSFRbThdJpQQ@HIDDEN>
 (Pip Cet's message of "Sun, 30 Aug 2020 16:21:42 +0000")
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain
X-SPAM-INFO: Spam detection results:  0
 ALL_TRUSTED                -1 Passed through trusted hosts only via SMTP
 AWL -0.060 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DKIM_SIGNED               0.1 Message has a DKIM or DK signature,
 not necessarily valid
 DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature
 DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's
 domain
X-SPAM-LEVEL: 
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 43100
Cc: Philipp Stephani <p.stephani2@HIDDEN>, 43100 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

>> IIUC you want
>>
>>     (pcase V
>>       ((or (pred symbolp) name)
>>        (let ((foo 'bar)) name)))
>>
>> to behave like
>>
>>     (cond
>>      ((symbolp V) (let ((foo 'bar)) name))
>>      (t (let ((name V)) (let ((foo 'bar)) name))))
>>
>> ?
>
> Yes, that's correct. It's also how (pcase V ((or (pred symbolp) name)
> name) behaves...

Indeed, but that's an accident.  Ideally it should either signal an
error at macro-expansion time, or return nil when V is a symbol.
Since the current implementation doesn't go to the effort of doing
either of those, we instead limit ourselves to recommend against using
such patterns (IOW, "use at your own risks").

>> I'd rather not go there
> You'd rather have the behavior of (pcase V ((or pred symbolp) name)
> EXPR) depend on the complexity of EXPR?

More specifically, I'd rather not choose a semantics that imposes
duplicating the branch body, since we have no control over its size and
that can hence lead to potential code size explosion.

A code size explosion due to a particular implementation choice is
undesirable, but a code size explosion imposed by the semantics is much
more problematic.

> I think it would be nice to have a lexical three-argument version of
> pcase which specifies which variables are output values, treating the
> remaining ones as input values, to make it easier to build
> non-constant patterns.

The design of `pcase` assumes you want to optimize away the tests that
are common to the various patterns.  That can't be done with dynamic
patterns.

> IOW, if you want to call a function with arguments determined by
> pcase-like patterns, why not introduce pcase-call so something like
> the following would work:
>
> (defun f (hello world) (cons hello world))
>
> (let ((space " ") (hw "hello world"))
>   (pcase-call 'f ((concat hello space world) hw)))

How do you intend to implement this?

> As for duplicating the body, that is an implementation detail. You can
> easily avoid it by producing
>
> (let ((name name))
>   (cond ((symbolp V) X)
>     (progn (setq name V) X)))

So it's more like my option of returning nil, except it would return
the value of a surrounding `name` variable?  That could be done, but I'm
not convinced it'd be more often useful.

> disallowing the modification of name in X.

That's rather hard to do (and I don't see what would be the benefit here).

>> The "intended" behavior instead would be to behave like
>>
>>     (cond
>>      ((symbolp V) (let ((name nil)) (let ((foo 'bar)) name)))
>>      (t (let ((name V)) (let ((foo 'bar)) name))))
>>
>> That's already the behavior you get if you switch the two:
>>
>>     (macroexpand '(pcase V
>>                     ((or (and (pred foo) name) (pred symbolp))
>>                      (let ((foo 'bar)) name))))
>>     =>
>>     (let* ((pcase-0 (lambda (name) (let ((foo 'bar)) name))))
>>       (cond ((foo V) (funcall pcase-0 V))
>>             ((symbolp V) (funcall pcase-0 nil))
>>             (t nil)))
>
> I don't see where the nil comes from, or why it's a useful choice for
> a default value.

It comes from the absence of a binding for `name` and was chosen because
nil is the standard default value in Elisp.

It comes from this code in pcase.el:

                    (let ((args (mapcar (lambda (pa)
                                          (let ((v (assq (car pa) vars)))
                                            (setq vars (delq v vars))
                                            (cdr v)))
                                        prevvars)))
                      ;; If some of `vars' were not found in `prevvars', that's
                      ;; OK it just means those vars aren't present in all
                      ;; branches, so they can be used within the pattern
                      ;; (e.g. by a `guard/let/pred') but not in the branch.
                      ;; FIXME: But if some of `prevvars' are not in `vars' we
                      ;; should remove them from `prevvars'!
                      `(funcall ,res ,@args)))))))

The computation of `args` searches in `vars` for the bindings expected
by the branch (stored in `prevvars` the first time we encountered that
branch).  The assq+cdr will return nil if a var from `prevvars` isn't
found in `vars`.

>> the fact that the behavior depends on the order of elements in `or` is
>> an undesirable side effect of the implementation technique.
> It also depends on the complexity of the branch.
> It seems to me there are at least three consistent ways of behaving
> (throw an error, bind name to nil, bind name to name), with an
> inconsistent fourth way being what's currently implemented.

The current implementation amounts to "we should signal an error but we
don't bother doing so and just warn against it in the manual".
Patch welcome ;-)

>> I don't know of a simple implementation.
> Here's my better-than-nothing attempt.  I don't think that's complex;
> if anything, it's too trivial.

So you give it a search-based semantics.
The problem with it for me is that if we turn

    `(,a ,@b)

into

    (append `(,a) b)

the pcase match will take a lot more time than the equivalent

    `(,a . ,b)

Of course, you can try and handle these "easy" cases more efficiently,
but then your ,@ will sometimes be very cheap and sometimes very
expensive (depending on when an optimization can be applied), which
I think is a misfeature (it's for this same reason that I dislike CL
keyword arguments for functions).

I think it's fine to have such a search-based `append` (because it's
"reliably expensive") but I'd rather not automatically use it for ,@ 

[ BTW, you don't need (nor want) `eval` in your definition.  ]


        Stefan





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 30 Aug 2020 16:22:26 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sun Aug 30 12:22:26 2020
Received: from localhost ([127.0.0.1]:50649 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kCQ66-00074G-Dh
	for submit <at> debbugs.gnu.org; Sun, 30 Aug 2020 12:22:26 -0400
Received: from mail-oo1-f43.google.com ([209.85.161.43]:35447)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pipcet@HIDDEN>) id 1kCQ64-000743-OX
 for 43100 <at> debbugs.gnu.org; Sun, 30 Aug 2020 12:22:25 -0400
Received: by mail-oo1-f43.google.com with SMTP id k13so548235oor.2
 for <43100 <at> debbugs.gnu.org>; Sun, 30 Aug 2020 09:22:24 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=w07nNXECaXWljAI84FYLJ8MZMakE00ftqm/8EmghEng=;
 b=Iu6h+3p8lYul7D1cYx7XnEb5vRxiXxQ6TNFAF3tzf/IQetE2nMgE+CUQ8Fm1wKTd27
 zWxFIa/uJrU5ZcqMVqhWpZ2jQlQthuR0xULBHJ1A7YlwKvRMa/f1cbTXFtq6phmrRZUJ
 IOddHO9Lk57EGB01mJKQV6+dZFVOlbFVne5FQ60OJTRW76syrxTHE2OpgifFvE2ma96l
 Ciku9bSkuA3w5GmXbcxh1y0a0Uv8dNH6FMi17xsJVo9tIZ/VW/vLdjFiZTpBtuF1tCWE
 bsdz888irjxAOSWWkQR7uuNqZ23ZAHQIzn8HLnqwysIOCAObIe+v9HPyo7ujPSvgqsBZ
 ZyUA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=w07nNXECaXWljAI84FYLJ8MZMakE00ftqm/8EmghEng=;
 b=tVgjHouIwGpFi3L72EmQlvNLAjh5Xe45MR+yMjWxgBn3Zkd2oONYcYgLxoDCR3Z3Np
 6LulY4hGnCjAnWEKGZjdLx0uJfJp6CsEQ2VVvY38H9ci2NUh0uBuTVT/IASf7QOKFuL0
 hV/IztF+65jFchF4KN6u2/UWYmRbsXoyuldsxMRzL9mkids5RCfitb3XY/CqTl3ItfOn
 Y5qV6aKo4BQwsgVODxWuZa35swI4uE2Lhxw2vn8RS7j3mKu+8EuGkQNprkcStKXv//pB
 3ftEEDxbjjQj+ytv0HPv8DEIwJb+ZaLkBCS2J5rjzSeSyClZScgWWqAjLEy3lZRPnUtQ
 rkEg==
X-Gm-Message-State: AOAM531m7QnJUSFsY9qRMcbCA4pdGGaJW+JyhDactCCEBebOcASbxg/X
 Zd2QhMiVVsR1R5qyrIFXRvIFqejKj/hJgf0GEDs=
X-Google-Smtp-Source: ABdhPJwzK9Q2Cc9qXRCviwjmV7Ht+7MSjinKq9nTotNWCdAXztHg//ui0DCCdl2yuKeFiESu9avmot02mOjGSlPSWx0=
X-Received: by 2002:a4a:aa42:: with SMTP id y2mr5315735oom.88.1598804538893;
 Sun, 30 Aug 2020 09:22:18 -0700 (PDT)
MIME-Version: 1.0
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
 <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
 <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
 <jwvpn791m8z.fsf-monnier+emacs@HIDDEN>
In-Reply-To: <jwvpn791m8z.fsf-monnier+emacs@HIDDEN>
From: Pip Cet <pipcet@HIDDEN>
Date: Sun, 30 Aug 2020 16:21:42 +0000
Message-ID: <CAOqdjBeXLHsbZtcWypng4+DpFtkXBs-+DTkCP3BSFRbThdJpQQ@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
To: Stefan Monnier <monnier@HIDDEN>
Content-Type: text/plain; charset="UTF-8"
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 43100
Cc: Philipp Stephani <p.stephani2@HIDDEN>, 43100 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Sat, Aug 29, 2020 at 4:06 PM Stefan Monnier <monnier@HIDDEN> wrote:
> >> > I'm having trouble with pcase's behavior.
> >> >
> >> > (pcase "a"
> >> >   ((or (pred symbolp) name)
> >> >    (let ((foo 'bar)) name)))
> >> >
> >> > throws an error. It shouldn't.
> >>
> >> Isn't this case documented in the manual? The last section of
> >> https://www.gnu.org/software/emacs/manual/html_node/elisp/pcase-Macro.html
> >> states:
> >> "It makes no sense for each sub-pattern [in an `or' sequence] to
> >> let-bind a different set of symbols because the body forms have no way
> >> to distinguish which sub-pattern matched and choose among the
> >> different sets."
> >
> > Thanks for pointing this out.
> >
> > I disagree with what the documentation says there: it does make
> > perfect sense, to me, to conditionally shadow a (lexical) let binding
> > with a pcase-let one, and body forms will have no trouble in practice
> > distinguishing between the outer and the inner let-binding.
>
> How do you expect them to distinguish?

By repeating the pcase pattern's predicate, usually, or by relying on
other knowledge about the previous value. That's in practice, in
theory you can use gensym or an inaccessible cons.

> IIUC you want
>
>     (pcase V
>       ((or (pred symbolp) name)
>        (let ((foo 'bar)) name)))
>
> to behave like
>
>     (cond
>      ((symbolp V) (let ((foo 'bar)) name))
>      (t (let ((name V)) (let ((foo 'bar)) name))))
>
> ?

Yes, that's correct. It's also how (pcase V ((or (pred symbolp) name)
name) behaves...

> I'd rather not go there

You'd rather have the behavior of (pcase V ((or pred symbolp) name)
EXPR) depend on the complexity of EXPR?

> since it means that the single occurrence of the
> `name` identifier in the branch's body refers to two different variable
> bindings depending on which pattern was matched.  It smells of dynamic
> scoping, tho it is admittedly compatible with lexical-scoping but only at
> the cost of having to duplicate the branch's body.

Well, I'm afraid pcase does smell of dynamic scoping :-)

More precisely, to me, what pcase simulates is building a lexical
environment, then evaluating the BODY argument with the environment as
second argument. (pcase EXP (PAT BODY)) is very roughly:

(for-each-possible-environment ENV (if (equalish (eval PAT ENV) EXP)
(return (eval BODY ENV)))

where for-each-possible-environment magically finds the smallest (or
"best") ENV first.

I think it would be nice to have a lexical three-argument version of
pcase which specifies which variables are output values, treating the
remaining ones as input values, to make it easier to build
non-constant patterns. But that would be very different from what
pcase does do today, which is closer to what I hinted at above.

IOW, if you want to call a function with arguments determined by
pcase-like patterns, why not introduce pcase-call so something like
the following would work:

(defun f (hello world) (cons hello world))

(let ((space " ") (hw "hello world"))
  (pcase-call 'f ((concat hello space world) hw)))

(that would introduce named function arguments, which I think would be
a nice bonus)?

But it's not what pcase is! There's no function call or argument list
in there, just expressions involved in environments.

As for duplicating the body, that is an implementation detail. You can
easily avoid it by producing

(let ((name name))
  (cond ((symbolp V) X)
    (progn (setq name V) X)))

disallowing the modification of name in X.

> The "intended" behavior instead would be to behave like
>
>     (cond
>      ((symbolp V) (let ((name nil)) (let ((foo 'bar)) name)))
>      (t (let ((name V)) (let ((foo 'bar)) name))))
>
> That's already the behavior you get if you switch the two:
>
>     (macroexpand '(pcase V
>                     ((or (and (pred foo) name) (pred symbolp))
>                      (let ((foo 'bar)) name))))
>     =>
>     (let* ((pcase-0 (lambda (name) (let ((foo 'bar)) name))))
>       (cond ((foo V) (funcall pcase-0 V))
>             ((symbolp V) (funcall pcase-0 nil))
>             (t nil)))

I don't see where the nil comes from, or why it's a useful choice for
a default value.

> the fact that the behavior depends on the order of elements in `or` is
> an undesirable side effect of the implementation technique.

It also depends on the complexity of the branch.

It seems to me there are at least three consistent ways of behaving
(throw an error, bind name to nil, bind name to name), with an
inconsistent fourth way being what's currently implemented.

> > Things like the behavior of
> >
> > (pcase-let ((`(,a ,@b) (list 3 4)))
> >   a)
> >
> > just seem puzzling to me. There are good reasons not to implement
> > sublist matching (though I don't think those reasons are sufficient
> > not to have a simple implementation anyway),
>
> I don't know of a simple implementation.

Here's my better-than-nothing attempt. I don't think that's complex;
if anything, it's too trivial.

(pcase-defmacro append (&rest patterns)
  (if patterns
      (let* ((r1 (gensym))
         (r2 (gensym))
         (pat (list '\` (cons (list '\, (list 'and r1 (car patterns)))
                  (list '\, (list 'and r2 (cons 'append
                          (cdr patterns)))))))
         (f (eval `(lambda (l)
             (catch 'pcase--append
               (dotimes (i (1+ (length l)))
                 (let ((l1 (seq-subseq l 0 i))
                   (l2 (seq-subseq l i)))
                   (pcase (cons l1 l2)
                 (,pat (throw 'pcase--append
                          (cons ,r1 ,r2))))))))
              t)))
    `(app ,f ,pat))
    ''nil))



>
> > so an error message would be acceptable,
>
> You're probably right.
>
> > Sorry for complaining. Here's a patch.
>
> LGTM,
>
>
>         Stefan
>




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 29 Aug 2020 16:06:26 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Aug 29 12:06:26 2020
Received: from localhost ([127.0.0.1]:48930 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kC3N3-0003Qz-SQ
	for submit <at> debbugs.gnu.org; Sat, 29 Aug 2020 12:06:26 -0400
Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:1054)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <monnier@HIDDEN>) id 1kC3N1-0003Qm-GV
 for 43100 <at> debbugs.gnu.org; Sat, 29 Aug 2020 12:06:24 -0400
Received: from pmg2.iro.umontreal.ca (localhost.localdomain [127.0.0.1])
 by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id 902B5809C0;
 Sat, 29 Aug 2020 12:06:17 -0400 (EDT)
Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1])
 by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id D8C788073F;
 Sat, 29 Aug 2020 12:06:15 -0400 (EDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca;
 s=mail; t=1598717175;
 bh=xgMP1NHOZG3DzJnMJY76YQsY+HSFbm1Uo+jTnoJCN6Q=;
 h=From:To:Cc:Subject:References:Date:In-Reply-To:From;
 b=o0phF5oC+k14y8i9f3DN3fsXdZvfo3iDDvNO7jMaahPklFwtV16GNIFjs711gCoTf
 2j/y9ZP6W19xJ7kE2iPZDwakHlDZteyzKqMG2xcUgDwmT2NmUQgNAgJ8o2Fi7oIHfS
 7g2koxQoWz6agns+YDxA2kTvirr/dGod5qo8BVye/sIpMRSbc+ShUJaDp8PluMQJ3x
 cflbpnpQCfbA8yCpeNKcoVtTya0VWFQg9VNfh1qZClP7aC8B5LsvL3o17PPozpdSyF
 WCQhXIs9TOUAivEaGnS2/BLvSn5p72w8wAxNaLckoA6JkCqyTSxhCwJKo0BY+dsEL3
 B7K98U5nYt3Qw==
Received: from alfajor (unknown [45.72.232.131])
 by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 9EA1F120314;
 Sat, 29 Aug 2020 12:06:15 -0400 (EDT)
From: Stefan Monnier <monnier@HIDDEN>
To: Pip Cet <pipcet@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
Message-ID: <jwvpn791m8z.fsf-monnier+emacs@HIDDEN>
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
 <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
 <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
Date: Sat, 29 Aug 2020 12:06:15 -0400
In-Reply-To: <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
 (Pip Cet's message of "Sat, 29 Aug 2020 14:27:51 +0000")
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain
X-SPAM-INFO: Spam detection results:  0
 ALL_TRUSTED                -1 Passed through trusted hosts only via SMTP
 AWL -0.061 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DKIM_SIGNED               0.1 Message has a DKIM or DK signature,
 not necessarily valid
 DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature
 DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's
 domain
 KAM_SHORT               0.001 Use of a URL Shortener for very short URL
X-SPAM-LEVEL: 
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 43100
Cc: Philipp Stephani <p.stephani2@HIDDEN>, 43100 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

>> > I'm having trouble with pcase's behavior.
>> >
>> > (pcase "a"
>> >   ((or (pred symbolp) name)
>> >    (let ((foo 'bar)) name)))
>> >
>> > throws an error. It shouldn't.
>>
>> Isn't this case documented in the manual? The last section of
>> https://www.gnu.org/software/emacs/manual/html_node/elisp/pcase-Macro.html
>> states:
>> "It makes no sense for each sub-pattern [in an `or' sequence] to
>> let-bind a different set of symbols because the body forms have no way
>> to distinguish which sub-pattern matched and choose among the
>> different sets."
>
> Thanks for pointing this out.
>
> I disagree with what the documentation says there: it does make
> perfect sense, to me, to conditionally shadow a (lexical) let binding
> with a pcase-let one, and body forms will have no trouble in practice
> distinguishing between the outer and the inner let-binding.

How do you expect them to distinguish?

IIUC you want 

    (pcase V
      ((or (pred symbolp) name)
       (let ((foo 'bar)) name)))

to behave like

    (cond
     ((symbolp V) (let ((foo 'bar)) name))
     (t (let ((name V)) (let ((foo 'bar)) name))))

?

I'd rather not go there since it means that the single occurrence of the
`name` identifier in the branch's body refers to two different variable
bindings depending on which pattern was matched.  It smells of dynamic
scoping, tho it is admittedly compatible with lexical-scoping but only at
the cost of having to duplicate the branch's body.

The "intended" behavior instead would be to behave like

    (cond
     ((symbolp V) (let ((name nil)) (let ((foo 'bar)) name)))
     (t (let ((name V)) (let ((foo 'bar)) name))))

That's already the behavior you get if you switch the two:

    (macroexpand '(pcase V
                    ((or (and (pred foo) name) (pred symbolp))
                     (let ((foo 'bar)) name))))
    =>
    (let* ((pcase-0 (lambda (name) (let ((foo 'bar)) name))))
      (cond ((foo V) (funcall pcase-0 V))
            ((symbolp V) (funcall pcase-0 nil))
            (t nil)))

the fact that the behavior depends on the order of elements in `or` is
an undesirable side effect of the implementation technique.

> Things like the behavior of
>
> (pcase-let ((`(,a ,@b) (list 3 4)))
>   a)
>
> just seem puzzling to me. There are good reasons not to implement
> sublist matching (though I don't think those reasons are sufficient
> not to have a simple implementation anyway),

I don't know of a simple implementation.

> so an error message would be acceptable,

You're probably right.

> Sorry for complaining. Here's a patch.

LGTM,


        Stefan





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 29 Aug 2020 14:28:36 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Aug 29 10:28:36 2020
Received: from localhost ([127.0.0.1]:48830 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kC1qN-00012C-Lc
	for submit <at> debbugs.gnu.org; Sat, 29 Aug 2020 10:28:36 -0400
Received: from mail-oi1-f175.google.com ([209.85.167.175]:46197)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pipcet@HIDDEN>) id 1kC1qL-00011z-Sw
 for 43100 <at> debbugs.gnu.org; Sat, 29 Aug 2020 10:28:34 -0400
Received: by mail-oi1-f175.google.com with SMTP id v13so3247707oiv.13
 for <43100 <at> debbugs.gnu.org>; Sat, 29 Aug 2020 07:28:33 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=6u8FltFOkxdmCm/81vkgwSZ7zo0QrqGTmTZfDtrkVzc=;
 b=EaEzAWt6vXk5C8WNXSnOW8+6zCkgiA8ZVCaEBl0qRzEZshenpdiJnr5m6F6yTLZ6If
 6y52TeTXGJfCHZrjU0zy49IUNl7zPnwOjrxR8gF5Ejee04cYm0re+oH1GyLIxm+a1V93
 Wm+q/7D6z8Q2D4dES8UmV67VbwjXvrp9wmKOUZIy2K9WDohIi8dF4QdG1JrjDUmXzPZl
 cR90sygtHMqmW2V7SBjKk2DParhofKcbsxe5AQlkMB4+Au4EAWv/Ej9EBuGWquiuuKVr
 frQsK16JXJQyx5KNluUH4oWMo2unxkXC9umNTs/edsoZ9LnKUkr76bO4PBgqY+n/3Svv
 +qeA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=6u8FltFOkxdmCm/81vkgwSZ7zo0QrqGTmTZfDtrkVzc=;
 b=Z2i4Cvi197vcj9mznrlXpzMj70FbeBh3Yi6SQVjZbuGytLyrzhw6bVcXO+GJvMUMQj
 yqvUhggpVByNja9oI34O0VgmVrUk1l0BNZdcPOJxNBBF+jcwW6nMA1ZcfbvG1KZizGcf
 fqOZYaeczgxN3aF+Hjk5TEwD6jymwwNk2T8+p3oD6xm3JdPWkgGzJdsRs6F+aVNiYtU8
 kwZEkDEpfrtagXbZVxIdObhAaVBnPXIhgYaoLd5hA+mJtjf2siIE0KHFGWyMOpIVK0RB
 8/UBfbcNPNchOIwj1q7tnhFVzJvpuat+gUlzHl6k/hW51FUWUVcPbi4lNa2BFSL4BQJg
 uVEg==
X-Gm-Message-State: AOAM531uGhQrdbvtUNcd9a0ztTxsmYueHkfl0WykAE+obMR7VVfyi1+d
 KVVQthMJwJcd1RcLMh3PqaZoRVH7utRtd76Pcxk=
X-Google-Smtp-Source: ABdhPJw4wppa/HTFsU8ADOALrsLDgFhdCowER/WGfbJfX31TNpVOr2I3lotdlR5ZrwLsrJezSaZEReVdOjwqHvXHEFM=
X-Received: by 2002:aca:dc04:: with SMTP id t4mr2060951oig.30.1598711308071;
 Sat, 29 Aug 2020 07:28:28 -0700 (PDT)
MIME-Version: 1.0
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
 <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
In-Reply-To: <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
From: Pip Cet <pipcet@HIDDEN>
Date: Sat, 29 Aug 2020 14:27:51 +0000
Message-ID: <CAOqdjBdHzW4M+f_Jc5RONd25BJ6DKcYNo3jAYZB4kifDti_yRQ@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
To: Philipp Stephani <p.stephani2@HIDDEN>
Content-Type: multipart/mixed; boundary="0000000000009dd90c05ae04fb9c"
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 43100
Cc: 43100 <at> debbugs.gnu.org, Stefan Monnier <monnier@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--0000000000009dd90c05ae04fb9c
Content-Type: text/plain; charset="UTF-8"

 On Sat, Aug 29, 2020 at 12:01 PM Philipp Stephani
<p.stephani2@HIDDEN> wrote:
> Am Sa., 29. Aug. 2020 um 11:42 Uhr schrieb Pip Cet <pipcet@HIDDEN>:
> > I'm having trouble with pcase's behavior.
> >
> > (pcase "a"
> >   ((or (pred symbolp) name)
> >    (let ((foo 'bar)) name)))
> >
> > throws an error. It shouldn't.
>
> Isn't this case documented in the manual? The last section of
> https://www.gnu.org/software/emacs/manual/html_node/elisp/pcase-Macro.html
> states:
> "It makes no sense for each sub-pattern [in an `or' sequence] to
> let-bind a different set of symbols because the body forms have no way
> to distinguish which sub-pattern matched and choose among the
> different sets."

Thanks for pointing this out.

I disagree with what the documentation says there: it does make
perfect sense, to me, to conditionally shadow a (lexical) let binding
with a pcase-let one, and body forms will have no trouble in practice
distinguishing between the outer and the inner let-binding. The code
obviously attempts to handle this case, too, it just doesn't get it
perfectly right.

I agree and accept that pcase is very limited, and it probably always
will be, but I think those limitations shouldn't be entirely
arbitrary, and hitting them shouldn't cause silently malfunctioning
code but error messages.

Things like the behavior of

(pcase-let ((`(,a ,@b) (list 3 4)))
  a)

just seem puzzling to me. There are good reasons not to implement
sublist matching (though I don't think those reasons are sufficient
not to have a simple implementation anyway), so an error message would
be acceptable, but the current implementation treats \,@ as an
ordinary symbol, which doesn't help anyone.

Sorry for complaining. Here's a patch.

--0000000000009dd90c05ae04fb9c
Content-Type: text/x-patch; charset="US-ASCII"; 
	name="0001-Complain-about-in-backquote-pcase-patterns.patch"
Content-Disposition: attachment; 
	filename="0001-Complain-about-in-backquote-pcase-patterns.patch"
Content-Transfer-Encoding: base64
Content-ID: <f_kefr9tay0>
X-Attachment-Id: f_kefr9tay0

RnJvbSBjNTI3MDhkOTJkZWM0YTZkNzgxMGQ2MzRkZDRmZjIzYTJjYmNhMWVjIE1vbiBTZXAgMTcg
MDA6MDA6MDAgMjAwMQpGcm9tOiBQaXAgQ2V0IDxwaXBjZXRAZ21haWwuY29tPgpEYXRlOiBTYXQs
IDI5IEF1ZyAyMDIwIDE0OjIxOjI5ICswMDAwClN1YmplY3Q6IFtQQVRDSF0gQ29tcGxhaW4gYWJv
dXQgLEAgaW4gYmFja3F1b3RlIHBjYXNlIHBhdHRlcm5zCgoqIGxpc3AvZW1hY3MtbGlzcC9wY2Fz
ZS5lbCAoXGApOiBDb21wbGFpbiB1cG9uIGVuY291bnRlcmluZyBcLEAgaW4KYmFja3F1b3RlIHBj
YXNlIHBhdHRlcm5zLgotLS0KIGxpc3AvZW1hY3MtbGlzcC9wY2FzZS5lbCB8IDEgKwogMSBmaWxl
IGNoYW5nZWQsIDEgaW5zZXJ0aW9uKCspCgpkaWZmIC0tZ2l0IGEvbGlzcC9lbWFjcy1saXNwL3Bj
YXNlLmVsIGIvbGlzcC9lbWFjcy1saXNwL3BjYXNlLmVsCmluZGV4IGE4Y2UyMzI4NGMuLjY0MmZm
MGY3M2EgMTAwNjQ0Ci0tLSBhL2xpc3AvZW1hY3MtbGlzcC9wY2FzZS5lbAorKysgYi9saXNwL2Vt
YWNzLWxpc3AvcGNhc2UuZWwKQEAgLTk3MSw2ICs5NzEsNyBAQCBcYAogICAoZGVjbGFyZSAoZGVi
dWcgKHBjYXNlLVFQQVQpKSkKICAgKGNvbmQKICAgICgoZXEgKGNhci1zYWZlIHFwYXQpICdcLCkg
KGNhZHIgcXBhdCkpCisgICAoKGVxIChjYXItc2FmZSBxcGF0KSAnXCxAKSAoZXJyb3IgInN1Ymxp
c3QgbWF0Y2hpbmcgbm90IHN1cHBvcnRlZCIpKQogICAgKCh2ZWN0b3JwIHFwYXQpCiAgICAgYChh
bmQgKHByZWQgdmVjdG9ycCkKICAgICAgICAgICAoYXBwIGxlbmd0aCAsKGxlbmd0aCBxcGF0KSkK
LS0gCjIuMjguMAoK
--0000000000009dd90c05ae04fb9c--




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at 43100 <at> debbugs.gnu.org:


Received: (at 43100) by debbugs.gnu.org; 29 Aug 2020 12:02:04 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Aug 29 08:02:04 2020
Received: from localhost ([127.0.0.1]:47994 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kBzYa-0003PQ-83
	for submit <at> debbugs.gnu.org; Sat, 29 Aug 2020 08:02:04 -0400
Received: from mail-ot1-f53.google.com ([209.85.210.53]:33860)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <p.stephani2@HIDDEN>) id 1kBzYY-0003Ov-2K
 for 43100 <at> debbugs.gnu.org; Sat, 29 Aug 2020 08:02:03 -0400
Received: by mail-ot1-f53.google.com with SMTP id k20so1549435otr.1
 for <43100 <at> debbugs.gnu.org>; Sat, 29 Aug 2020 05:02:01 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=nvsEnZ076OwdPyi/GUAK85QsSX+9bAobn4d23nIRRzE=;
 b=lpdeCS0C+zBXu3kACPTwHRVlqnRNhVG/zgOymnn+V5nWZcTJXK6XPADFNuegRb2ON0
 38HFMJr2WUFk47OWbLrey0PNX8uOmOTFZ9+6n+zSjhqQ/BHFq0ec/AydZlzek+Q0ZliD
 qetV15zb/MHxOA7vzQqNvZLPf4M9tH6wRsKQrrQa6Iz3oVYk3jK7czSw89vgK/gD6UoA
 +8eaKsYGsh6E16ohvT4sEbd8KnZIWhCjZgmYgPb1RtD7NVUCeETJUlVKJGuQrn/xuoQw
 UPZqXtDkXFA0+fywUMPo3LpL4yMdWXQ4Prhtp6snsc2pit5g9r0oifwMPmfauxVvmUZE
 4ABw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=nvsEnZ076OwdPyi/GUAK85QsSX+9bAobn4d23nIRRzE=;
 b=oEvN/3VKADuA1bc9IxjQ3hXOE972Vysta4KwPfC7ltHs3p+ZZxouo/+1mOywDBpbtU
 dQ6flfVDGp8tZPOcx1Dz51zpjbtSND+JPIb6Gz7puusW1aogKED+AwzEvQAd7bjYNUKY
 q9ChgrnyU+vp1g9a2HYyfWKiwg9zLmMIgiqr10ajkyP2FBljPi+GKCoGXMk3F7NF+nUc
 LceUrnyCbz6aW4ll7ecMX4ZTPAgQMn5OZd04xc7urrdRLucQK6DU94h+pJUKb3MlJVeU
 e9VcVMtvrvawz9iBgWOmvyzBvjwp53XTO/9QsPUt2d/dymp4DiBnO4Ov1j9PjmToU59M
 pJFw==
X-Gm-Message-State: AOAM533/TL7Iy78IivqxRtaqsn5WdXf3h32cr68Dk0UNG4SZUmzz3lxY
 y+UveHlQymaUVGbQx/HoUMQqfFIw/6Lsc2u0dTo=
X-Google-Smtp-Source: ABdhPJxRZyUXlLXgLtAuQl85lf/FHEHC4O+wfJuUZjGzznyry5y6QjNeOEuwBVh3X2U+6MXciwUaewTXJax24enaz1I=
X-Received: by 2002:a9d:20c1:: with SMTP id x59mr1959996ota.36.1598702516120; 
 Sat, 29 Aug 2020 05:01:56 -0700 (PDT)
MIME-Version: 1.0
References: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
In-Reply-To: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
From: Philipp Stephani <p.stephani2@HIDDEN>
Date: Sat, 29 Aug 2020 14:01:45 +0200
Message-ID: <CAArVCkTPrDJoPXw+s5qzHqwygSut25E-eKXp+vDzp0-E+6n1PA@HIDDEN>
Subject: Re: bug#43100: 28.0.50; pcase not binding variables conditionally
To: Pip Cet <pipcet@HIDDEN>
Content-Type: text/plain; charset="UTF-8"
X-Spam-Score: 0.3 (/)
X-Debbugs-Envelope-To: 43100
Cc: 43100 <at> debbugs.gnu.org, Stefan Monnier <monnier@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.7 (/)

Am Sa., 29. Aug. 2020 um 11:42 Uhr schrieb Pip Cet <pipcet@HIDDEN>:
>
> I'm having trouble with pcase's behavior.
>
> (pcase "a"
>   ((or (pred symbolp) name)
>    (let ((foo 'bar)) name)))
>
> throws an error. It shouldn't.

Isn't this case documented in the manual? The last section of
https://www.gnu.org/software/emacs/manual/html_node/elisp/pcase-Macro.html
states:
"It makes no sense for each sub-pattern [in an `or' sequence] to
let-bind a different set of symbols because the body forms have no way
to distinguish which sub-pattern matched and choose among the
different sets."




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 29 Aug 2020 09:41:53 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat Aug 29 05:41:53 2020
Received: from localhost ([127.0.0.1]:47932 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1kBxMv-0003yG-BL
	for submit <at> debbugs.gnu.org; Sat, 29 Aug 2020 05:41:53 -0400
Received: from lists.gnu.org ([209.51.188.17]:39578)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <pipcet@HIDDEN>) id 1kBxMt-0003y9-S4
 for submit <at> debbugs.gnu.org; Sat, 29 Aug 2020 05:41:52 -0400
Received: from eggs.gnu.org ([2001:470:142:3::10]:46482)
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <pipcet@HIDDEN>) id 1kBxMt-0000ho-LF
 for bug-gnu-emacs@HIDDEN; Sat, 29 Aug 2020 05:41:51 -0400
Received: from mail-oi1-x22a.google.com ([2607:f8b0:4864:20::22a]:42839)
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <pipcet@HIDDEN>) id 1kBxMr-0001eh-8p
 for bug-gnu-emacs@HIDDEN; Sat, 29 Aug 2020 05:41:51 -0400
Received: by mail-oi1-x22a.google.com with SMTP id j7so2879872oij.9
 for <bug-gnu-emacs@HIDDEN>; Sat, 29 Aug 2020 02:41:48 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=mime-version:from:date:message-id:subject:to;
 bh=dK6piiH0w4fTvG90pSaLuk8/aojNP95rKv6u5SUG8pQ=;
 b=h9nm7P9RJTRJvKR+YXuX7A6nF8r66tksz290rhz+G7Vh7eWD4EMGHrg63bGgj7fHNC
 gfKruMHvtp8lXnl+KZHRdF+c4neKd1i/qtdh54yE5nWGdZUkcH6t1jnp7SVQqRM5c0iq
 5VscWn1LxhI8dymJv3La02bCdYWN79iQJwJgrMNqfueOsxe0lQH/ANHCAHJtMcDqd0ij
 +dOQzpPxvUSbfJC9OpcqiSjDKL6KuvP9LAETL2PdVK+92lOSTfEwrpnpmFB1amblglGz
 m2i+PqjCHFb3QUyZyt84ec8dwpQ9QvMzVIH0jwIUs7FSTfmIhfeqAJ5AjZZsMeQYUCpc
 KCtQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:mime-version:from:date:message-id:subject:to;
 bh=dK6piiH0w4fTvG90pSaLuk8/aojNP95rKv6u5SUG8pQ=;
 b=ESj9eT4m3VXxTxFPcOTuzinvh8LJFdHf0capuig9aU42HmPjrAohPEuiVAGDXPU93o
 dDSuoZbhZP5+GqgY67mlnSS2mbBRQu/ZSvJFfDCmfc3rxAXcdPufxtROOxPz921IOoQX
 +0iFVEi/wPg82QZbF5kXpRTiC+z92fYN4l5bzyyugI1CX++elHus6sGFN8CmXHp+3tmM
 k5HkElHFhNhcvh9rUWdaBFyk820v1PM00GAhW+Ns5e0BMoREN5EnuKWNUoUNmEpbaSW9
 UxSywtUxhQkr9lpA0VbtdoaXHD0BFBWbba8ncM0rSd8PeAkAF/pHrUcsRAQCL9G8Hvta
 NEqg==
X-Gm-Message-State: AOAM533PqHG1/+LTvkAG6NF6Pybd4sMs9WG7Dygx318WmxK2GAGEXahf
 gL0ZHWtMEaVdn+rGj691xO7aBvy5ILC00jw4xAGgwKVYZZcPbg==
X-Google-Smtp-Source: ABdhPJwLDjLfsV1ZGJLiV9atK38xh1xs2AlwoBX/u53KaO3L5hHWchsw/8NKoxvkCr/Kneb+BM7/tcO4EEr0++RTX8s=
X-Received: by 2002:aca:dc04:: with SMTP id t4mr1612979oig.30.1598694107350;
 Sat, 29 Aug 2020 02:41:47 -0700 (PDT)
MIME-Version: 1.0
From: Pip Cet <pipcet@HIDDEN>
Date: Sat, 29 Aug 2020 09:41:10 +0000
Message-ID: <CAOqdjBde5Xkfx9076tNPrhhcpXjo+h-DWawZeeOLwj6U3JTbPQ@HIDDEN>
Subject: 28.0.50; pcase not binding variables conditionally
To: bug-gnu-emacs@HIDDEN, Stefan Monnier <monnier@HIDDEN>
Content-Type: multipart/mixed; boundary="0000000000005fa99805ae00fa25"
Received-SPF: pass client-ip=2607:f8b0:4864:20::22a;
 envelope-from=pipcet@HIDDEN; helo=mail-oi1-x22a.google.com
X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache.
 That's all we know.
X-Spam_score_int: -20
X-Spam_score: -2.1
X-Spam_bar: --
X-Spam_report: (-2.1 / 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_NONE=-0.0001, SPF_HELO_NONE=0.001,
 SPF_PASS=-0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-Spam-Score: -0.1 (/)
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -2.3 (--)

--0000000000005fa99805ae00fa25
Content-Type: text/plain; charset="UTF-8"

I'm having trouble with pcase's behavior.

(pcase "a"
  ((or (pred symbolp) name)
   (let ((foo 'bar)) name)))

throws an error. It shouldn't. (Note that the dummy "let" is necessary
to force the pcase code generation to use a function call).

I believe the culprit is the code around this comment in pcase.el

;; If some of `vars' were not found in `prevvars', that's
;; OK it just means those vars aren't present in all
;; branches, so they can be used within the pattern
;; (e.g. by a `guard/let/pred') but not in the branch.

I believe that's incorrect: using the variable in a condition-case
should work, as should conditional shadowing of an existing binding,
as in this case:

(let ((name "default"))
  (pcase "a"
    ((or (pred symbolp) name)
     name)))

(which works), or this case:

(let ((name "default"))
  (pcase "a"
    ((or (pred symbolp) name)
     (let ((foo 'bar)) name))))

(which doesn't).

I believe the right fix is not to share code for the same branch if it
uses different variables, as in the attached patch. It's possible this
increases codegen complexity in some construed cases, but in practice
that shouldn't be a problem.

--0000000000005fa99805ae00fa25
Content-Type: text/x-patch; charset="US-ASCII"; 
	name="0001-Allow-variable-bindings-to-differ-across-pcase-alter.patch"
Content-Disposition: attachment; 
	filename="0001-Allow-variable-bindings-to-differ-across-pcase-alter.patch"
Content-Transfer-Encoding: base64
Content-ID: <f_kefh413x0>
X-Attachment-Id: f_kefh413x0

RnJvbSBlYzdlNGE5MmFiMDhhZGY0ZWIwMzZlYTUwZjdkNzBiYWRlNjM3MTliIE1vbiBTZXAgMTcg
MDA6MDA6MDAgMjAwMQpGcm9tOiBQaXAgQ2V0IDxwaXBjZXRAZ21haWwuY29tPgpEYXRlOiBTYXQs
IDI5IEF1ZyAyMDIwIDA5OjM1OjQxICswMDAwClN1YmplY3Q6IFtQQVRDSF0gQWxsb3cgdmFyaWFi
bGUgYmluZGluZ3MgdG8gZGlmZmVyIGFjcm9zcyBwY2FzZSBhbHRlcm5hdGl2ZXMuCgpUaGlzIGZp
eGVzIHBjYXNlIGNhc2VzIGxpa2UgKChvciAocHJlZCBzdHJpbmdwKSBuYW1lKSBuYW1lKSwgd2hp
Y2gKc2hvdWxkIHVzZSB0aGUgcGNhc2UtbG9jYWwgYmluZGluZyBvbmx5IGlmIEVYUFZBTCBpc24n
dCBhIHN0cmluZy4KCiogbGlzcC9lbWFjcy1saXNwL3BjYXNlLmVsIChwY2FzZS0tZXhwYW5kKTog
RG8gbm90IHNoYXJlIGNvZGUgaWYKdmFyaWFibGVzIGRpZmZlci4KLS0tCiBsaXNwL2VtYWNzLWxp
c3AvcGNhc2UuZWwgfCAzICsrLQogMSBmaWxlIGNoYW5nZWQsIDIgaW5zZXJ0aW9ucygrKSwgMSBk
ZWxldGlvbigtKQoKZGlmZiAtLWdpdCBhL2xpc3AvZW1hY3MtbGlzcC9wY2FzZS5lbCBiL2xpc3Av
ZW1hY3MtbGlzcC9wY2FzZS5lbAppbmRleCBhOGNlMjMyODRjLi43MjkxNjI5NmNiIDEwMDY0NAot
LS0gYS9saXNwL2VtYWNzLWxpc3AvcGNhc2UuZWwKKysrIGIvbGlzcC9lbWFjcy1saXNwL3BjYXNl
LmVsCkBAIC0zNDYsNyArMzQ2LDggQEAgcGNhc2UtLWV4cGFuZAogICAgICAgICAgICAgKGxhbWJk
YSAoY29kZSB2YXJzKQogICAgICAgICAgICAgICAobGV0ICgodmFycyAocGNhc2UtLWZncmVwIHZh
cnMgY29kZSkpCiAgICAgICAgICAgICAgICAgICAgIChwcmV2IChhc3NxIGNvZGUgc2VlbikpKQot
ICAgICAgICAgICAgICAgIChpZiAobm90IHByZXYpCisgICAgICAgICAgICAgICAgKGlmIChvciAo
bm90IHByZXYpCisgICAgICAgICAgICAgICAgICAgICAgICAobm90IChlcXVhbCAoY2FkciBwcmV2
KSB2YXJzKSkpCiAgICAgICAgICAgICAgICAgICAgIChsZXQgKChyZXMgKHBjYXNlLWNvZGVnZW4g
Y29kZSB2YXJzKSkpCiAgICAgICAgICAgICAgICAgICAgICAgKHB1c2ggKGxpc3QgY29kZSB2YXJz
IHJlcykgc2VlbikKICAgICAgICAgICAgICAgICAgICAgICByZXMpCi0tIAoyLjI4LjAKCg==
--0000000000005fa99805ae00fa25--




Acknowledgement sent to Pip Cet <pipcet@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to bug-gnu-emacs@HIDDEN:
bug#43100; Package emacs. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Sat, 5 Sep 2020 14:45:01 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.