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: Sun, 28 May 2023 10:12:15 -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="12306"; 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 Sun May 28 16:13:21 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 1q3H96-00034O-83 for geh-help-gnu-emacs@m.gmane-mx.org; Sun, 28 May 2023 16:13:20 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q3H8M-0008KP-Hl; Sun, 28 May 2023 10:12:34 -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 1q3H8K-0008KE-G6 for help-gnu-emacs@gnu.org; Sun, 28 May 2023 10:12:32 -0400 Original-Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1q3H8I-0004IU-0T for help-gnu-emacs@gnu.org; Sun, 28 May 2023 10:12:32 -0400 Original-Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-1b00ffb4186so14616235ad.0 for ; Sun, 28 May 2023 07:12:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1685283147; x=1687875147; 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=G+DOaSK69+MlAYWgpKii9b2DHDq2ODeSu2x06lmGyw0=; b=ejM8lsvwtYN2hOOjtdw1IPMOkUILZ4ygmq2IGpDF+FKhhqm2IHxRBfOyf4nNQpRH2B /V+Zjh9DVn/LtwNd5djI5nV2fKzEmGu63uD/12JQIEGGScfvFZYxpRqVLl5jdyKeeUCy cJNVyYNwPriXYxfqGIfoSPJLDwMr251psaIscdk2q13O/RlWFAZebGY0xdbWB4C3K2Xt tucyYJzm+NG0j7N7vqXLXXGWf2qHnXdxcqpBMyuMdSSWNZVlkTQ1uCecSRTDvH1aMkeP A+O7DqH1gpz9Yauq96/yo+Re5XPRBoZOYd1iFsjoOOD1/LZorAv8IRyjqSaDxsMtz2Bo Sm4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685283147; x=1687875147; 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=G+DOaSK69+MlAYWgpKii9b2DHDq2ODeSu2x06lmGyw0=; b=L85MF9m5KW5edyYRcAwctOifF4k7tfuuCa8rIHcAFwTgwfJeepjB1XwP/yey+dUsGl NJXMzm2S/GqRIH/zyzvFOnlSoplDKV9/WYkvSlecETQG8zBmKgLYTqDMpryKUhuXSttN wZfgfmL8OMpqJsIkkCnuRVRVd8/jULi7df1ZzQLBXP1DncCmWU3/y8GtQJ8EHxfuBwQI UqhvQZrzbxuVNRnIeKlr+kVqKN6JBTasAcNL5HiUaeJ0NqC63jvlSVAFW7biJgmbuTtj 1cqK0H4sfzRBm2GguGmE3RPxBu/xiYCwRl/oElXAJq6kqrhVxvHJNyxpKHmTACW4c8Th JHXg== X-Gm-Message-State: AC+VfDzq6kNIDPYs9LL1Uki1/9KdI0i4vmqmijqBR9IgssWt4jC9vV2n ejB+7qXWwapnjSJt2qcthHYrnKGvc2w1wXNtEQkFkUTP57E= X-Google-Smtp-Source: ACHHUZ7OPXtgEfEJm47C1ymM+NBm4ovFjNOBHJrLiDLyVmKg/QgFVaWwTqGwg6TIjRnzZNoHJDnwnCN7Sk+uhQC20vA= X-Received: by 2002:a17:902:8603:b0:1ab:1355:1a45 with SMTP id f3-20020a170902860300b001ab13551a45mr7984732plo.30.1685283146886; Sun, 28 May 2023 07:12:26 -0700 (PDT) In-Reply-To: Received-SPF: pass client-ip=2607:f8b0:4864:20::634; envelope-from=owinebar@gmail.com; helo=mail-pl1-x634.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:143777 Archived-At: On Sat, May 27, 2023 at 10:34=E2=80=AFAM Lynn Winebarger wrote: > > 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 slo= t > > > 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 int= o > > > a generic function of interface realizations that produces a concrete > > > runtime function. I'm thinking to adopt the "place name" technique o= f > > > 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 whe= n > > > 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, whil= e > > > 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: > My intention below is that define-inline-method is like applying the generic function to the abstract interfaces, producing a function that consumes the body as an argument. So maybe there should be a (define-inline-generic max (< a b)) that creates the dual-definition of max as a (generic) compiler macro and generic function, with the method specializing max on "realized-interface" arguments that successfully unify against the supplied interface spec: (max <-iface a-iface b-iface) =3D (lambda (<-realized a-realized b-realized) ((lambda (a b) ...) (realized-interface-value a) (realized-interface-value b))) where "realized-interface-value" removes the wrapper used for specialization. Note that it also only does so for "opaque" arguments, to allow the "<" argument to be treated as a fixed constant when the call site provides a constant. This definition should specialize both the generic compiler macro and the generic function on realizations of the specified interfaces for the arguments of max. Technically, we need the following definitions: ;; these should be predefined constants (define-interface null-interface) (define-realized-interface null-realized) In the code below, not specifying an interface for the a and b arguments is the same as specifying the null-interface. > ;; 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)) > And this > ;; because elisp does not allow applications in the operator position > (define-inlined-method integer-max (max integer-ordering)) should be (define-inlined-method integer-max (max integer-ordering null-realized null-realized)) > ;; 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))) > Lynn