<div class="gmail_quote">On Sun, Apr 26, 2009 at 8:03 AM, Vladimir Sedach <span dir="ltr"><<a href="mailto:vsedach@gmail.com">vsedach@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi Red,<br>
<div class="im"><br>
> I have modified the behavior of keywords found in Parenscript source to be<br>
> parsed into (PS-QUOTE keyword) instead of (JS-VARIABLE keyword).<br>
<br>
</div>The current behavior is (ps::compile-parenscript-form :baz) => :baz<br>
(there's no quoting involved). The printer then outputs keyword<br>
symbols as strings, since this is the closest analogue (a<br>
self-evaluating object) to keywords among the native JavaScript<br>
objects.</blockquote><div class="im"><br>It appears that I had an old version. I was using the darcs repo instead of the git repo. There must have been a lot of changes as of August! (ps:ps :foo) used to output a variable reference to foo.<br>
<br>Nonetheless, here is a bug with the current implementation:<br><br>CL-USER> <br>(setf (ps:PS-PACKAGE-PREFIX :cl-user) "CL_USER_")<br>CL-USER> (ps:ps <br>
(let* ((some-prop 'foo-sym) <br> (my-object (ps:create 'foo-sym "value!"))) <br>
(slot-value my-object 'foo-sym))) <br> <br>"var CL_USER_someProp = 'foo-sym'; <br>
var CL_USER_myObject = { 'foo-sym' : 'value!' }; <br>CL_USER_myObject.CL_USER_fooSym;" <br><br>The expected behavior would be for the (create ...) form to reference the same value as the (slot-value ...) form.<br>
<br>If there were any sort of Parenscript runtime, it would be easy to make a data structure for symbols. For example, the above code could translate to something like...<br><br>function Symbol(string, prefix) {<br> this.string = string;<br>
this.prefix = prefix;<br> // .. add to symbol table, etc.<br>}<br>Symbol.prototype.toString = function() { if (this.prefix) return this.prefix + "::" + this.string; else return this.string; }<br>var someProp_symbol = new Symbol("someProp", "CL_USER");<br>
<br>var CL_USER_someProp = someProp_symbol;
<br>
var CL_USER_myObject = { someProp_symbol : 'value!'
};
<br>
CL_USER_myObject[someProp_symbol];<br><br>This would differentiate symbols and strings, and it would result in pointer comparisons between symbols, just as in lisp.<br><br>I understand the current approach is to avoid any runtime, but the runtime solution does seem like less of a hack in the end.<br>
<br>
> This seems<br>
> to make more sense because in Lisp, evaluating a keyword yields the keyword<br>
> itself rather than the value bound to it. As a result, the ability to paass<br>
> keyword arguments to functions is now restored.<br>
><br>
> CL-USER> (ps:ps (foo "bar" :quix "quo" :etc "etc..."))<br>
> "foo('bar', { quix : 'quo', etc : 'etc...' });"<br>
><br>
> Whereas this used to yield foo('bar', quix, 'quo', etc, 'etc...')<br>
<br>
</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">This is actually a fix to keyword argument handling: previously the PS<br>
lambda-list handling code assumed that whenever it encountered a<br>
keyword in the arglist of a function, it was the beginning of the<br>
keyword portion of the lambda list, and started making the object at<br>
that point. This of course may not be the case if you are trying to<br>
use keywords as arguments to a function. With keywords compiled to<br>
strings, you get self-evaluating objects and can do keyword handling<br>
in the function body at runtime (which is what the current code does).</blockquote><div><br>I see the latest implementation now processes keyword arguments differently, eliminating the old hash table approach. This seems like an okay solution, but I suspect it adds a a little overhead for each call to a function with keyword arguments.<br>
<br>I also noticed a bug that resulted in improper handling of the following case:<br>(ps:ps <br>
(defun hello-world (&key ((my-name-key my-name))) <br> (print "hello, " + my-name)) <br>
(hello-world 'my-name-key "fred"))<br> <br>"function CL_USER_helloWorld() { <br>
var CL_USER_myName; <br> var _js54 = arguments.length; <br>
for (var n52 = 0; n52 < _js54; n52 += 2) { <br> switch (arguments[n52]) { <br>
case CL_USER_myNameKey: <br> { <br>
CL_USER_myName = arguments[n52 + 1]; <br> }; <br>
}; <br> }; <br>
if (CL_USER_myName === undefined) { <br> CL_USER_myName = null; <br>
}; <br> print('hello, ', plus, CL_USER_myName); <br>
}; <br>CL_USER_helloWorld('my-name-key', 'fred');"<br>
<br>the javascript should really use the following case: case 'myNameKey' instead of case CL_USER_myNameKey. a patch is attached<br><br><br>All the best,<br>Red<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<br>
Thanks,<br>
<font color="#888888">Vladimir<br>
</font><div class="im"><br>
> In general, symbols occupy a strange place in Parenscript. Javascript has<br>
> no analogue of Lisp symbols, so there is no sensible translation of symbols<br>
> that works for everyone. Nonetheless, quoted symbols are used in many<br>
> Parenscript macros to fake having real symbols in javascript. We could<br>
> build in the ability to translate symbols to some javascript form, e.g.<br>
><br>
> (ps:ps (make-instance 'animal)) => makeInstance( symbolTable["ANIMAL"] )<br>
><br>
> The latter part of this post is just food for thought. I will go ahead and<br>
> commit the patch for the former part of this post unless someone objects.<br>
><br>
> Red<br>
><br>
</div><div><div></div><div class="h5">> _______________________________________________<br>
> parenscript-devel mailing list<br>
> <a href="mailto:parenscript-devel@common-lisp.net">parenscript-devel@common-lisp.net</a><br>
> <a href="http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel" target="_blank">http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel</a><br>
><br>
><br>
<br>
_______________________________________________<br>
parenscript-devel mailing list<br>
<a href="mailto:parenscript-devel@common-lisp.net">parenscript-devel@common-lisp.net</a><br>
<a href="http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel" target="_blank">http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel</a><br>
</div></div></blockquote></div><br>