help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: inline function expansion


From: Stefan Monnier
Subject: Re: inline function expansion
Date: Sat, 20 May 2023 11:48:38 -0400
User-agent: Gnus/5.13 (Gnus v5.13)

>> 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'm still lost.  An example might help.

>>     (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)?

    ELISP> (macroexpand-all '(my-plus 5 y))
    (+ 5 y)
    ELISP> (macroexpand-all '(my-plus 5 6))
    11 (#o13, #xb, ?\C-k)
    ELISP> 

>> 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).

> 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.

> After all, the advice facility makes every function identified by
> a symbol impure.

It's the mutability of the symbol (i.e. `fset`) rather than the advice
facility itself, but yes :-)


        Stefan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]