common-lispparenscript

How to set a Lisp list as the value of a JavaScript variable using parenscript?


I have:

(ps:ps (ps:var vertices (ps:lisp (cons 'list *VERTICES*))))

which evaluates to:

"var vertices = [0.0, -200.0, 0, ... 0.4, 40];"

which is the correct expected result.

Where:


However, When *VERTICES* is large, the evaluation leads to the error:

Error: Too many arguments. While executing: PARENSCRIPT::COMPILE-SPECIAL-FORM, in process listener(1).

How do I get around this error?


Not knowing how parenscript really works internally, this problem is hard to solve. So I tried changing the way the list is passed to ps.

Here are a few failed attempts:

(ps:ps (ps:var vertices (ps:lisp (list *VERTICES*))))
=> "var vertices = 1(2, 3, 4, 0, 9, 0.1)();"

(ps:ps (ps:var vertices (ps:lisp *VERTICES*)))
=> "var vertices = 1(2, 3, 4, 0, 9, 0.1);"

(ps:ps (ps:var vertices *VERTICES*))
=> "var vertices = VERTICES;"

None are the correct expected output.

What is the right way to pass a Lisp list variable's value to parenscript to form a correct javascript array-variable assignment-statement?


Solution

  • I was able to reproduce this with 1000000 items. It seems that the parenscript compiler (which is sitting behind that ps macro) translates your list to a form (array 1 2 3 4 5 …) first. This means that array gets a million arguments, which is rather unusual for source code.

    I'd recommend thinking over your design. Why do you want to create such a large vector in your source code? Should this maybe sit in a separate file, or be loaded at runtime over the network?

    By the way, you can inspect what is happening by using the debugger you get thrown into at error. For example, in SLIME, I pressed v on the frame of compile-special-form to see the corresponding source code of parenscript. This showed the following expression:

    (apply expression-impl (cdr form))
    

    which suggests that expressions will be subject to call-arguments-limit.