From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Lynn Winebarger Newsgroups: gmane.emacs.devel Subject: Re: Instead of pcase Date: Sat, 2 Dec 2023 16:37:51 -0500 Message-ID: References: <87fs169mjj.fsf@posteo.net> <093f11a1-57c2-5e56-d39b-26fef1c67cbb@gutov.dev> <25942.25061.217864.329049@retriever.mtv.corp.google.com> <87zfzdcz6z.fsf@posteo.net> <87zfza2aq2.fsf@web.de> <7nmsv9zq6u.fsf@ecube.ecubist.org> <7nv89x5tsi.fsf@ecube.ecubist.org> <87o7focuf5.fsf@web.de> <875y1r10jr.fsf@web.de> <87y1eiz8pd.fsf@yggdrasil.mail-host-address-is-not-set> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="00000000000025795d060b8db3f7" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="9693"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Richard Stallman , michael_heerdegen@web.de, emacs-devel To: Nikita Domnitskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Dec 02 22:38:51 2023 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1r9XhK-0002KN-V2 for ged-emacs-devel@m.gmane-mx.org; Sat, 02 Dec 2023 22:38:51 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r9Xgj-0006CF-AV; Sat, 02 Dec 2023 16:38:13 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r9Xgh-0006C5-Q1 for emacs-devel@gnu.org; Sat, 02 Dec 2023 16:38:11 -0500 Original-Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1r9Xgf-0008Ja-LM; Sat, 02 Dec 2023 16:38:11 -0500 Original-Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-28613d87c4cso3092493a91.3; Sat, 02 Dec 2023 13:38:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701553084; x=1702157884; darn=gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=EaJ+Yt5BY3LWZqQDiJnXM7gXEguJT3HMoOInoYvT/oQ=; b=TnNmfnGljrn5oqLXdU8HOOLf7mdX+9PORDx/8Lz78gqQ/9bibMe5xBSbrpguzdBZpN ITkNy041b3v9v6yQcUEnfcb9m7W4fdPwVnyRAXwg9uATQlVE3AZVGlgFttBJZoEzMCbo zjwyRPCog14UxRQ21Ieibsbk31KlVXSDnJAlLKwI6F4/YYsDB1R5Nu0MbzYM27pT4T+T zXZWQte0waz/+ETIhsyXQJOJUDFfq+2yBMgAEVusxGFgegYAgwyPWrreEEz4EYYvQ3Dn iROLXOnkOY+Fo7OdkdH/5X+0yR8J2+gPseGX28yiFSco9feebpkaZEjT6L7gkYLdAvJk 0rWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701553084; x=1702157884; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=EaJ+Yt5BY3LWZqQDiJnXM7gXEguJT3HMoOInoYvT/oQ=; b=dZc4ijqIk3Vh1Icnc4xJxtDHjJugmjIxqXg0/UjsQwn7WR2K8UkanhLTrM8JQTivnm tu7OoXZDSzXE/iZhfcuj6fSbRIZJV9bFcZMEzR/VV0UbBmqVWykMqoonrm31a8HMLJ8n N5arWUzxWQIZmq9ZY5XzCOAsBaEGtu4Oroa1qh9TOHYYVmkrQsLDGTzXW7NrqmfImPJf AK1ppiwlv5FBVomgVz4SM9p2ZG2C4/0/oZMMc4F25zO78TdbP1zvMLtMFzEI+uf9kIbS Kpz8dVrhYL36kBBbJsS23vG2x5wGyDbcwDxg4J9NsSF4FPV+yi0F3/2Wj7Va+Sg+ZuDm Hq/A== X-Gm-Message-State: AOJu0Yw8OF7NB1ziuaVaMLFPgboZq7y50J7spj7VpmqinXI2Ga7Tkyf2 uOs/RmPjAE/XDhM7OBYlZQ5Pnh/jiwn/h3rzft0= X-Google-Smtp-Source: AGHT+IFVy/XZq1aog6pN8WGzezTGi6PDP1GvjqlFR0qeXnctq7PCR/bkncdguL6l2PJXG4EbhHhMIbL+m7xxwXdGXvM= X-Received: by 2002:a17:90b:3504:b0:286:7ec4:81fb with SMTP id ls4-20020a17090b350400b002867ec481fbmr669985pjb.16.1701553084134; Sat, 02 Dec 2023 13:38:04 -0800 (PST) In-Reply-To: <87y1eiz8pd.fsf@yggdrasil.mail-host-address-is-not-set> Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=owinebar@gmail.com; helo=mail-pj1-x1035.google.com 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, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:313476 Archived-At: --00000000000025795d060b8db3f7 Content-Type: text/plain; charset="UTF-8" On Tue, Nov 28, 2023, 8:54 AM Nikita Domnitskii wrote: > Richard Stallman writes: > > > (cond* (:bind b1 (b (save-window-excursion (find-file-at-point > filename)))) > > ((bufferp b) (setq b1 b)) > > ((bufferp (car-safe b)) (setq b1 (car-safe b)))) > > (if b1 (switch-to-buffer-other-window b))) > > > > (cond* (:bind b1 (b (save-window-excursion (find-file-at-point > filename)))) > > ((bufferp b) (switch-to-buffer-other-window b)) > > ((bufferp (car-safe b)) (switch-to-buffer-other-window > (car-safe b))))) > > > > (let ((b (save-window-excursion (find-file-at-point filename))) b1) > > (if (or (match-set b1 b (bufferp b1)) > > (match-set b1 (car-safe b) (bufferp b1))) > > (switch-to-buffer-other-window b1))) > > To be honest all variants look less expressive than original > pcase. > > Maybe instead of trying to implement cond* we should look into impoving > pcase patterns? As a starting point I suggest Racket pattern matching > implementation (which in my opinion is fairly readable): > https://docs.racket-lang.org/reference/match.html A similar match package is available in guile: https://www.gnu.org/software/guile/manual/html_node/Pattern-Matching.html Indeed, I first saw "match" in a course on compiler theory around 2000. When I saw pcase I thought the author had based it on "match", but according to https://dl.acm.org/doi/pdf/10.1145/3386324 (Evolution of Emacs Lisp, p 37), that resemblance was, at least initially, accidental. As some others here have expressed, I find the use of "constructor syntax" for both construction (in a value position) and destructuring (in a binding position) aesthetically appealing. On the other hand, since pcase is in some ways an inverse operator to quasiquotation, I feel like the pattern clauses should be implicitly backquoted. Or, one might say, backquote introduces a value context for constructor syntax, but is not itself part of that constructor syntax, while unquote (comma) and unquote-splice (comma-at) operators are constructor syntax. Then pcase can be seen as introducing a binding context (i.e. similar to the"cond-let" form being discussed elsewhere). Read syntax could also be introduced to formalize the duality of the operators, say "`?". The documentation of the "bare" patterns (un-backquoted) is probably the most confusing part of the doc, especially with the "Caveats for symbol in pattern" section, but that's how pcase is introduced(!). That's where the confusing DSL is to me, since operators like "and" and "or" are redefined but act on patterns rather than values, but there's no visual prompt that this redefinition is in effect. A similar complaint might be levelled at ",(and ...)". If backquote and pcase were understood to introduce evaluation and binding contexts respectively for constructor syntax, then maybe the change in meaning would be more apparent? There are also macro expanders written explicitly for syntax pattern matching in Scheme. Those might be adapted if the core developers would prefer separate facilities for pattern matching used for compiling than "low-level" facilities made available everywhere. In a system like "syntax-case" the bindings made by the matcher are only available in the "syntax" constructor form, rather than bound as ordinary lexically-scoped variables. Lynn --00000000000025795d060b8db3f7 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Tue, Nov 28, 2023, 8:54 AM Nikita Domnitskii <nikita@domnitskii.me> wrote:
=
Richard Stallman <rms@gnu.org> writes:
>=C2=A0 =C2=A0(cond* (:bind b1 (b (save-window-excursion (find-file-at-p= oint filename))))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((bufferp b) (setq b1 b))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((bufferp (car-safe b)) (setq b1 (ca= r-safe b))))
>=C2=A0 =C2=A0(if b1 (switch-to-buffer-other-window b)))
>
>=C2=A0 =C2=A0(cond* (:bind b1 (b (save-window-excursion (find-file-at-p= oint filename))))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((bufferp b) (switch-to-buffer-other= -window b))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((bufferp (car-safe b)) (switch-to-b= uffer-other-window (car-safe b)))))
>
>=C2=A0 =C2=A0(let ((b (save-window-excursion (find-file-at-point filena= me))) b1)
>=C2=A0 =C2=A0 =C2=A0(if (or (match-set b1 b (bufferp b1))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(match-set b1 (car-safe= b) (bufferp b1)))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(switch-to-buffer-other-window b1)))<= br>
To be honest all variants look less expressive than original
pcase.

Maybe instead of trying to implement cond* we should look into impoving
pcase patterns? As a starting point I suggest Racket pattern matching
implementation (which in my opinion is fairly readable):
https://docs.racket-lang.org/reference/m= atch.html

A similar match package is available in guile:=C2=A0

Indeed, I first saw "match" in a course on compiler theory aroun= d 2000.=C2=A0 When I saw pcase I thought the author had based it on "m= atch", but according to=C2=A0 https://dl.acm.org/doi/pdf/10.1145/3386324 (Evolution of= Emacs Lisp, p 37), that resemblance was, at least initially, accidental.

As some others here have = expressed, I find the use of "constructor syntax" for both constr= uction (in a value position) and destructuring (in a binding position) aest= hetically appealing.=C2=A0 On the other hand, since pcase is in some ways a= n inverse operator to quasiquotation, I feel like the pattern clauses shoul= d be implicitly backquoted.=C2=A0 Or, one might say, backquote introduces a= value context for constructor syntax, but is not itself part of that const= ructor syntax, while unquote (comma) and unquote-splice (comma-at) operator= s are constructor syntax.=C2=A0 Then pcase can be seen as introducing a bin= ding context (i.e. similar to the"cond-let" form being discussed = elsewhere).=C2=A0 Read syntax could also be introduced to formalize the dua= lity of the operators, say "`?".=C2=A0=C2=A0

The documentation of the "bare" pa= tterns (un-backquoted) is probably the most confusing part of the doc, espe= cially with the "Caveats for symbol in pattern" section, but that= 's how pcase is introduced(!).=C2=A0 That's where the confusing DSL= is to me, since operators like "and" and "or" are rede= fined but act on patterns rather than values, but there's no visual pro= mpt that this redefinition is in effect. A similar complaint might be level= led at ",(and ...)".=C2=A0 If backquote and pcase were understood= to introduce evaluation and binding contexts respectively for constructor = syntax, then maybe the change in meaning would be more apparent?

There are also macro expanders wri= tten explicitly for syntax pattern matching in Scheme.=C2=A0 Those might be= adapted if the core developers would prefer separate facilities for patter= n matching used for compiling than "low-level" facilities made av= ailable everywhere.=C2=A0 In a system like "syntax-case" the bind= ings made by the matcher are only available in the "syntax" const= ructor form, rather than bound as ordinary lexically-scoped variables.


= Lynn


--00000000000025795d060b8db3f7--