Thanks Per, Now I understand that with that strategy you don't need binding at compile time,
and also the compiler needs to distinguish keywords introducing keyword arguments from
ordinary arguments.



On Mon, Mar 16, 2020 at 12:36 PM Per Bothner <xxxxxx@bothner.com> wrote:
On 3/16/20 3:18 PM, Lassi Kortela wrote:

> Yeah, that's the scenario I was wondering about. Calls to unknown procedures will have to use the slow path. But isn't that the case also for Kawa/Racket-style kwargs? It may be able to omit some checks, but it will still have to internally make a hash-table or list out of the kwargs. I guess the callee can assume the keyword list is sorted/hashed properly and doesn't need to type-check the keywords or the collection containing them and their values.

Compiling the callee creates a vector of the keywords, sorted lexicographically.
This vector is part of the procedure object.

Compiling the call, if you assume a direct call with no apply or argument "splicing",
the compiler creates a vector of the keywords in the call, also sorted.
(It can do this without knowing the callee.)  Since the vector only contains
indexes into the argument list, rather than the actual arguments, it can be created
at compile+load time.

Matching keywords arguments to parameters can now be done in a single
very efficient pass, comparing keywords with eq.  The code is simple enough
to inline when compiling the calle: No hash calculations, or dealing with collisions.
No space overhead as you'd need for a hashtable or linked list.  Very cache-friendly.

(There are some extra complications to make sure default expressions
are evaluated in the correct order.)
--
        --Per Bothner
xxxxxx@bothner.com   http://per.bothner.com/