[parenscript-devel] Tighter keyword arguments?

Nick Fitzgerald fitzgen at gmail.com
Thu Aug 5 21:42:08 UTC 2010


Ah! Very good points, thank you for the explanation.

_Nick_



On Thu, Aug 5, 2010 at 2:13 PM, Daniel Gackle <danielgackle at gmail.com>wrote:

> < why not just use an object as the only parameter >
>
> That was the first way we did it, and we changed it for a good reason,
> but my recollection of why is fuzzy. Does anybody remember?
> The archives of this list may be helpful here.
>
> I believe the reason may have been that it places an undue burden
> on the caller. If I want to write something like this...
>
>   (member item arr :key foo :test bar)
>
> ... who is going to figure out that the last 4 arguments are really two
> keyword params and bundle them into { key : foo, test : bar }?
>
> You could make the caller do it:
>
>  (member item arr (create :key foo :test bar))
>
> ... but then you lose interoperability with CL, and arguably dilute the
> feature to the point where you might as well not have it, since it's
> easy enough to define a function that takes a js object as its last
> parameter and picks out the keys.
>
> On the other hand, you could make PS do it by decreeing that
> keywords in an arglist *always* identify keyword params, but
> that breaks this:
>
>   (member :blah arr :key foo :test bar)
>
> ... which now generates member({blah : arr, key : foo, test : bar})
> instead of the desired member("blah", arr, {key : foo, test : bar}).
> In other words, this option makes the semantics of keywords
> inconsistent in PS.
>
> Another option is to make the PS compiler consider the signature
> of the function being called before it generates the code for the call.
> That complicates the compiler and IIRC is hard to get working in
> the general case (Vladimir can comment here).
>
> So my recollection is that we settled on the existing method as the
> one that places no burden on either the caller or the callee (at the source
> level... obviously the JS that's generated for the callee is what does
> all the extra work), preserves the semantics of keywords, is closest
> to how CL does keyword args, and keeps the compiler simple.
>
>
>
>
> On Thu, Aug 5, 2010 at 2:47 PM, Nick Fitzgerald <fitzgen at gmail.com> wrote:
>
>> Ok, I just realized that I completely misread your original post. I
>> thought you were proposing the removal of defaulting to null rather than
>> leaving the value undefined.
>>
>> Have you done any profiling to see if there is a reasonable difference
>> between
>>
>> "function foo() {
>>     var a;
>>    // ... pick out and assign keyword args ...
>>     if (a === undefined) {
>>         a = null;
>>     };
>>     return bar(a);
>> };"
>>
>> and
>>
>> "function foo() {
>>     var a = null;
>>    // ... pick out and assign keyword args ...
>>     return bar(a);
>>  };"
>>
>> ?
>>
>> I just ran this very naive test in Chromium:
>>
>> var then = +new Date;
>> var i = 20000;
>> while (i--) {
>>   (function () {
>>      var a;
>>      if (a === undefined) a = null;
>>   }())
>> };
>> console.log(+new Date - then);
>>
>> Which logs 70 ms.
>>
>> var then = +new Date;
>> var i = 20000;
>> while (i--) {
>>   (function () {
>>      var a = null;
>>   }())
>> };
>> console.log(+new Date - then);
>>
>>
>> This one logs 71 ms.
>>
>> This has to have come up before, but why not just use an object as the
>> only parameter and use it's keys as the keyword arguments? I just ran the
>> same test for that, and when the keyword was missing I got 82 ms, but when
>> it was available, I got 56.
>>
>> I think using objects would make the generated code much more readable,
>> which trumps speed in this case IMO given that the difference is so small
>> and the high number of iterations being performed.
>>
>> _Nick_
>>
>>
>>
>>
>> On Thu, Aug 5, 2010 at 1:24 PM, Daniel Gackle <danielgackle at gmail.com>wrote:
>>
>>> Good point. I kept the null assignment for consistency with how PS does
>>> &optional
>>> arguments. But this begs the question: why do we care about &optional
>>> and &key arguments being set to null, as opposed to just leaving them
>>> undefined?
>>> I'm trying to remember the reason... anybody?
>>>
>>> Our experience has been that PS code works best if one treats null and
>>> undefined
>>> as interchangeable. But that may be an artifact of running some of the
>>> same code
>>> in CL as well, where there is no such distinction.
>>>
>>>
>>> On Thu, Aug 5, 2010 at 1:51 PM, Nick Fitzgerald <fitzgen at gmail.com>wrote:
>>>
>>>> +1 from me but that doesn't mean too much.
>>>>
>>>> No need to explicitly set them as `null`, because JS already has (the
>>>> more semantic in this case) `undefined`.
>>>>
>>>> _Nick_
>>>>
>>>>
>>>>
>>>> On Wed, Aug 4, 2010 at 12:30 PM, Daniel Gackle <danielgackle at gmail.com>wrote:
>>>>
>>>>> The code that's generated for a keyword argument goes like this:
>>>>>
>>>>> (ps (defun foo (&key a) (bar a)))  =>
>>>>>
>>>>> (abbreviated for clarity):
>>>>>
>>>>> "function foo() {
>>>>>     var a;
>>>>>    // ... pick out and assign keyword args ...
>>>>>     if (a === undefined) {
>>>>>         a = null;
>>>>>     };
>>>>>     return bar(a);
>>>>> };"
>>>>>
>>>>> It seems to me that this could be made tighter as follows:
>>>>>
>>>>> "function foo() {
>>>>>     var a = null;
>>>>>    // ... pick out and assign keyword args ...
>>>>>     return bar(a);
>>>>> };"
>>>>>
>>>>> The only difference I can think of is when someone explicitly passes
>>>>> undefined
>>>>> as a value for the argument, but that's an oxymoronic thing to do.
>>>>>
>>>>> Can anyone think of a reason not to make this change? I like PS's
>>>>> keyword
>>>>> arguments a lot, but the generated JS is bloated enough to make me
>>>>> wince.
>>>>>
>>>>> _______________________________________________
>>>>> parenscript-devel mailing list
>>>>> parenscript-devel at common-lisp.net
>>>>> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> parenscript-devel mailing list
>>>> parenscript-devel at common-lisp.net
>>>> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>>>
>>>>
>>>
>>> _______________________________________________
>>> parenscript-devel mailing list
>>> parenscript-devel at common-lisp.net
>>> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>>
>>>
>>
>> _______________________________________________
>> parenscript-devel mailing list
>> parenscript-devel at common-lisp.net
>> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>
>>
>
> _______________________________________________
> parenscript-devel mailing list
> parenscript-devel at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/parenscript-devel/attachments/20100805/b21005f7/attachment.html>


More information about the parenscript-devel mailing list