From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Tomas Hlavaty Newsgroups: gmane.emacs.devel Subject: Re: What's missing in ELisp that makes people want to use cl-lib? Date: Tue, 14 Nov 2023 18:40:01 +0100 Message-ID: <871qcskzda.fsf@neko.mail-host-address-is-not-set> References: <87il6bt4z0.fsf@yahoo.com> <8734xetjkk.fsf@yahoo.com> <87cywhsrcf.fsf@yahoo.com> <87cywgx1z0.fsf@web.de> <83wmuowwp3.fsf@gnu.org> <83leb3v5al.fsf@gnu.org> <87a5rgrbvv.fsf@neko.mail-host-address-is-not-set> <87edgsmwni.fsf@yahoo.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="38023"; mail-complaints-to="usenet@ciao.gmane.io" Cc: rms@gnu.org, Eli Zaretskii , emacs-devel@gnu.org To: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= , Po Lu Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue Nov 14 18:41:06 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 1r2xPN-0009n8-JB for ged-emacs-devel@m.gmane-mx.org; Tue, 14 Nov 2023 18:41:05 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r2xOb-0001s4-KU; Tue, 14 Nov 2023 12:40:17 -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 1r2xOS-0001pl-QK for emacs-devel@gnu.org; Tue, 14 Nov 2023 12:40:13 -0500 Original-Received: from logand.com ([37.48.87.44]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r2xOQ-0004mC-B7; Tue, 14 Nov 2023 12:40:08 -0500 Original-Received: by logand.com (Postfix, from userid 1001) id 2021B19E7F0; Tue, 14 Nov 2023 18:40:04 +0100 (CET) X-Mailer: emacs 28.2 (via feedmail 11-beta-1 I) In-Reply-To: Received-SPF: pass client-ip=37.48.87.44; envelope-from=tom@logand.com; helo=logand.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-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:312739 Archived-At: On Tue 14 Nov 2023 at 11:47, Jo=C3=A3o T=C3=A1vora w= rote: > On Tue, Nov 14, 2023 at 10:55=E2=80=AFAM Po Lu wrote: > LOOP, pcase, etc, like any other macros, are mini-languages. Like > any higher-level language, the more powerful they are, the more > transformations they will do on your input. LOOP is pretty powerful, > and may or may not be suitable for the task at hand, like any other > language. The question is if those are "nice" mini-languages or expressing the code in simple emacs-lisp is nicer. > At any rate Tomas' translation of the loop is just plain > wrong. Where is 'type-spec' being bound? It needs to be > destructured: Thanks, you found a bug in the sketch. It should have been: (puthash (pop f) (comp-type-spec-to-cstr (pop f)) h) or maybe (puthash (car f) (comp-type-spec-to-cstr (cadr f)) h) > LOOP is a language which is very good > at expressing this fact concisely in a self-documenting way: > > for (f type-spec) in comp-known-type-specifiers or (dolist (x comp-known-type-specifiers) (destructuring-bind (f type-spec) x ...)) if emacs-lisp had destructuring-bind. Note that in this particular example, the variables are not needed at all. Also note that comp-known-type-specifiers contains unnecessary cons cell for each element. > Here from this one line, without ever having looked at Andrea's > code I learn that comp-known-type-specifiers is a list of > 2-element lists, where each such tuple is at least made of > an 'f' and a 'type-spec'. Even better feature of destructuring-bind is: when comp-known-type-specifiers changes structure, destructuring-bind will fail laudly. If cl-loop supported keywords, it could be even more strict: (destructuring-bind (&key f type-spec) comp-known-type-specifiers ...) Or maybe comp-known-type-specifiers should be a structure? How strict do we want to be? > Here, I think dolist + pcase-let/cl-destructuring-case/seq-let > would also be appropriate. Though I'm sure someone out there > would find it insufferably ugly or anti-Elisp as well. I think dolist would be the right choice. > > (cl-loop > > with comp-ctxt =3D (make-comp-cstr-ctxt) > > with h =3D (make-hash-table :test #'eq) > > for (f type-spec) in comp-known-type-specifiers > > for cstr =3D (comp-type-spec-to-cstr type-spec) > > do (puthash f cstr h) > > finally return h) That would be something along the lines of: (let ((h (make-hash-table :test #'eq))) (dolist (f comp-known-type-specifiers h) (puthash (pop f) (comp-type-spec-to-cstr (pop f)) h))) which seems the most concise translation of the cl-loop code above or (let ((h (make-hash-table :test #'eq))) (dolist (f comp-known-type-specifiers h) (puthash (car f) (comp-type-spec-to-cstr (cadr f)) h))) > Anyway Tomas' example, if it were to be corrected, would become > "ugly" perhaps "uglier" (as if "ugly" were even an objective > thing) So I removed the unused variable comp-ctxt, pulled the hash-table out of cl-loop, and puthash stuff for each element of comp-known-type-specifiers. The only ugly thing remaining is destructuring the elements of comp-known-type-specifiers which plain emacs-lisp does not have a good way of expressing: (let ((h (make-hash-table :test #'eq))) (dolist (x comp-known-type-specifiers h) (destructuring-bind (f type-spec) x (puthash f (comp-type-spec-to-cstr type-spec) h)))) or (if emacs-lisp had &key) (let ((h (make-hash-table :test #'eq))) (dolist (x comp-known-type-specifiers h) (destructuring-bind (&key f type-spec) x (puthash f (comp-type-spec-to-cstr type-spec) h)))) or in plain emacs-lisp: (let ((h (make-hash-table :test #'eq))) (dolist (x comp-known-type-specifiers h) (apply (lambda (f type-spec) (puthash f (comp-type-spec-to-cstr type-spec) h)) x))) or (defun mapcly (fn seq) (mapc (lambda (x) (apply fn x)) seq)) (let ((h (make-hash-table :test #'eq))) (mapcly (lambda (f type-spec) (puthash f (comp-type-spec-to-cstr type-spec) h)) comp-known-type-specifiers) h)