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.help Subject: Re: inline function expansion Date: Sun, 28 May 2023 10:57:19 -0400 Message-ID: References: <87bkivhqip.fsf@posteo.net> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="21805"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: Philip Kaludercic , help-gnu-emacs@gnu.org To: Lynn Winebarger Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Sun May 28 16:58:06 2023 Return-path: Envelope-to: geh-help-gnu-emacs@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 1q3HqQ-0005TA-19 for geh-help-gnu-emacs@m.gmane-mx.org; Sun, 28 May 2023 16:58:06 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q3Hpn-0007DR-MV; Sun, 28 May 2023 10:57:27 -0400 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 1q3Hpm-0007DG-9S for help-gnu-emacs@gnu.org; Sun, 28 May 2023 10:57:26 -0400 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q3Hpk-00087y-Ap for help-gnu-emacs@gnu.org; Sun, 28 May 2023 10:57:26 -0400 Original-Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 6381D1001C7; Sun, 28 May 2023 10:57:22 -0400 (EDT) Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 568D31000C4; Sun, 28 May 2023 10:57:21 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1685285841; bh=8P5CGWBNGGuewpup/2z5bx96GneybDuN5penrUDGH2c=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=I01jkfBxWqckHxhGNfE9awn+5F5ajuChsxHvDbyhQyQPt+Yc6L8HnPRVPWvE5mJ// IANV7IjFRKZqtT5JdiByaS/uI7OUsxCdEY3HDa+FY0Vb4jf9y8/hkOULYfuzcncWVb hx4ApPkQCTM2A3gOKWF+rDM0BvqrUMhwNCAoedU0Smw22LDaKH9A92ZXxKARUeIiKT u12nAIzFpEolmwWrZCWOgviusK/w8lfiWpMJaTZ1kqYOyzTZ2R/88A98dvpGpKO05v hWBSBcpxhlHsWSHou4Dha09aTc+62P+och2EFOTn4uhaA4SFCS8C1AbK0o101r+zma uvIlKFyKizHkA== Original-Received: from pastel (unknown [167.88.20.246]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id D88321203A1; Sun, 28 May 2023 10:57:20 -0400 (EDT) In-Reply-To: (Lynn Winebarger's message of "Sat, 27 May 2023 10:34:23 -0400") 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.help:143778 Archived-At: > For my purposes, interfaces and realizations of interfaces are just a > way to specify bindings of symbols in a more structured and > encapsulated way than raw macros. > I'm still spit-balling here, but I'm thinking a generic > compile-time-dispatched (inlineable) "max" might be defined along > these lines: > > ;; ordering interface has two parameters > (define-interface ordering (bool-T elt-T) > ;; return value of `lt' method satisfies bool-T interface > (method (bool-T lt) (elt-T a) (elt-T b))) > > (define-realized-interface integer-ordering (ordering boolean integer) > ;; bind lt method to built-in `<' > (method lt <)) > > (defgeneric max (< a b) > "Determine the larger of a and b according to <") > > (define-inline-method max ((ordering <) &opaque a b) > "Determine the larger of a and b according to ordering <" > ;; < is treated syntactically as a dispatcher > (if (< lt a b) a b)) > > ;; because elisp does not allow applications in the operator position > (define-inlined-method integer-max (max integer-ordering)) > ;; Alternatively, > ;; (integer-ordering lt) reduces at compile time to something like > ;; #s(interface-method > ;; #s(interface-realization > ;; #s(interface ordering boolean integer) > ;; <) > ;; lt > ;; <) > ;; which `max' is specialized for by define-inline-method above, so > (defun integer-max (a b) > ;; inlined by compile-time dispatch of the max generic method > (max (integer-ordering lt) a b)) > > ;; These should produce t > (=3D (max integer-ordering 5 6) (integer-max 5 6)) > (=3D (max (integer-ordering lt) 5 6) (integer-max 5 6)) > (macroexp-const-p (macroexpand-all '(max (integer-ordering lt) 5 6))) OK, that helps me understand a bit what you're talking about, thanks. This example seems rather uninteresting (lots of extra code for very little gain), so I strongly suspect this is not your prime-motivator. What's the over-arching goal? I think `define-inline` is definitely not a good starting point for the above. OTOH you might be able to layer your `define-inlined-method` on top of the current `cl-generic.el`. AFAICT the main thing you need is some way to write a "call with enough =ABtype=BB annotations" such that the dispatch can be performed at compile time. >> >> I'm still not sure why you're not using a `compiler-macro` which seems >> >> to be exactly what you're after. >> > >> > I'm very finicky I suppose. I want to get constant expression >> > evaluation as automatically as possible, to enable the compile-time >> > dispatch cleanly. Or are you saying that generic methods can be >> > directly made into compiler macros? >> >> And here I'm lost as well. AFAICT there's just as little "directly made >> into" for define-inline as for compiler-macros (`define-inline` is just >> a way to define a function and its `compiler-macro` in one go). > > Hopefully the example above clarified what I'm talking about Somewhat. Still doesn't explain why you're focusing on `define-inline` rather than `compiler-macro`. A compiler macro is just like a macro except: - It shares its name with a function. - The returned expansion should behave identically to the way the function call would behave. - It's unspecified when or even *if* it's expanded (if it's not expanded, the function is called at runtime instead). - It receives an additional argument (the whole sexp), which it can use to say "I don't want to expand anything this time, just call the function at runtime instead". IOW it's a mechanism to implement compile-time (well, macroexpansion-time in our case) optimizations. > Although I would change "inline-const-p" to test for function purity > (exclude stateful closures or otherwise impure functions). I think that would be a mistake. "const-p" doesn't mean that the return value is pure but that the expression itself always returns the same value. Stefan