From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: akater Newsgroups: gmane.emacs.devel Subject: Re: [PATCH] Add cl-map-into, revision 3 Date: Tue, 26 Oct 2021 12:52:33 +0000 Message-ID: <87bl3cdk32.fsf@gmail.com> References: <87h7eag90n.fsf@gmail.com> <87wnmprajk.fsf@gmail.com> <83o8811ex5.fsf@gnu.org> <87a6jidifa.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="39549"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Eli Zaretskii , emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue Oct 26 15:06:44 2021 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 1mfMA8-000A54-DG for ged-emacs-devel@m.gmane-mx.org; Tue, 26 Oct 2021 15:06:44 +0200 Original-Received: from localhost ([::1]:44210 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mfMA7-00073i-2P for ged-emacs-devel@m.gmane-mx.org; Tue, 26 Oct 2021 09:06:43 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:58776) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mfM7r-0005VA-TV for emacs-devel@gnu.org; Tue, 26 Oct 2021 09:04:25 -0400 Original-Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]:44619) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mfM7m-0007me-Bp; Tue, 26 Oct 2021 09:04:23 -0400 Original-Received: by mail-wr1-x42a.google.com with SMTP id d13so16619719wrf.11; Tue, 26 Oct 2021 06:04:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:in-reply-to:references:date:message-id :mime-version; bh=vBiOMufj42ge0pGXvJGUIq/yQqNqds7kGBMnlIG45hE=; b=KMz/8bUSfO6hjlytSb19/I27zqdhT+SUhMm8vtkOTCu0T8siDNO3qAx7NtCfWkJ3kO ZekQgahKZ6TEtbMwtiJQSNo55H5n/0y5WabSdaraUA/5P8UTRJpLmtPukq/t45AJiv14 vjzthQ6F4Y9GnidUUoJhr2kIOBVt9DOpAfk5FjonNeaaLgY1tlNAargsHusdiXXq0Rz6 nnEpcUOxiufFacO6zLBY+Ayg8sNT+DIDj1I1GYpgfmQgs35u09UEqLI0dA4CxnzWyweb uW4oqMV/pzfPdVFV8Hp2izUm6XyAPHM3jCcqCTpsBDdMJyeFSeEWbGakZBao6x/tVNb/ baxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references:date :message-id:mime-version; bh=vBiOMufj42ge0pGXvJGUIq/yQqNqds7kGBMnlIG45hE=; b=Yk9qyJ+G4MoAQYUJOfycpThfvTAEiSplIORTrygJw9hAnYegOtPjVULTFJV4YkbhIC Svfe/xo9C1273LYTXxhGGfLkjTc45YPT5O3xdHoHtIQYFLQIn6Y+86H7S1SQ55wLTqmW tn/zRugpHo/xH/709Nuo/sYFSrAFt/RGywvYbkMJf2OtEbS1ANpvGoflK+2GTPeRUOR/ 4hjFyOHx7knbBq3o7yqSxRfLpMGUhejgMtNJ7bhexkyUefT2DeLSnmAipoFj6MoXajV2 TvtZkXHS3t0PmZcojvpnJJzuyAQwpt7tCWWTE82s94kGHMMnb9BcbMnlBpreiII3d8tY 0Fvw== X-Gm-Message-State: AOAM5313b5xW+STCxfuB5tgyXpcEge/Qdnmjo52vSQTCX9L6pYK9aL1X m81bSnP4dYKeaKGbNi27VE4= X-Google-Smtp-Source: ABdhPJx7a1xoiV2M794KHYLMIp9MJkayutgNm3VZ2ZeL140benz2FeX/bIF0oNKTyj0DNT+eSpqoQw== X-Received: by 2002:a5d:4570:: with SMTP id a16mr30855633wrc.310.1635253456285; Tue, 26 Oct 2021 06:04:16 -0700 (PDT) Original-Received: from localhost (tor-exit-16.zbau.f3netze.de. [185.220.100.243]) by smtp.googlemail.com with ESMTPSA id f3sm568553wmb.12.2021.10.26.06.04.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Oct 2021 06:04:15 -0700 (PDT) In-Reply-To: Received-SPF: pass client-ip=2a00:1450:4864:20::42a; envelope-from=nuclearspace@gmail.com; helo=mail-wr1-x42a.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, 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-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 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" Xref: news.gmane.io gmane.emacs.devel:277846 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Stefan Monnier writes: >> +(cl-defmacro cl--do-seq-type-signature ((type-var signature &optional r= esult) >> + &body body) > > I'm not fond of this internal macro used at only one place. > I'd rather we write the resulting code at its caller's location.> It can be reused to reimplement other functions in cl-extra. See the bug report on why they probably should be reimplemented: https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-10/msg02374.html >> + `(let ((,sig ,signature) ,type-var) >> + ;; (declare (type (integer (1)) ,sig) >> + ;; ;; Let's keep nil for now. >> + ;; (type (member nil list vector) ,type-var)) >> + (cl-check-type ,sig (integer (1))) >> + (cl-loop (cond >> + ((or (when (=3D 2 ,sig) (setq ,type-var 'list)) >> + (when (=3D 3 ,sig) (setq ,type-var 'array))) >> + ;; This duplicates main code sometimes. Maybe, >> + ;; there is elegant enough way to eliminate duplica= tion. >> + ,@(or first main) (cl-return ,result)) >> + (t (setq ,type-var (if (zerop (mod ,sig 2)) >> + 'list >> + 'array)) >> + ,@main)) >> + (setf ,sig (floor ,sig 2))))))) > > (let (,type-var) > ... > (setq ,type-var ...) > ...) > > generates worse code than > > ... > (let ((,type-var ...)) > ...) Rewriting it with a correct initial value would complicate the code while we don't want this code to be particularly efficient as it only runs once per signature. >> + (funcall >> + (if do-not-compile #'identity #'byte-compile) >> + `(lambda ,(cons (setq f (make-symbol "f")) (cons result-var ss)) > > I think you meant `#'eval` (or better: (lambda (x) (eval x t))) instead > of `#'identity`. The purpose of do-not-compile: t is to get a human-readable expression, e.g. for better understanding and for tests (which is why it's not made default). eval would produce something less straightforward. > Also you'll want to bind `lexical-binding` around the call to `byte-compi= le`. Will do. What about native-compile? I suggested above to use it as default (and use COMPILE rather than DO-NOT-COMPILE argname) but I'm not familiar with it. >> + (apply >> + (let* ((sig (apply #'cl--compute-map-into-signature result-sequence >> + sequences)) >> + (small (< sig cl--map-into-max-small-signature))) >> + (with-memoization (if small (aref cl--map-into-mappers-array sig) >> + ;; TODO: Order alist entries for faster lookup >> + ;; (note that we'll have to abandon alist-get = then). >> + (alist-get sig cl--map-into-mappers-alist >> + nil nil #'=3D)) >> + (cl--make-map-into-mapper sig))) >> + function result-sequence sequences)) > > Makes me wonder if we could define this as a cl-generic function Define what exactly as cl-generic function? make-mapper? What would it dispatch on? I have to reiterate: it's almost always a mistake trying to use CLOS when there's no class hierarchy at sight. The mistake does not seem to be recognised even though CL users keep writing CL libraries that try to implement non-CLOS dispatch, for valid reasons. CLOS dispatch is deliberately limited in what it can work with, so that it can order methods for combining. Often, you simply need a more general dispatch which is incompatible with predictable ordering of methods. Here we dispatch on signatures which are integers. One can't canonically order =E2=80=9Cmethods=E2=80=9D that specialize on integer rang= es, for example. In any case, here we'd dispatch on values which are, similarly, too complex to order into a hierarchy. Which makes the whole method-combination mechanism unapplicable. > and use something like method combinators to generate the code on > the fly. More specifically, if we can't with the current code, it > seems like a fun exercise to see what it would take to make it > possible. It so happens that I'm currently writing another general purpose sequence-oriented library in elisp, trying to actually use cl-generic there fore code generation. The topic has been intriguing me for quite some time. But for cl-map-into, I'm fine with what's already there. It works, for reasonable purposes it is as efficient as compiler will allow it to be, and it's straightforwardly extensible to other sequence types. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJLBAEBCgA1FiEEgu5SJRdnQOF34djNsr6xYbHsf0QFAmF3+hIXHG51Y2xlYXJz cGFjZUBnbWFpbC5jb20ACgkQsr6xYbHsf0TiCw/+Mf9S3ew2CondmwTAlHMlucfo 5r5w4h9r3G6ztOUZpCmdNqpHnsy5gcIveeKOAwCJswIhfawsMWqoBQOxHUhwp8Gs pBAkp1BoLyDLXC3zrJPTXAn6SDuRLKJkjlbleAQA858P1EVTTJy7EAen4aRuKQcg 5/4LJRH2qJ5uu5NqVGDv1QCBa1dOb3fOshJ3KoVAHE1vTQS/j9zlWpD+PwF6ihdr uyxjwUhsswMcUUnNuyjOQtSxGi0Khkm5N3q5fAVPrqw6efrYCCMjDjthmEPf4HIz YGl85DKKNY1cCR6ZRu6FdnglQ401GqR5nu0JNNdvA2cllEDpl+Xy3XDPLO4WYvW6 v1sSAhBUb91WzciOoen5G6fSNRBLZke05uGULm915CCCvFNOwkaeAHE9ai2k1goY 0YV16DF29E5u9VpK+4MniyrPhhWh14hsEBFBbjtfaYhhMrdLtQYC9PjHrIJfgvA9 Joga/QrRbS+4TwT/qAgMDddUbdiSL7PLB9FQv3nv+e56LxlMUYSXCGUHzlOgnVbU Qq5zhtjCrr45DPe9c3kHM+YGmw6mW2r569LrBAH4aabDw4QK8W4FY0Zg3Iu76cAy rpTDl5GQgdpLB7MjHEuMTKo5KAsvKSPMAkgYTNASLRbXjG+hmOtMHHFzG3UnE0gK bnFWeBe0PtNv+n7PVW8= =1vjk -----END PGP SIGNATURE----- --=-=-=--