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.help Subject: Re: inline function expansion Date: Sat, 27 May 2023 10:34:23 -0400 Message-ID: References: <87bkivhqip.fsf@posteo.net> 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="30450"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Philip Kaludercic , help-gnu-emacs@gnu.org To: Stefan Monnier Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Sat May 27 16:35:30 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 1q2v0z-0007lE-WE for geh-help-gnu-emacs@m.gmane-mx.org; Sat, 27 May 2023 16:35:30 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q2v0B-0004Qj-D2; Sat, 27 May 2023 10:34:39 -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 1q2v0A-0004Qa-6z for help-gnu-emacs@gnu.org; Sat, 27 May 2023 10:34:38 -0400 Original-Received: from mail-pg1-x533.google.com ([2607:f8b0:4864:20::533]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1q2v08-0004bx-Fb for help-gnu-emacs@gnu.org; Sat, 27 May 2023 10:34:37 -0400 Original-Received: by mail-pg1-x533.google.com with SMTP id 41be03b00d2f7-5346d150972so1574916a12.3 for ; Sat, 27 May 2023 07:34:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685198075; x=1687790075; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=JC8KYYxKFGZMI2CsdC0wzfhlS39x9hdv5e81qfUYMQk=; b=Rpr0cxS/Z90gkhFSLUNyoNQG92mVOSWbyRvyaNMKiQG6mYu4DIis7ntWIHCOLPFK39 EHFiYrbP6GWQYAr7c7j29r8LUpsL5gOyJOfVLycpmcT/IJBV4AX5e86BQ+C9RFbQ68Jn SrDYqHCUzYm7mMVDIAXL/6ncsNPl6MKS20ybJWScuTCNzxb/gjPJWeP3QJFSn9NRrDJS bynj1s855SmJRRopV46yFpAwnXWxNp5eONEtdw/X0JgH+CFyViVQdKN/cPaeMlswld6n 6310OEfucZxMYWx5jIZR6pZX0bZYKXWI2GHFlnXK4RX8OK9F32PA4h/IKBFrmFUK5VA+ UqbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685198075; x=1687790075; h=content-transfer-encoding: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=JC8KYYxKFGZMI2CsdC0wzfhlS39x9hdv5e81qfUYMQk=; b=PRZZYxM888J7PIarRHeoTOoQAzLkFtKPwn0smhLECx8NqMyVtL358FM/NLHO+n0x+k rR/U6Q3/ueJBtBX7io6l13VmziIQctgyqYPkvcsbC4x+EIccVTVvWZwyVu6uhsRegoMb MH8ApjfJl4Im7wJSnfoSrEqnH+w6/JVXj42ir8PoPkUPItTVuInzwudNn5y7dx/gFxk1 awxt6B9pRZSXb5SUAxZMNWywMlkjgAp/T2Nx8HGS18GTw6tvJ5C9SY2KxHrz8NuqD7GJ 0TrdXFH92QhVqam+VaZgGFuxHrH8ZEqF6alHHajG6N+mvLP7paiVBesGj4vH2Yat+Dq7 VInA== X-Gm-Message-State: AC+VfDyE01/U1d33QnA+PgpmHS36BjI+9cbgK0uG32eLObhu1RgAyBoq boKaaRkhSpyn+SRCtE65r39I3gt1n+2tfMfuKzM= X-Google-Smtp-Source: ACHHUZ7QTRd+mQbEmTVqG0VFJ8Rq0B7goxaNVzc2RoTHQHk2Sh8FKgmm2uxbq4taOYPqiUuxbsRShpQ3QAH/syU1zYM= X-Received: by 2002:a17:902:7e85:b0:1ab:7fb:aac1 with SMTP id z5-20020a1709027e8500b001ab07fbaac1mr5588224pla.24.1685198074770; Sat, 27 May 2023 07:34:34 -0700 (PDT) In-Reply-To: Received-SPF: pass client-ip=2607:f8b0:4864:20::533; envelope-from=owinebar@gmail.com; helo=mail-pg1-x533.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, 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:143769 Archived-At: On Sat, May 20, 2023 at 11:48=E2=80=AFAM Stefan Monnier wrote: > > For my purposes, an "interface" spec is just a list of method and slot > > signatures associated to some object, which will be realized by a set > > of bindings specified via special forms and bound to some name. > > Then a compile-time generic f is a factoring of a regular generic into > > a generic function of interface realizations that produces a concrete > > runtime function. I'm thinking to adopt the "place name" technique of > > naming the concrete function by the form that created it, ie. \(f\ > > arg1-iface-realizer\ arg2-iface-realizer\ ...\). Note the check is > > that the realizer provides all the required signatures (a superset), > > which is why I refer to it as a "constraint" on the interface > > implementation. > > > > Then the generic method could dispatch on simple wrappers created by > > the iface-realizers. If constructors are invoked at compile time when > > they appear in constant expressions and have constant arguments, then > > the generic multi-dispatch method specialized on those realizers can > > inline the call to the specialized method in the compiler macro, while > > a residual generic method could do the same dispatch at run-time. > > > > But the point is to separate the expression of the algorithm from the > > expression of the bindings that are used by the algorithm, without > > resorting to either dynamic dispatch tables or ad hoc macros per > > algorithm. > > I'm still lost. An example might help. 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))) > > >> (define-inline my-plus (&rest args) > >> (inline-letevals args > >> (if (seq-every-p (lambda (x) (inline-const-p x)) args) > >> (apply #'+ (mapcar (lambda (x) (inline-const-val x)) args)= ) > >> (inline-quote (+ . ,args))))) > >> > >> seems to do (more or less) what your code illustrated. > > > > But then inline-const-val will (and inline-const-p) will get the > > symbol 'x as the operand, right? > > I don't think so. Have you tried it (Edebug should work correctly)? Ok, now I see why inline--testconst-p expands to include a call to macroexp-const-p. > >> 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 - `max' is specialized at compile-time, and reduced completely at compile-time as well if all the arguments are constant. Although I would change "inline-const-p" to test for function purity (exclude stateful closures or otherwise impure functions). > > I was thinking I needed the original symbol redefined to avoid > > multiple macro expansions of the operands, > > `compiler-macro`s can decide to keep the call as-is without introducing > an infinite macro-expansion loop. > I was concerned about an exponential rather than infinite number of expansions , though I may have just been thinking conservatively. Lynn