[GSoC] Parameter protocols in CL
Helmut Eller
eller.helmut@gmail.com
Wed Jul 18 20:29:00 GMT 2012
On Wed, Jul 18 2012, Charles Turner wrote:
> On 18 July 2012 00:04, Per Bothner <per@bothner.com> wrote:
>> Try not to get bogged down into this. The apply methods are also
>> likely to change for various reasons. So just try to translate
>> the Common Lisp forms into whatever LambdaExp forms that Scheme
>> would. Don't try to add to or enhance the parameter handling: It's
>> complicated, and it may change soon.
>
> I'm not sure what you mean by just translating to LambdaExp.
One idea is to rewrite
(lambda (&optional (var init-form supplied-p))
body)
to
(lambda (#!optional (tmp-var <unbound-marker>))
(let ((var (if (eq tmp-var <unbound-marker)
init-form
tmp-var)))
body))
where <unbound-marker> is some special value that the user can usually
not create, e.g. some of those in gnu.expr.Special.
> The other
> parameter feature missing is the ability to have a keyword name not be
> a keyword symbol, i.e. (&key ((:keyname some-other-symname) dflt)).
> That appears to need new plumbing in the code generator.
Similarity rewrite:
(lambda (&key (((keyword-name var) init-form supplied-p)))
body)
to
(lambda (#!key (keyword-name <unbound-marker>))
(let ((var (if (eq keyword-name <unbound-marker)
init-form
keyword-name)))
body))
I guess this doesn't work if keyword-name is something exotic like
&whole. Anyway the fall back:
(lambda (#!rest tmp-var)
(destructuring-bind ((((keyword-name var) init-form supplied-p)) tmp-var)
body))
should always work even in that case.
> There's also
> an inconsistency with Kawa Scheme's extended formal parameter lists.
> The grammar appears to prohibit the following:
>
> formal-arguments ::=
> req-opt-args (rest-key-args | . rest-arg)
> req-opt-args ::= req-arg ... [#!optional opt-arg ...]
>
> prohibits:
>
> ((lambda (#!optional (a 2)) (list a)))
The meta syntax: "req-arg ..." means zero-or-more so it seems that this
case is included.
> But it works. However, ((lambda (#!optional (a 2) #!rest x) (list a
> x))) fails quite spectacularly with an ArrayOutOfBoundsException.
> Tracking this bug down is like tracking The Ghost Of Christmas Past
> down. Lambda#rewriteFormals does this:
>
> if (rest_args > 0)
> lexp.max_args = -1;
>
> which I think might be causing the problem, but I'm getting lost in
> the visitor recursion.
Could also be that Kawa tries to inline the call (beta reduce) to
(list 2 '())
but makes some mistake along he way.
> This syntax is used in SBCL's
> DESTRUCTURING-BIND for reasons not completely clear to me.
You mean SBCL's DESTRUCTURING-BIND generates
something like ((lambda (&optional (a 2) &rest x) (list a x))) ?
Then it would be good to get that beta reduction right, otherwise we end
up with rather inefficient code.
> (The grammatically correct version (x #!optional (a 2) #!rest y)
> doesn't fail.. But (&optional (a 2) &rest x) if *not* a grammatical
> violation in CL). I'm not sure why the decision was made to require at
> least one "req-arg".
>
> The icing on the cake for today is that I'm getting an internal
> compiler error when I try to compile my destructuring code:
>
> <unknown>: Literals: Internal error:java.lang.Error: no method to
> construct ClassType gnu.kawa.lispexpr.LispPackage
>
> Has anyone seen that before? I'm not even using lisp packages in my
> code, I assume it's some sort of bootstrapping error in the code I've
> added, just thought I'd ask to see if anyone's been bitten by it
> before.
Without some small test case it's pretty hard to say what is going on.
Helmut
More information about the Kawa
mailing list