[Top][All Lists]

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

Re: case-lambda integration

From: Andy Wingo
Subject: Re: case-lambda integration
Date: Mon, 19 Oct 2009 21:10:46 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.92 (gnu/linux)

Good evening Ludovic :)

On Tue 13 Oct 2009 22:35, address@hidden (Ludovic Courtès) writes:

> Andy Wingo <address@hidden> writes:
>> I made allowances for efficient optional and keyword argument
>> dispatch -- so we can have keyword arguments without consing, and
>> arguments which are positionally optional yet can have keywords. This
>> is so lambda* and define* can be implemented nicely.
> I threw a glance at the branch (in particular “flesh out glil support
> for optional and keyword arguments”), but it’s unclear to me how it
> works.  The callee reserves space on the stack for its parameters, but
> how are keyword parameters associated with a reserved slot on the
> stack?

All args are passed on the stack. A procedure may have required,
optional, keyword, and rest arguments. The N required arguments are
bound to the first N local variable slots. The M optional arguments are
bound to the next M local variable slots. If an optional variable is not
positionally present, SCM_UNDEFINED is placed in the slot. If there are
keywords as well, then things get complicated.

I wanted to allow positional arguments to also have keywords. I had to
make a decision what to do if you have 2 required args, 1 optional, and
1 keyword -- if the 3rd argument is a keyword, does it go in the
optional slot or does it start the keyword processing? I chose the
latter. So once you run out of optionals or see a keyword, the remaining
arguments are shuffled up on the stack, to be placed above the empty
slots for keyword arguments -- /if any/. Then the keyword arguments are
traversed, looking at the keyword alist ((#:KW . N) ...), to determinine
the local slot that a given keyword corresponds to. If no slot is found,
that may be an error or it may be ignored -- depending on the
allow-other-keywords? option.

If a rest arg is also given, it will hold all keyword args as well, and
the rest must be a valid keyword arg list.

It's quite complicated, and very much "feature on top of feature". You
could emulate this with rest arguments, as (ice-9 optargs) does, but
with callee-parsed arguments we can make keyword arg procedures pay for
it, but without the cost of allocation on each procedure call.

So that's the deal. The tree-il interface will require initializers for
all args, so after all the args are bound, if any given arg is
uninitialized, it will be set to the value of some user-given
expression. This is useful for Scheme, where you never have
uninitialized lexicals except in erroroneous use of letrec, and for e.g.
javascript, where you want optionals to have certain values.

The system is very flexible, but should you need more flexibility, you
can have that too -- by using the rest arg interface. It costs, in terms
of allocation, but there's only so much we can do.

>> There are hooks in <lambda-case> for these, but again the question is
>> how to expose to Scheme. As I see it there are two options:
>>    1. Implement lambda* (and define*) in psyntax
>>    -or-
>>    2. Make the stock lambda accept #:optional, #:keyword, et al
>>       arguments (also a hack to psyntax)
>> I'm kindof leaning towards (2) actually. But I could go either way. Both
>> ways expose lambda* capability in the default environment -- because
>> psyntax boots before modules have booted, and these things need access
>> to psyntax internals.
> As you rightfully guessed I lean towards (1), but then again I don’t
> understand how this affects the implementation.  Would option (1) be
> somehow harder to implement, or would it tend to duplicate code or
> something like that?

So it's either introduce new identifiers (lambda* and define*) in the
default environment, or add functionality to the existing ones. I don't
care very much either way, TBH, though I lean to enhancing lambda.

> OTOH, how difficult would it be to accommodate different keyword
> argument APIs, such as ‘(ice-9 optargs)’, SRFI-89, and DSSSL, which have
> subtle differences, once we have built-in support for one flavor?

The Scheme interface will be the same as optargs, I think -- possibly
with some extensions. I haven't looked at srfi-89. I think we can do
DSSSL as it's a subset of optargs afaik.

What do you think?


reply via email to

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