On Thu, Apr 23, 2009 at 11:42 PM, Erik Huelsmann <ehuels@...> wrote:
> On Wed, Apr 22, 2009 at 3:40 PM, Russell McManus
> <russell_mcmanus@...> wrote:
>> Erik Huelsmann <ehuels@...> writes:
>>> Now, there are supposedly 2 ways of resolving this issue:
>>> 1) Make the context available to processArgs() by creating a lexical
>>> environment at run time when needed
>>> 2) Compile the parsing of arguments into each function which needs
>>> that, using the lexical environment as established by the compiler
>>> Last October, I was working on (1), but I estimate runtime cost:
>>> environment records need to be created for every call to a function
>>> with non-constant init forms. Now, I'm thinking (2) may be favorable,
>>> but will cost a lot more storage space: nearly the same code will be
>>> repeated in lots of places, depending on whether we *always* compile
>>> argument parsing or that we do it only for non-constant cases.
>>> So, I'm basically posting this because of 2 reasons: first of all, I'd
>>> like your opinions, but second of all, I'm hoping some of you may know
>>> how other implementations handle this issue.
>> I think it makes perfect sense to effectively have the compiler inline
>> arg parsing code into the body of the defun being compiled. It will
>> increase the size of the generated bytecode a little, but it's
>> conceptually simple, and should be fast.
>> I'm pretty sure that sbcl takes a similar approach. The body of a
>> compiled function has an arg-parsing prelude, and then a label later in
>> the body where the real processing starts assuming that the args are all
>> computed and in the right place. If a direct call is made to a function
>> with keyword args (i.e. not #'apply or #'funcall) then at the call site
>> this can be compiled into a call that skips the arg parsing prelude.
> For now, I have taken a similar approach: the argument list gets
> rewritten to assign the values passed in to uninterned symbols. Then,
> in a LET* form, the values are bound to the actual symbols and the
> declarations added to the LET* body.
> This rewriting of *all* lamda list elements is required to make it
> work for the declarations. This could be made more efficient, but for
> now I just wanted a prototype.
> The issue now is however that the attached patch implements the above
> described behaviour, but when I build ABCL with the patch applied, it
> starts complaining about symbols being unbound (the one I see:
> DOC-STRING-ALLOWED unbound). Without the patch I don't see this issue.
> However, when I look at the code that's being generated for the
> function which has a DOC-STRING-ALLOWED argument (that's parse-body in
> destructuring-bind.lisp), it looks completely sane!
> Can someone help by having a look at the patch? That would be greatly
Last weekend, I committed a patch - a variant of the one which was attached.
The effect of the patch is that - using an additional LET* block - the
non-constants get evaluated, but only when the parameter hasn't been
specified. Because a LET* block is used, the code in the initforms
will be compiled.
A funny outcome of the above is that code was suddenly being compiled
which used to be interpreted, therefore generating style warnings
because of unused arguments. [That explains the additional commits..]
To achieve the above, I had to create code to rewrite argument lists
big time. This means that the code being run through the compiler has
all gensym-ed symbols in the lambda-list. Hope it doesn't disturb you
too much :-)