unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Lynn Winebarger <owinebar@gmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Philip Kaludercic <philipk@posteo.net>, help-gnu-emacs@gnu.org
Subject: Re: inline function expansion
Date: Sat, 20 May 2023 11:01:00 -0400	[thread overview]
Message-ID: <CAM=F=bA6+bWcPahY6tk36ELi9PboCGeJZV=NPSPOTVQrtoDCkQ@mail.gmail.com> (raw)
In-Reply-To: <jwv353sv62r.fsf-monnier+emacs@gnu.org>

On Fri, May 19, 2023 at 9:07 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> > I'm trying to provide myself a tool for generic programming that
> > dispatches at compile time.
>
> I still don't understand what you mean by that.
> Do you mean that the programmers write
>
>     (my-foo a b c)
>
> and during macroexpansion this is turned into
>
>     (my-foo-for-thurbies a b c)
>
> when we somehow figure out that `a` is a "thurby"?

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've been writing too much repetitive
> > code, but I'm not a fan of ad hoc macros either.  Basically, I'm
> > trying to provide a C#-ish system for writing generic code
> > parameterized by interface requirements.
>
> [ "generic code" and "interface requirements" are ... generic terms with
> wildly different meanings in different communities, and I'm not familiar
> enough with the C# world to guess what you mean by that.  ]

I only hacked on C#'s generics for about a month a decade ago, so it
really is just my memory of the "flavor" of the generics being
expressed by constraints on interfaces.

>
> >> > (define-inline inline-+ (&rest args)
> >> >    (if (seq-every-p #'inline-const-p args)
> >> >        (apply (eval-when-compile (symbol-function '+)) args)
> >> >     (inline-quote (,(eval-when-compile (symbol-function '+)) . ,args))))
> >>
> >> IIRC you definitely need an `inline-letvals` somewhere here.
> >
> > That's the issue - if you use inline-letvals, then the code can't make
> > use of constant values provided as operands.
>
> Are you sure?  I think the real problem is that `inline-const-p` is not
> a function but a macro, so you can pass it as a first-class function
> E.g.:
>
>     (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?

>
> >> But also this will define the non-inlined version as something along the
> >> lines of:
> >>
> >>     (defun inline-+ (&rest args)
> >>        (if (seq-every-p ... args)
> >>            (apply '+ args)
> >>         (apply (symbol-function '+) args)))
> >>
> >> which is much too slow IMO.
> >
> > I agree.
> >
> > I posted a patch to emacs-devel for define-inline-pure-subr that
> > adapts the technique of define-inline.
>
> 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?

I was thinking I needed the original symbol redefined to avoid
multiple macro expansions of the operands, as define-inline-pure-subr
expands its operands before returning, so returning the inline-form is
problematic.  I also  consider the property that inlining is
uncooperative with advice to be a feature, particularly for pure
functions.  After all, the advice facility makes every function
identified by a symbol impure.

Lynn



  reply	other threads:[~2023-05-20 15:01 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-07 14:32 inline function expansion Lynn Winebarger
2023-05-07 17:51 ` Basile Starynkevitch
2023-05-07 19:48 ` Philip Kaludercic
2023-05-07 20:16   ` Lynn Winebarger
2023-05-08  0:21     ` Emanuel Berg
2023-05-08 11:12       ` Lynn Winebarger
2023-05-08  2:03   ` Lynn Winebarger
2023-05-11  7:11   ` Lynn Winebarger
2023-05-12  6:25     ` Emanuel Berg
2023-05-18 14:56     ` Lynn Winebarger
2023-05-19 13:31       ` Stefan Monnier
2023-05-20 14:18         ` Lynn Winebarger
2023-05-20 15:32           ` Stefan Monnier
2023-05-21 12:47             ` Lynn Winebarger
2023-05-18 18:29     ` Stefan Monnier
2023-05-19  0:22       ` Lynn Winebarger
2023-05-19 13:07         ` Stefan Monnier
2023-05-20 15:01           ` Lynn Winebarger [this message]
2023-05-20 15:48             ` Stefan Monnier
2023-05-27 14:34               ` Lynn Winebarger
2023-05-28 14:12                 ` Lynn Winebarger
2023-05-28 14:57                 ` Stefan Monnier
2023-05-28 22:42                   ` Lynn Winebarger
2023-05-29  2:59                     ` Stefan Monnier
2023-06-06 22:38                       ` Lynn Winebarger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAM=F=bA6+bWcPahY6tk36ELi9PboCGeJZV=NPSPOTVQrtoDCkQ@mail.gmail.com' \
    --to=owinebar@gmail.com \
    --cc=help-gnu-emacs@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=philipk@posteo.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).