From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: [PATCH] Some improvements for cl-flet Date: Sat, 02 Oct 2021 23:51:09 -0400 Message-ID: References: <87bl4zqnqn.fsf@gmail.com> <87mto2gbpu.fsf@gmail.com> <87k0j6gbjg.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="32512"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: akater Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Oct 03 05:52:05 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 1mWsXk-0008CQ-DL for ged-emacs-devel@m.gmane-mx.org; Sun, 03 Oct 2021 05:52:04 +0200 Original-Received: from localhost ([::1]:43324 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mWsXj-0003aI-00 for ged-emacs-devel@m.gmane-mx.org; Sat, 02 Oct 2021 23:52:03 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:47412) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mWsX4-0002vN-Vj for emacs-devel@gnu.org; Sat, 02 Oct 2021 23:51:22 -0400 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:46620) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mWsX1-0002YC-ET for emacs-devel@gnu.org; Sat, 02 Oct 2021 23:51:21 -0400 Original-Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id A430810038B; Sat, 2 Oct 2021 23:51:16 -0400 (EDT) Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id C019610018E; Sat, 2 Oct 2021 23:51:10 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1633233070; bh=ZLPanryYlHbWWckFBPBro+fHPhUyl861GbraSEpyR80=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=LFc6HrkicAbBDM3fLzacpEWZ6SFktKTc6Za+PqzL3W9z9S/B8P7B11ud+XCo75qur NtcyVEIZeGBIAGZvz3A5Xd1odWGc0gTHBfzj78cTYKObbn1Zb5YYOi0mpoG8PX1EVo Ge7gTa7uDLfJWHn/LVuRNJsnmn2R8b1RujZQsj8OEwRm4sHtGBFYwXeVTFfjxdyiNO bpprv4ON23/xWLIXoTXcBwtmOxe4vb1TmwZo8hyl+ktsyUKvo3lBbXNds+N4Nl/AXS eGuSnPBag2sAWVA2q7DywWzNnuLPdn6x498Au+3vIbn8LGOhQaKDgR6oN/pcqIt/4T myThSbwvkxB4g== Original-Received: from pastel (unknown [45.72.241.23]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 861CF12020A; Sat, 2 Oct 2021 23:51:10 -0400 (EDT) In-Reply-To: <87k0j6gbjg.fsf@gmail.com> (akater's message of "Thu, 23 Sep 2021 22:41:23 +0000") Received-SPF: pass client-ip=132.204.25.50; envelope-from=monnier@iro.umontreal.ca; helo=mailscanner.iro.umontreal.ca X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, 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:276096 Archived-At: Hi, Sorry for taking so long to review this. This looks very complex for a macro that's used rather rarely. Maybe it might be worthwhile splitting it into 2 or 3 patches so as to better see how we got to the level of complexity. See more comments below. > --- a/lisp/emacs-lisp/cl-generic.el I skipped this since `with-memoization` is now in `subr-x`. > diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el > index 6d6482c349..ecbe8e86fc 100644 > --- a/lisp/emacs-lisp/cl-macs.el > +++ b/lisp/emacs-lisp/cl-macs.el > @@ -2004,6 +2004,282 @@ defun cl--labels-convert (f) > (setq cl--labels-convert-cache (cons f res)) > res)))))) > > +(defvar cl--flet-convert-with-setf-cache nil > + "Like `cl--labels-convert-cache' but for local setf functions.") > + > +(defun cl--flet-convert-with-setf (f) > + "Special macro-expander to rename (function F) references in `cl-flet', including (function (setf F)). > + > +See also `cl--labels-convert'." > + ;; Note: If this function, or `cl--labels-convert', for that matter, > + ;; is redefined at runtime, > + ;; the whole replacement mechanism breaks! > + (if (and (consp f) (eq 'setf (car f))) > + (cond > + ;; We repeat lots of code from `cl--labels-convert' > + ((eq (cadr f) (car cl--flet-convert-with-setf-cache)) > + (cdr cl--flet-convert-with-setf-cache)) > + (t > + (let* ((found (assoc f macroexpand-all-environment #'equal)) > + (replacement (and found > + (ignore-errors > + (funcall (cdr found) cl--labels-magic))))) > + (if (and replacement (eq cl--labels-magic (car replacement))) > + (nth 1 replacement) > + (let ((res `(function ,f))) > + (setq cl--flet-convert-with-setf-cache (cons (cadr f) res)) > + res))))) > + (cl--labels-convert f))) I didn't get to the point of trying to understand this. > +(defmacro with--cl-flet-macroexp ( arglist var > + function-name expander memoized-alist > + &rest body) All the defs should start with "cl-" so it should be `cl--with...`. > +(defun cl--expand-local-setf (&rest places-and-values) > + "Expand `(setf . ,PLACES-AND-VALUES) > +according to `cl--local-setf-expanders'. > + > +Presumes the caller has `macroexpand-all-environment' bound." Why do we have/need this? Does it work with other things that use gv-places, like `push`, `pop`, `cl-callf`, ...? If so, how? If not, then we need another approach which does. I thought handling `cl-flet` of (setf foo) would amount to calling `gv-setter` to get the symbol corresponding to `(setf foo)` and then c-flet-binding that symbol instead of `(setf foo). > +(defun cl--expand-flet (env body &rest flet-expanders-plist) > + "Return a form equivalent to `(cl-flet ,bindings BODY) > +where bindings correspond to FLET-EXPANDERS-PLIST as described below. > + > +ENV should be macroexpansion environment > +to be augmented with some definitions from FLET-EXPANDERS-PLIST > +to then expand forms in BODY with. > + > +FLET-EXPANDERS-PLIST should be a plist > +where keys are function names > +and values are 0-argument lambdas > +to be called if the corresponding function name is encountered > +in BODY and then only (that is, at most once). Why "at most once"? > +The return value of said lambdas should be either > + > +- a valid let-binding (SYMBOL function) to be used in let* > + bindings over BODY so that SYMBOL could be used in place of the > + corresponding function name in BODY > + > +or > + > +- a list (NIL EXPR) for EXPR to be used in BODY in place of the > + corresponding function name as is. Can we simplify this so only one of the two is supported? Stefan