[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: inline function expansion
From: |
Lynn Winebarger |
Subject: |
Re: inline function expansion |
Date: |
Sun, 28 May 2023 10:12:15 -0400 |
On Sat, May 27, 2023 at 10:34 AM Lynn Winebarger <owinebar@gmail.com> wrote:
>
> On Sat, May 20, 2023 at 11:48 AM Stefan Monnier
> <monnier@iro.umontreal.ca> 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:
>
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) = (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
> (= (max integer-ordering 5 6) (integer-max 5 6))
> (= (max (integer-ordering lt) 5 6) (integer-max 5 6))
> (macroexp-const-p (macroexpand-all '(max (integer-ordering lt) 5 6)))
>
Lynn
- Re: inline function expansion, (continued)
- Re: inline function expansion, Stefan Monnier, 2023/05/18
- Re: inline function expansion, Lynn Winebarger, 2023/05/18
- Re: inline function expansion, Stefan Monnier, 2023/05/19
- Re: inline function expansion, Lynn Winebarger, 2023/05/20
- Re: inline function expansion, Stefan Monnier, 2023/05/20
- Re: inline function expansion, Lynn Winebarger, 2023/05/27
- Re: inline function expansion,
Lynn Winebarger <=
- Re: inline function expansion, Stefan Monnier, 2023/05/28
- Re: inline function expansion, Lynn Winebarger, 2023/05/28
- Re: inline function expansion, Stefan Monnier, 2023/05/28