Merge remote-tracking branch 'upstream/master' into upstream-ter
[parenscript.git] / docs / reference.html
blob20dcf71738a5bfa81296a083f6e37f8250e1e77e
1 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6 <title>Parenscript Reference Manual</title>
8 <style type="text/css">
9 body {
10 margin-left:50px;
11 margin-right:50px;
13 pre {
14 margin-left:60px;
16 p {
17 margin-left:10px;
19 dd {
20 color:#909;
22 </style>
23 </head>
25 <body>
26 <center><h1>Parenscript Reference Manual</h1></center>
28 <h2>Table of Contents</h2>
30 <ol>
31 <li><a href="#section-ps-compiler">The Parenscript compiler</a></li>
32 <li><a href="#section-symbolconv">Symbol conversion</a></li>
33 <li><a href="#section-namespace">The Parenscript namespace system</a>
34 <ul>
35 <li><a href="#section-obfuscation">Identifier obfuscation</a></li>
36 <li><a href="#section-minification">Minification</a></li>
37 </ul>
38 </li>
39 <li><a href="#reserved-symbols">Reserved symbols</a></li>
40 <li><a href="#section-statements-expressions">Statements, expressions, and return</a></li>
41 <li><a href="#section-types">Types and type predicates</a></li>
42 <li><a href="#section-literals">Literals</a>
43 <ul>
44 <li><a href="#ssection-numbers">Numbers</a></li>
45 <li><a href="#ssection-strings-chars">Strings and characters</a></li>
46 <li><a href="#ssection-regex">Regular expressions</a></li>
47 <li><a href="#ssection-booleans">Booleans and undefined</a></li>
48 </ul>
49 </li>
50 <li><a href="#section-objects">Objects</a></li>
51 <li><a href="#section-arrays">Arrays</a></li>
52 <li><a href="#section-arithmetic">Arithmetic and boolean operators</a></li>
53 <li><a href="#section-math">Mathematical functions and constants</a></li>
54 <li><a href="#section-blocks">Blocks</a></li>
55 <li><a href="#section-functions">Functions and multiple values</a></li>
56 <li><a href="#section-control-transfer">Control transfer and exceptions</a></li>
57 <li><a href="#section-conditionals">Conditionals</a></li>
58 <li><a href="#section-variables">Variable binding and declaration</a></li>
59 <li><a href="#section-assignment">Assignment</a></li>
60 <li><a href="#section-iteration">Iteration</a></li>
61 <li><a href="#section-macros">Macros</a>
62 <ul>
63 <li><a href="#ssection-defining-macros">Defining macros</a></li>
64 <li><a href="#ssection-symbol-macros">Symbol macros</a></li>
65 <li><a href="#ssection-gensym">Gensym</a></li>
66 </ul>
67 </li>
68 <li><a href="#section-utilities">Utilities</a>
69 <ul>
70 <li><a href="#ssection-dom">DOM</a></li>
71 <li><a href="#ssection-html-gen">HTML generation</a></li>
72 </ul>
73 </li>
74 <li><a href="#section-runtime-library">Runtime library</a></li>
75 <li><a href="#section-slime-integration">SLIME integration</a></li>
76 </ol>
78 <h2 id="section-ps-compiler">The Parenscript compiler</h2>
79 <ul>
80 <li>(<code id="ps">PS</code> &body body)</li>
81 <li>(<code id="ps-to-stream">PS-TO-STREAM</code> stream &body body)</li>
82 <li>(<code id="ps*">PS*</code> &rest body)</li>
83 <li>(<code id="ps-doc">PS-DOC</code> &body body)</li>
84 <li>(<code id="ps-doc*">PS-DOC*</code> &body body)</li>
85 <li>(<code id="ps-inline">PS-INLINE</code> form &optional <code>*JS-STRING-DELIMITER*</code>)</li>
86 <li>(<code id="ps-inline*">PS-INLINE*</code> form &optional <code>*JS-STRING-DELIMITER*</code>)</li>
87 <li>(<code id="ps-compile-stream">PS-COMPILE-STREAM</code> stream)</li>
88 <li>(<code id="ps-compile-file">PS-COMPILE-FILE</code> file)</li>
89 <li>(<code id="lisp">LISP</code> lisp-forms)</li>
90 <li>(<code id="symbol-to-js-string">SYMBOL-TO-JS-STRING</code> symbol)</li>
92 <li><code id="*js-target-version*">*JS-TARGET-VERSION*</code></li>
93 <li><code id="*parenscript-stream*">*PARENSCRIPT-STREAM*</code></li>
94 <li><code id="*js-string-delimiter*">*JS-STRING-DELIMITER*</code></li>
95 <li><code id="*js-inline-string-delimiter*">*JS-INLINE-STRING-DELIMITER*</code></li>
96 <li><code id="*ps-read-function*">*PS-READ-FUNCTION*</code></li>
97 <li><code id="*version*">*VERSION*</code></li>
98 <li><code id="*defined-operators*">*DEFINED-OPERATORS*</code></li>
99 </ul>
101 <dl>
102 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
103 </dl>
105 <p>The difference between the regular and <code>*</code> versions
106 of the Parenscript compiler forms is roughly the difference
107 between <code>COMPILE</code>
108 and <code>EVAL</code>. The <code>*</code> forms are functions
109 that do all compilation when they are evaluated, while the
110 regular forms are macros that do almost all (except for the use
111 of the <code>LISP</code> special form, see below) compilation at
112 macro-expansion time.</p>
114 <p><code>PS</code> and <code>PS*</code> are the main interfaces to
115 the Parenscript compiler. They come with <code>PS-DOC</code>
116 and <code>PS-DOC*</code> counterparts which compile the given
117 code
118 with <a href="#*ps-gensym-counter*"><code>*PS-GENSYM-COUNTER*</code></a>
119 bound to 0, and are useful for writing automated tests.</p>
121 <p>By default, Parenscript writes output to a string. You can
122 output directly to a stream in one of two ways: either by
123 using <code>PS-TO-STREAM</code> instead of <code>PS</code>, or by
124 binding <code>*PARENSCRIPT-STREAM*</code> before
125 calling <code>PS*</code>.</p>
127 <p><code>PS-INLINE</code> and <code>PS-INLINE*</code> take a single
128 Parenscript form and output a string starting
129 with <code>javascript:</code> that can be used in HTML node
130 attributes. As well, they provide an argument to bind the value of
131 <code>*JS-STRING-DELIMITER*</code> to control the value of the
132 JavaScript string escape character to be compatible with
133 whatever the HTML generation mechanism is used (for example, if
134 HTML strings are delimited using <code>#\'</code>,
135 using <code>#\&quot;</code> will avoid conflicts without
136 requiring the output JavaScript code to be escaped). By default
137 the value is taken
138 from <code>*JS-INLINE-STRING-DELIMITER*</code>.</p>
140 <p>Parenscript code can be compiled from a stream or file
141 via <code>PS-COMPILE-STREAM</code>
142 and <code>PS-COMPILE-FILE</code>, respectively. The special
143 variable <code>*PS-READ-FUNCTION*</code> is bound to the function
144 used to read the forms from the file/stream (<code>READ</code> by
145 default), and can be used to provide completely customizable
146 syntax for Parenscript files.</p>
148 <p>Parenscript can also call out to arbitrary Common Lisp code at
149 <i>output time</i> (that is, every time an expression containing
150 a call to the Parenscript compiler is evaluated, compared
151 to <i>compile time</i>, where the effect is accomplished using
152 macros) using the special form <code>LISP</code>. The form
153 provided to <code>LISP</code> is evaluated, and its result is
154 compiled as though it were Parenscript code. For <code>PS</code>
155 and <code>PS-INLINE</code>, the Parenscript output code is
156 generated at macro-expansion time, and the <code>LISP</code>
157 statements are inserted inline into the output and have access
158 to the enclosing Common Lisp lexical
159 environment. <code>PS*</code> and <code>PS1*</code> evaluate the
160 <code>LISP</code> forms using <code>EVAL</code>, providing them
161 access to the current dynamic environment only (of course,
162 using <code>LISP</code> when calling the <code>*</code> forms is
163 not strictly necessary, as the values can be inserted inline
164 into code).</p>
166 <p><code>*JS-TARGET-VERSION*</code> (<code>1.3</code> by default)
167 controls which version of JavaScript that Parenscript
168 targets. For newer versions of JS, some Parenscript special
169 forms may compile to more concise and/or efficient expressions
170 that are not present in earlier versions of JavaScript.</p>
172 <p><code>SYMBOL-TO-JS-STRING</code> is the Parenscript function
173 responsible for translating Common Lisp symbols to JavaScript
174 identifiers (see the section
175 on <a href="#section-symbolconv">symbol conversion</a> for the
176 translation rules). It is helpful for writing libraries or other
177 pieces of code that will interface with Parenscript-generated
178 JavaScript.</p>
180 <p>Newer versions of Parenscript may implement Common Lisp special
181 forms, functions or macros that were left unimplemented by earlier
182 versions. This can cause problems if your code provides
183 implementations for those forms itself. To help deal with
184 this, <code>*DEFINED-OPERATORS*</code> provides a list of special
185 forms, macros, and symbol macros defined by Parenscript
186 itself. <code>*VERSION*</code> is bound to the current release
187 version number of Parenscript.</p>
189 <h2 id="section-symbolconv">Symbol conversion</h2>
191 <p>Parenscript supports output for both case-sensitive and
192 case-insensitive symbols. By default the Lisp reader upcases all
193 symbols. By setting readtable-case
194 to <a href="http://www.lispworks.com/documentation/lw50/CLHS/Body/23_ab.htm">:invert</a>
195 (you can use
196 the <a href="http://common-lisp.net/project/named-readtables/">named-readtables</a>
197 library to make this more convenient) symbol case is preserved,
198 and Parenscript will output mixed-case symbols
199 (like <code>encodeURIComponent</code>) correctly.</p>
201 <p>Lisp symbols (other than keywords) that are all uppercase or
202 contain special characters are converted to JavaScript
203 identifiers by following a few simple rules. Special
204 characters <code>!, ?, #, @, %, /, *</code> and <code>+</code>
205 get replaced by their written-out equivalents "bang", "what",
206 "hash", "at", "percent", "slash", "start" and "plus"
207 respectively. The <code>$</code> character is untouched.</p>
209 <dl>
210 <dt><code>!?#@%</code></dt>
211 <dd><code>bangwhathashatpercent;</code></dd>
212 </dl>
214 <p>The <code>-</code> is an indication that the following
215 character should be converted to uppercase.</p>
217 <dl>
218 <dt><code>bla-foo-bar</code></dt>
219 <dd><code>blaFooBar;</code></dd>
220 </dl>
222 <p>JavaScript identifiers that begin with an uppercase letter can
223 be obtained with a leading <code>-</code> or <code>*</code>.</p>
225 <dl>
226 <dt><code>*array</code></dt>
227 <dd><code>Array;</code></dd>
228 </dl>
230 <p>A symbol starting and ending with <code>+</code>
231 or <code>*</code> is converted to all uppercase, to signify that
232 this is a constant or a global variable.</p>
234 <dl>
235 <dt><code>*global-array*</code></dt>
236 <dd><code>GLOBALARRAY;</code></dd>
237 </dl>
239 <p>Keywords are not translated to JavaScript identifiers, but are
240 printed in lower case without any character substitution as
241 strings. This is done because strings are the closest equivalent
242 to Common Lisp keywords (being self-evaluating objects in
243 JavaScript), and to permit keywords to be used for identifying
244 various symbols (for example, as tokens in a parser).</p>
246 <dl>
247 <dt><code>:+</code></dt>
248 <dd><code>'+';</code></dd>
250 <dt><code>:foo-Bar</code></dt>
251 <dd><code>'foo-bar';</code></dd>
252 </dl>
254 <h2 id="section-namespace">The Parenscript namespace system</h2>
255 <ul>
256 <li>(<code id="in-package">in-package</code> package-designator)</li>
257 <li>(<code id="use-package">use-package</code> package-designator)</li>
258 <li>(setf (<code id="ps-package-prefix">PS-PACKAGE-PREFIX</code> package-designator) string)</li>
259 </ul>
261 <p>Although JavaScript does not offer namespacing or a package system,
262 Parenscript does provide a namespace mechanism for generated
263 JavaScript by integrating with the Common Lisp package system. Since
264 Parenscript code is normally read in by the Lisp reader, all symbols
265 (except for uninterned ones, ie - those specified with
266 the <code>#:</code> reader macro) have a Lisp package. By default, no
267 packages are prefixed. You can specify that symbols in a particular
268 package receive a prefix when translated to JavaScript with the
269 <code>PS-PACKAGE-PREFIX</code> place.</p>
271 <code>
272 <pre>(defpackage "PS-REF.MY-LIBRARY"
273 (:use "PARENSCRIPT"))
274 (setf (ps-package-prefix "PS-REF.MY-LIBRARY") "my_library_")</pre>
275 </code>
277 <dl>
278 <dt><code>
279 <pre>(defun ps-ref.my-library::library-function (x y)
280 (return (+ x y)))</pre>
281 </code>
282 </dt>
283 <dd><code>
284 <pre>function my_library_libraryFunction(x, y) {
285 return x + y;
286 };</pre>
287 </code>
288 </dd>
289 </dl>
291 <p>Parenscript provides <code>IN-PACKAGE</code>
292 and <code>USE-PACKAGE</code> special forms, primarily useful
293 with <a href="#ps-compile-file"><code>PS-COMPILE-FILE</code></a>
294 and <a href="#ps-compile-stream"><code>PS-COMPILE-STREAM</code></a>.</p>
296 <h3 id="section-obfuscation">Identifier obfuscation</h3>
297 <ul>
298 <li>(<code id="obfuscate-package">OBFUSCATE-PACKAGE</code> package-designator &optional symbol-map)</li>
299 <li>(<code id="unobfuscate-package">UNOBFUSCATE-PACKAGE</code> package-designator)</li>
300 </ul>
302 <p>Similar to the namespace mechanism, Parenscript provides a
303 facility to generate obfuscated identifiers in specified CL
304 packages. The function <code>OBFUSCATE-PACKAGE</code> may
305 optionally be passed a closure that maps symbols to their
306 obfuscated counterparts. By default, the mapping is done
307 using <code><a href="#ps-gensym">PS-GENSYM</a></code>.</p>
309 <code>
310 <pre>(defpackage "PS-REF.OBFUSCATE-ME")
311 (obfuscate-package "PS-REF.OBFUSCATE-ME"
312 (let ((code-pt-counter #x8CF6)
313 (symbol-map (make-hash-table)))
314 (lambda (symbol)
315 (or (gethash symbol symbol-map)
316 (setf (gethash symbol symbol-map)
317 (make-symbol (string (code-char (incf code-pt-counter)))))))))</pre>
318 </code>
320 <dl>
321 <dt><code>
322 <pre>(defun ps-ref.obfuscate-me::a-function (a b ps-ref.obfuscate-me::foo)
323 (+ a (ps-ref.my-library::library-function b ps-ref.obfuscate-me::foo)))</pre>
324 </code>
325 </dt>
326 <dd><code>
327 <pre>function 賷(a, b, 賸) {
328 return a + libraryFunction(b, 賸);
329 };</pre>
330 </code>
331 </dd>
332 </dl>
334 <p>The obfuscation and namespace facilities can be used on packages
335 at the same time.</p>
337 <p>Since Parenscript doesn't know anything about the DOM or other
338 JavaScript libraries, library function and property names might be
339 inadvertently obfuscated. To help prevent that, Parenscript comes
340 with
341 the <code>ps-dom1-symbols</code>, <code>ps-dom2-symbols</code>, <code>ps-window-wd-symbols</code>, <code>ps-dom-nonstandard-symbols</code>
342 and <code>ps-dhtml-symbols</code> symbol packages that define
343 various DOM property and function identifiers as exported symbols
344 (in both case-sensitive and insensitive variants), which you can
345 import into your packages to help prevent symbols
346 like <code>pageXOffset</code> from being
347 obfuscated. The <code>ps-dhtml-symbols</code> package contains the
348 broadest range of symbols and is most generally useful.</p>
350 <p>If you use obfuscation and external JavaScript libraries, you
351 can use the same technique to define your own packages with
352 symbols that will not be obfuscated.</p>
354 <h3 id="section-minification">Minification</h3>
355 <ul>
356 <li><code id="*ps-print-pretty*">*PS-PRINT-PRETTY*</code></li>
357 <li><code id="*indent-num-spaces*">*INDENT-NUM-SPACES*</code></li>
358 </ul>
360 <p><code>*PS-PRINT-PRETTY*</code>
361 and <code>*INDENT-NUM-SPACES*</code> control whether the resulting
362 JavaScript code is pretty-printed, and if so, how many spaces go
363 into each indent level, respectively. By default the code is
364 pretty-printed with 4 spaces per indent level.</p>
366 <p>Setting <code>*PS-PRINT-PRETTY*</code> to nil and turning
367 on <a href="#section-obfuscation">obfuscation</a> will minify the
368 generated JavaScript code.</p>
370 <h2 id="reserved-symbols">Reserved symbols</h2>
372 <p>The following symbols are reserved in Parenscript, and should not
373 be used as variable names.</p>
375 <code>
376 ! ~ ++ -- * / % + - &lt;&lt; &gt;&gt; &gt;&gt;&gt; &lt; &gt;
377 &lt;= &gt;= == != === !== & ^ | && || *= /= %= += -= &lt;&lt;=
378 &gt;&gt;= &gt;&gt;&gt;= &= ^= |= 1- 1+ @ ABSTRACT AND AREF ARRAY
379 BOOLEAN BREAK BYTE CASE CATCH CHAR CLASS COMMA CONST CONTINUE
380 CREATE DEBUGGER DECF DEFAULT DEFUN DEFVAR DELETE DO DO* DOEACH
381 DOLIST DOTIMES DOUBLE ELSE ENUM EQL EXPORT EXTENDS F FALSE FINAL
382 FINALLY FLOAT FLOOR FOR FOR-IN FUNCTION GOTO IF IMPLEMENTS
383 IMPORT IN INCF INSTANCEOF INT INTERFACE JS LABELED-FOR LAMBDA
384 LET LET* LISP LIST LONG MAKE-ARRAY NATIVE NEW NIL NOT OR PACKAGE
385 PRIVATE PROGN PROTECTED PUBLIC RANDOM REGEX RETURN SETF SHORT
386 GETPROP STATIC SUPER SWITCH SYMBOL-MACROLET SYNCHRONIZED T THIS
387 THROW THROWS TRANSIENT TRY TYPEOF UNDEFINED UNLESS VAR VOID
388 VOLATILE WHEN WHILE WITH WITH-SLOTS
389 </code>
391 <h2 id="section-statements-expressions">Statements, expressions, and return</h2>
393 <p>In contrast to Lisp, where everything is an expression,
394 JavaScript makes an arbitrary distinction between expressions,
395 which yield a value and can be nested in other expressions, and
396 statements, which have no value and cannot occur in
397 expressions.</p>
399 <p>Some Parenscript special forms compile to expressions, while
400 others can only compile to statements. Certain Parenscript
401 forms, like <code>IF</code> and <code>PROGN</code>, generate
402 different JavaScript depending on if they are used in an
403 expression context or a statement context. In such cases,
404 Parenscript tries to generate statement code if possible to
405 increase readability, only falling back to the expression code
406 if it is necessary.</p>
408 <dl><dt><code>(+ i (if x (foo) (bar)))</code></dt>
409 <dd><code>i + (x ? foo() : bar());</code></dd>
411 <dt><code>(if x (foo) (bar))</code></dt>
412 <dd><code>
413 <pre>if (x) {
414 foo();
415 } else {
416 bar();
417 };</pre>
418 </code>
419 </dd>
420 </dl>
422 <p>One important feature found in Lisp but absent in JavaScript is
423 implicit return in functions. Parenscript supports implicit
424 return by having a <code>RETURN</code> special form that works
425 around the statement-expression dichotomy:</p>
427 <dl>
428 <dt><code>
429 <pre>(defun foo (x)
430 (1+ x))</pre>
431 </code>
432 </dt>
433 <dd><code>
434 <pre>function foo(x) {
435 return x + 1;
436 };</pre>
437 </code>
438 </dd>
440 <dt><code>
441 <pre>(lambda (x)
442 (case x
443 (1 (loop repeat 3 do (alert "foo")))
444 (:bar (alert "bar"))
445 (otherwise 4)))</pre>
446 </code>
447 </dt>
448 <dd><code>
449 <pre>function (x) {
450 switch (x) {
451 case 1:
452 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
453 alert('foo');
455 return null;
456 case 'bar':
457 return alert('bar');
458 default:
459 return 4;
461 };</pre>
462 </code>
463 </dd>
464 </dl>
466 <p>Note that Parenscript does not enforce the statement-expression
467 dichotomy, so it is possible to generate syntactically incorrect
468 JavaScript by nesting special forms that only compile to
469 statements in a context that calls for an expression:</p>
471 <dl>
472 <dt><code>(+ 1 (dotimes (x 3) (+ x x)))</code></dt>
473 <dd>
474 <code>
475 <pre>1 + for (var x = 0; x < 3; x += 1) {
476 x + x;
477 };</pre>
478 </code>
479 </dd>
480 </dl>
482 <h2 id="section-types">Types and type predicates</h2>
483 <ul>
484 <li>(<code id="typeof">TYPEOF</code> object)</li>
485 <li>(<code id="instanceof">INSTANCEOF</code> object type)</li>
486 <li>(<code id="null">NULL</code> object)</li>
487 <li>(<code id="undefined">UNDEFINED</code> object)</li>
488 <li>(<code id="defined">DEFINED</code> object)</li>
489 <li>(<code id="stringp">STRINGP</code> object)</li>
490 <li>(<code id="numberp">NUMBERP</code> object)</li>
491 <li>(<code id="functionp">FUNCTIONP</code> object)</li>
492 <li>(<code id="objectp">OBJECTP</code> object)</li>
493 </ul>
495 <dl>
496 <dt>object</dt> <dd>an expression yielding an object</dd>
497 <dt>type</dt> <dd>a type designator</dd>
498 </dl>
500 <p>Parenscript is based around the JavaScript type system, and
501 does not introduce any new types or objects, nor does it attempt
502 to provide a Common Lisp-like interface to the type system.</p>
504 <h2 id="section-literals">Literals</h2>
506 <h3 id="ssection-numbers">Numbers</h3>
508 <p>Parenscript prints all integer literals as integers, and floats
509 and rationals as floats, in base 10.</p>
511 <dl>
512 <dt><code>1</code></dt>
513 <dd><code>1;</code></dd>
515 <dt><code>123.123</code></dt>
516 <dd><code>123.123;</code></dd>
518 <dt><code>3/4</code></dt>
519 <dd><code>0.75;</code></dd>
521 <dt><code>#x10</code></dt>
522 <dd><code>16;</code></dd>
523 </dl>
525 <h3 id="ssection-strings-chars">Strings and characters</h3>
527 <p>Lisp strings are converted to JavaScript strings.</p>
529 <dl>
530 <dt><code>"foobar"</code></dt>
531 <dd><code>'foobar';</code></dd>
532 </dl>
534 <p>Parenscript makes no effort to interpolate C-style escape
535 strings. Rather, non-printable characters in Lisp strings are
536 output using escape sequences:</p>
538 <dl>
539 <dt><code>#\Tab</code></dt>
540 <dd><code>'\t';</code></dd>
542 <dt><code>"\\n"</code></dt>
543 <dd><code>'\\n';</code></dd>
544 </dl>
546 <h3 id="ssection-regex">Regular expressions</h3>
547 <ul>
548 <li>(<code id="regex">REGEX</code> regex)</li>
549 </ul>
551 <dl>
552 <dt>regex</dt> <dd>a string</dd>
553 </dl>
555 <p>Regular expressions can be created by using
556 the <code>REGEX</code> form. If the argument does not start with
557 <code>/</code>, it is surrounded by <code>/</code>, otherwise it
558 is left as it is.</p>
560 <dl>
561 <dt><code>(regex "foobar")</code></dt>
562 <dd><code>/foobar/;</code></dd>
564 <dt><code>(regex "/foobar/i")</code></dt>
565 <dd><code>/foobar/i;</code></dd>
566 </dl>
568 <p><a href="http://weitz.de/cl-interpol/">CL-INTERPOL</a> is
569 convenient for writing regular expressions:</p>
571 <dl>
572 <dt><code>(regex #?r"/([^\s]+)foobar/i")</code></dt>
573 <dd><code>/([^\s]+)foobar/i;</code></dd>
574 </dl>
576 <h3 id="ssection-booleans">Booleans and undefined</h3>
577 <ul>
578 <li><code id="t">T</code></li>
579 <li><code id="f">F</code></li>
580 <li><code if="false">FALSE</code></li>
581 <li><code id="nil">NIL</code></li>
582 <li><code id="undefined">UNDEFINED</code></li>
583 </ul>
585 <p><code>T</code> and <code>FALSE</code> (or <code>F</code>) are
586 converted to their JavaScript boolean
587 equivalents <code>true</code> and <code>false</code>.</p>
589 <p><code>NIL</code> is converted to the JavaScript keyword
590 <code>null</code>.</p>
592 <p><code>UNDEFINED</code> is converted to the JavaScript global
593 variable <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Properties/undefined"><code>undefined</code></a>.</p>
595 <h2 id="section-objects">Objects</h2>
596 <ul>
597 <li>(<code id="new">NEW</code> constructor)</li>
598 <li>(<code id="create">CREATE</code> {name value}*)</li>
599 <li>(<code id="getprop">GETPROP</code> object {slot-specifier}*)</li>
600 <li>(<code id="@">@</code> {slot-specifier}*)</li>
601 <li>(<code id="chain">CHAIN</code> {slot-specifier | function-call}*)</li>
602 <li>(<code id="with-slots">WITH-SLOTS</code> ({slot-name}*) object body)</li>
603 <li>(<code id="delete">DELETE</code> object)</li>
604 </ul>
606 <dl>
607 <dt>constructor</dt> <dd>a function call to an object constructor</dd>
608 <dt>name</dt> <dd>symbol, string or keyword</dd>
609 <dt>value</dt> <dd>an expression</dd>
610 <dt>object</dt> <dd>an expression yielding an object</dd>
611 <dt>slot-specifier</dt> <dd>a quoted symbol, a string, a number, or an expression yielding a string or number</dd>
612 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
613 </dl>
615 <p>The <code>NEW</code> operator maps to JavaScript like:</p>
617 <dl>
618 <dt><code>(new (Person age shoe-size))</code></dt>
619 <dd><code>new Person(age, shoeSize);</code></dd>
620 </dl>
622 <p>Object literals are created
623 with <code>CREATE</code>. <code>CREATE</code> takes a property
624 list of property names and values.</p>
626 <dl>
627 <dt><code>(create foo "bar" :blorg 1)</code></dt>
628 <dd><code>{ foo : 'bar', 'blorg' : 1 };</code></dd>
630 <dt><code>
631 <pre>(create foo "hihi"
632 blorg (array 1 2 3)
633 another-object (create :schtrunz 1))</pre>
634 </code>
635 </dt>
636 <dd><code>
637 <pre>{ foo : 'hihi',
638 blorg : [ 1, 2, 3 ],
639 anotherObject : { 'schtrunz' : 1 } };</pre>
640 </code>
641 </dd>
642 </dl>
644 <p>Object properties can be accessed using
645 <code>GETPROP</code>, which takes an object and a list of
646 properties.</p>
648 <dl>
649 <dt><code>(getprop obj 'foo)</code></dt>
650 <dd><code>obj.foo;</code></dd>
652 <dt><code>(getprop obj foo)</code></dt>
653 <dd><code>obj[foo];</code></dd>
655 <dt><code>(getprop element i 'child-node 0 'node-value)</code></dt>
656 <dd><code>element[i].childNode[0].nodeValue;</code></dd>
657 </dl>
659 <p>The convenience macro <code>@</code> quotes all its given
660 symbol slot-specifiers to save typing:</p>
662 <dl>
663 <dt><code>(@ an-object foo bar)</code></dt>
664 <dd><code>anObject.foo.bar;</code></dd>
666 <dt><code>(@ foo bar child-node 0 node-value)</code></dt>
667 <dd><code>foo.bar.childNode[0].nodeValue;</code></dd>
668 </dl>
670 <p><code>CHAIN</code> can be used to conveniently chain together
671 accessors and function calls:</p>
673 <dl>
674 <dt><code>(chain foo (bar x y) 0 baz)</code></dt>
675 <dd><code>foo.bar(x, y)[0].baz;</code></dd>
676 </dl>
678 <p><code>WITH-SLOTS</code> can be used to bind the given
679 slot-names to a symbol macro that will expand into
680 a <code>GETPROP</code> form at expansion time:</p>
682 <dl>
683 <dt><code>
684 <pre>(with-slots (a b c) this
685 (+ a b c))</pre>
686 </code>
687 </dt>
688 <dd><code>this.a + this.b + this.c;</code></dd>
689 </dl>
691 <h2 id="section-arrays">Arrays</h2>
692 <ul>
693 <li>(<code id="array">ARRAY</code> {values}*)</li>
694 <li>(<code id="list">LIST</code> {values}*)</li>
695 <li>(<code id="[]">[]</code> {values}*)</li>
696 <li>(<code id="make-array">MAKE-ARRAY</code> {values}*)</li>
697 <li>(<code id="length">LENGTH</code> array)</li>
698 <li>(<code id="aref">AREF</code> array index)</li>
699 <li>(<code id="elt">ELT</code> array index)</li>
700 <li>(<code id="destructuring-bind">DESTRUCTURING-BIND</code> bindings array body)</li>
701 <li>(<code id="concatenate">CONCATENATE 'STRING</code> {values}*)</li>
702 <li>(<code id="append">APPEND</code> {values}*)</li>
703 </ul>
705 <dl>
706 <dt>values</dt> <dd>an expression</dd>
707 <dt>array</dt> <dd>an expression</dd>
708 <dt>index</dt> <dd>an expression</dd>
709 </dl>
711 <p>Array literals can be created using the <code>ARRAY</code>
712 or <code>LIST</code> forms.</p>
714 <dl>
715 <dt><code>(array)</code></dt>
716 <dd><code>[];</code></dd>
718 <dt><code>(array 1 2 3)</code></dt>
719 <dd><code>[1, 2, 3];</code></dd>
721 <dt><code>(list (foo) (bar) 3)</code></dt>
722 <dd><code>[foo(), bar(), 3];</code></dd>
724 <dt><code>
725 <pre>(array (array 2 3)
726 (array "foo" "bar"))</pre>
727 </code>
728 </dt>
729 <dd><code>[[ 2, 3 ], ['foo', 'bar']];</code></dd>
730 </dl>
732 <p>The <code>[]</code> macro treats list arguments as quoted,
733 making it easy to write nested array literals:</p>
735 <dl>
736 <dt><code>([] 1 2 (3 4) 5 6)</code></dt>
737 <dd><code>[1, 2, [3, 4], 5, 6];</code></dd>
738 </dl>
740 <p>Arrays can also be created with a call to the <code>Array</code>
741 function using <code>MAKE-ARRAY</code>.</p>
743 <dl>
744 <dt><code>(make-array)</code></dt>
745 <dd><code>new Array();</code></dd>
747 <dt><code>(make-array 1 2 3)</code></dt>
748 <dd><code>new Array(1, 2, 3);</code></dd>
750 <dt><code>
751 <pre>(make-array
752 (make-array 2 3)
753 (make-array "foobar" "bratzel bub"))</pre>
754 </code>
755 </dt>
756 <dd><code>new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));</code></dd>
757 </dl>
759 <p>Array elements can be accessed using <code>AREF</code> or <code>ELT</code>.</p>
761 <h2 id="section-arithmetic">Arithmetic and boolean operators</h2>
762 <ul>
763 <li>(&lt;operator&gt; {argument}*)</li>
764 <li>(&lt;single-operator&gt; argument)</li>
765 </ul>
767 <dl>
768 <dt>&lt;operator&gt;</dt>
769 <dd>one of <code>*, /, %, +, -, <<, >>, >>>, < >, EQL,
770 ==, !=, =, ===, !==, &, ^, |, &&, AND, ||, OR</code>
771 </dd>
773 <dt>&lt;single-operator&gt;</dt>
774 <dd>one of <code>INCF, DECF, ++, --, NOT, !</code></dd>
776 <dt>argument</dt> <dd>an expression</dd>
777 </dl>
779 <p>Operator forms are similar to function call forms, but have an
780 operator as function name.</p>
782 <p>Please note that <code>=</code> is converted to <code>==</code> in
783 JavaScript. The <code>=</code> Parenscript operator is not the
784 assignment operator.</p>
786 <dl>
787 <dt><code>(* 1 2)</code></dt>
788 <dd><code>1 * 2;</code></dd>
790 <dt><code>(= 1 2)</code></dt>
791 <dd><code>1 === 2;</code></dd>
792 </dl>
794 <h2 id="section-math">Mathematical functions and constants</h2>
795 <ul>
796 <li>(<code id="max">MAX</code> {number}*)</li>
797 <li>(<code id="min">MIN</code> {number}*)</li>
798 <li>(<code id="floor">FLOOR</code> number &optional divisor)</li>
799 <li>(<code id="ceiling">CEILING</code> number &optional divisor)</li>
800 <li>(<code id="round">ROUND</code> number &optional divisor)</li>
801 <li>(<code id="sin">SIN</code> number)</li>
802 <li>(<code id="cos">COS</code> number)</li>
803 <li>(<code id="tan">TAN</code> number)</li>
804 <li>(<code id="asin">ASIN</code> number)</li>
805 <li>(<code id="acos">ACOS</code> number)</li>
806 <li>(<code id="atan">ATAN</code> number1 &optional number2)</li>
807 <li>(<code id="sinh">SINH</code> number)</li>
808 <li>(<code id="cosh">COSH</code> number)</li>
809 <li>(<code id="tanh">TANH</code> number)</li>
810 <li>(<code id="asinh">ASINH</code> number)</li>
811 <li>(<code id="acosh">ACOSH</code> number)</li>
812 <li>(<code id="atanh">ATANH</code> number)</li>
813 <li>(<code id="1+">1+</code> number)</li>
814 <li>(<code id="1-">1-</code> number)</li>
815 <li>(<code id="abs">ABS</code> number)</li>
816 <li>(<code id="evenp">EVENP</code> number)</li>
817 <li>(<code id="oddp">ODDP</code> number)</li>
818 <li>(<code id="exp">EXP</code> number)</li>
819 <li>(<code id="expt">EXPT</code> base power)</li>
820 <li>(<code id="log">LOG</code> number &optional base)</li>
821 <li>(<code id="sqrt">SQRT</code> number)</li>
822 <li>(<code id="random">RANDOM</code> &optional limit)</li>
824 <li><code id="pi">PI</code></li>
825 </ul>
827 <p>The mathematical functions listed above work mostly like their
828 Common Lisp counterparts when called directly, with the
829 exception that complex numbers are not supported. However, most
830 of them are implemented as macros, and as such cannot be treated
831 as first-class functions.</p>
833 <h2 id="section-blocks">Blocks</h2>
834 <ul>
835 <li>(<code id="progn">PROGN</code> {statement}*) in statement context</li>
836 <li>(<code>PROGN</code> {expression}*) in expression context</li>
837 <li>(<code id="prog1">PROG1</code> {expression | statement}*)</li>
838 <li>(<code id="prog2">PROG2</code> {expression | statement}*)</li>
839 <li>(<code id="eval-when">EVAL-WHEN</code> {expression | statement}*)</li>
840 </ul>
842 <dl>
843 <dt>statement</dt> <dd>a form that compiles to a statement</dd>
844 <dt>expression</dt> <dd>a form that compiles to an expression</dd>
845 </dl>
847 <p>The translation of <code>PROGN</code> depends on whether it is
848 found in a statement or expression context:</p>
850 <dl>
851 <dt><code>(progn (blorg i) (blafoo i))</code></dt>
852 <dd><code>
853 <pre>blorg(i);
854 blafoo(i);</pre>
855 </code>
856 </dd>
858 <dt><code>(+ i (progn (blorg i) (blafoo i)))</code></dt>
859 <dd><code>i + (blorg(i), blafoo(i));</code></dd>
860 </dl>
862 <p>The Parenscript <code>EVAL-WHEN</code> special operator has a
863 slightly different meaning from the Common Lisp one. The code in
864 the <code>EVAL-WHEN</code> special form is assumed to be Common Lisp
865 code in :compile-toplevel and :load-toplevel sitations, and is
866 executed by the Parenscript compiler, and is assumed to be Parenscript
867 code in the :execute situation, when it is run as JavaScript.</p>
869 <h2 id="section-functions">Functions and multiple values</h2>
870 <ul>
871 <li>(<code id="defun">DEFUN</code> name lambda-list body)</li>
872 <li>(<code id="lambda">LAMBDA</code> lambda-list body)</li>
873 <li>(<code id="flet">FLET</code> ({(name lambda-list body)}*) body)</li>
874 <li>(<code id="labels">LABELS</code> ({(name lambda-list body)}*) body)</li>
875 <li>(<code id="values">VALUES</code> {expression}*)</li>
876 <li>(<code id="multiple-value-bind">MULTIPLE-VALUE-BIND</code> (var*) expression body)</li>
877 <li>(<code id="apply">APPLY</code> function expression*)</li>
878 <li>(<code id="funcall">FUNCALL</code> function expression*)</li>
879 <li><code id="this">THIS</code></li>
880 </ul>
882 <dl>
883 <dt>expression</dt> <dd>a form that compiles to an expression</dd>
884 <dt>name</dt> <dd>a symbol</dd>
885 <dt>lambda-list</dt> <dd>a lambda list</dd>
886 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
887 <dt>var</dt> <dd>a symbol naming a variable</dd>
888 <dt>function</dt> <dd>an expression that yields a function</dd>
889 </dl>
891 <p>New function definitions can be introduced using all the
892 regular Lisp forms
893 - <code>DEFUN</code>, <code>LAMBDA</code>, <code>FLET</code>,
894 and <code>LABELS</code>. Function lambda lists
895 support <code>&optional</code>, <code>&rest</code> and
896 <code>&key</code> arguments.</p>
898 <p>The Parenscript multiple value facility passes the first return
899 value using the regular JavaScript convention, therefore functions
900 returning multiple values can be called by regular JavaScript code
901 and <code>MULTIPLE-VALUE-BIND</code> works with regular JavaScript
902 functions.</p>
904 <p><code>APPLY</code> is a macro that expands into a call to the
905 JavaScript <code>apply</code> method.</p>
907 <h2 id="section-control-transfer">Control transfer and exceptions</h2>
908 <ul>
909 <li>(<code id="return">RETURN</code> {value}?)</li>
910 <li>(<code id="throw">THROW</code> {exp}?)</li>
911 <li>(<code id="try">TRY</code> form
912 {(<code id="catch">:CATCH</code> (var) body)}?
913 {(<code id="finally">:FINALLY</code> body)}?)</li>
914 <li>(<code id="unwind-protect">UNWIND-PROTECT</code> protected-form cleanup-form)</li>
915 <li>(<code id="ignore-errors">IGNORE-ERRORS</code> body)</li>
916 </ul>
918 <dl>
919 <dt>value</dt> <dd>a statement or expression</dd>
920 <dt>exp</dt> <dd>an expression</dd>
921 <dt>var</dt> <dd>variable to which the value of the caught <code>THROW</code> is bound</dd>
922 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
923 </dl>
925 <p>Parenscript <code>RETURN</code> and <code>THROW</code> forms do
926 not work like the Common Lisp forms with the same names.</p>
928 <p><code>RETURN</code> can only be used to return a value from
929 a function - Parenscript has no analogue of Common Lisp's
930 blocks. <code>RETURN</code> works when given either expressions or
931 statements (in which case it performs semantic analysis to
932 determine what should be returned).</p>
934 <dl>
935 <dt><code>
936 <pre>(lambda (x)
937 (return (case x
938 (1 :a)
939 (2 :b))))</pre>
940 </code>
941 </dt>
942 <dd><code>
943 <pre>function (x) {
944 switch (x) {
945 case 1:
946 return 'a';
947 case 2:
948 return 'b';
950 };</pre>
951 </code>
952 </dd>
953 </dl>
955 <p>Likewise, <code>THROW</code> translates directly into the
956 JavaScript <code>throw</code>, to be used with <code>TRY</code>,
957 which is translated to the JavaScript <code>try</code>.</p>
959 <dl>
960 <dt><code>
961 <pre>(try (throw "i")
962 (:catch (error)
963 (alert (+ "an error happened: " error)))
964 (:finally
965 (alert "Leaving the try form")))</pre>
966 </code>
967 </dt>
968 <dd><code>
969 <pre>try {
970 throw 'i';
971 } catch (error) {
972 alert('an error happened: ' + error);
973 } finally {
974 alert('Leaving the try form');
975 };</pre>
976 </code>
977 </dd>
978 </dl>
980 <h2 id="section-conditionals">Conditionals</h2>
981 <ul>
982 <li>(<code id="if">IF</code> condition then {else})</li>
983 <li>(<code id="when">WHEN</code> condition then)</li>
984 <li>(<code id="unless">UNLESS</code> condition then)</li>
985 <li>(<code id="cond">COND</code> {clauses}*)</li>
986 <li>(<code id="case">CASE</code> case-value clause*)</li>
987 <li>(<code id="switch">SWITCH</code> case-value clause*)</li>
988 <li><code id="break">BREAK</code></li>
989 </ul>
991 <dl>
992 <dt>condition</dt> <dd>an expression</dd>
993 <dt>then</dt> <dd>a statement in statement context, or an expression in expression context</dd>
994 <dt>else</dt> <dd>a statement in statement context, or an expression in expression context</dd>
995 <dt>clause</dt> <dd>(&lt;value&gt; body) | (default body)</dd>
996 </dl>
998 <p><code>IF, WHEN, UNLESS</code> and <code>COND</code> work like
999 their Lisp counterparts, and are compiled either into statements
1000 or expressions, depending on the context:</p>
1002 <dl>
1003 <dt><code>(cond ((= x 1) (+ x (if (foo y) 2 3))))</code>
1004 </dt>
1005 <dd><code>
1006 <pre>if (x == 1) {
1007 x + (foo(y) ? 2 : 3);
1008 };</pre>
1009 </code>
1010 </dd>
1011 </dl>
1013 <p><code>CASE</code> works similar to its Common Lisp equivalent,
1014 but keys are limited to keywords, numbers, and strings, and the
1015 symbols <tt>t</tt> and <tt>otherwise</tt>. Any other symbols used
1016 as keys are assumed to be symbol-macros that macroexpand to
1017 numbers or strings (this behavior differs from Common Lisp, which
1018 does not macroexpand keys). If the symbol does not macroexpand to
1019 a number or string, an error is signalled.
1021 An additional form, <code>SWITCH</code>, takes the same syntax
1022 as <code>CASE</code>, but the individual branches must be
1023 terminated with the
1024 symbol <a href="#break"><code>BREAK</code></a>. This allows
1025 C-style case "fall-throughs" in <code>switch</code>
1026 statements:</p>
1028 <dl>
1029 <dt><code>
1030 <pre>(switch (aref blorg i)
1031 (1 (alert "If I get here"))
1032 (2 (alert "I also get here")
1033 break)
1034 (default (alert "I always get here")))</pre>
1035 </code>
1036 </dt>
1037 <dd><code>
1038 <pre>switch (blorg[i]) {
1039 case 1:
1040 alert('If I get here');
1041 case 2:
1042 alert('I also get here');
1043 break;
1044 default:
1045 alert('I always get here');
1046 };</pre>
1047 </code>
1048 </dd>
1049 </dl>
1051 <p>Note that the default case in a <code>SWITCH</code> statement
1052 must be named <code id="default">DEFAULT</code>.</p>
1054 <h2 id="section-variables">Variable binding and declaration</h2>
1055 <ul>
1056 <li>(<code id="let">LET</code> ({var | (var value)}*) body)</li>
1057 <li>(<code id="let*">LET*</code> ({var | (var value)}*) body)</li>
1058 <li>(<code id="defvar">DEFVAR</code> var {value}?)</li>
1059 <li>(<code id="var">VAR</code> var {value}?)</li>
1060 </ul>
1062 <dl>
1063 <dt>var</dt> <dd>a symbol</dd>
1064 <dt>value</dt> <dd>an expression</dd>
1065 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
1066 <dt>object</dt> <dd>an expression evaluating to an object</dd>
1067 </dl>
1069 <p>Parenscript provides the <code>LET</code> and <code>LET*</code>
1070 special forms for creating new variable bindings. Both special
1071 forms implement lexical scope by renaming the provided variables
1072 via <a href="#ps-gensym"><code>GENSYM</code></a>, and implement
1073 dynamic binding
1074 using <a href="#try"><code>TRY-FINALLY</code></a>.</p>
1076 <p>Special variables can be declared using
1077 <code>DEFVAR</code>. Note that the result is undefined
1078 if <code>DEFVAR</code> does not occur as a top-level form.</p>
1080 <p>One Parenscript feature that is not part of Common Lisp is the
1081 lexically-scoped global variable, which is declared using
1082 the <code>VAR</code> special form. The result is undefined
1083 if <code>VAR</code> does not occur as a top-level form.</p>
1085 <p>An example of variable declaration and binding:</p>
1087 <dl>
1088 <dt><code>
1089 <pre>(defvar *a* 4)
1090 (var *b* 3)
1091 (lambda ()
1092 (let ((x 1)
1093 (*a* 2)
1094 (*b* 6))
1095 (let* ((y (+ x 1))
1096 (x (+ x y)))
1097 (+ *a* *b* x y))))</pre>
1098 </code>
1099 </dt>
1100 <dd><code>
1101 <pre>var A = 4;
1102 var B = 3;
1103 function () {
1104 var x = 1;
1105 var B = 6;
1106 var A_TMPSTACK1;
1107 try {
1108 A_TMPSTACK1 = A;
1109 A = 2;
1110 var y = x + 1;
1111 var x2 = x + y;
1112 return A + B + x2 + y;
1113 } finally {
1114 A = A_TMPSTACK1;
1116 };</pre>
1117 </code>
1118 </dd>
1119 </dl>
1121 <h2 id="section-assignment">Assignment</h2>
1123 <p>Parenscript assignment is done via the
1124 standard <code id="setf">SETF</code>, <code id="SETQ">SETQ</code>,
1125 <code id="PSETF">PSETF</code>, and <code id="PSETQ">PSETQ</code>
1126 Lisp special forms. Parenscript supports the Common Lisp
1127 protocol of <code>SETF</code>able places.</p>
1129 <p>New places can be defined in one of two ways: using
1130 <code>DEFSETF</code> or using <code>DEFUN</code> with a setf
1131 function name; both are analogous to their Common Lisp
1132 counterparts. <code>DEFSETF</code> supports both long and short
1133 forms, while <code>DEFUN</code> of a setf place generates a
1134 JavaScript function name with the <code>__setf_</code>
1135 prefix:</p>
1137 <dl>
1138 <dt><code>
1139 <pre>(defun (setf color) (new-color el)
1140 (setf (@ el style color) new-color))</pre>
1141 </code>
1142 </dt>
1143 <dd><code>
1144 <pre>function __setf_color(newColor, el) {
1145 return el.style.color = newColor;
1146 };</pre>
1147 </code>
1148 </dd>
1150 <dt><code>(setf (color some-div) (+ 23 "em"))</code></dt>
1151 <dd><code>
1152 <pre>var _js2 = someDiv;
1153 var _js1 = 23 + 'em';
1154 __setf_color(_js1, _js2);</pre>
1155 </code>
1156 </dd>
1157 </dl>
1159 <p>The following example illustrates how setf places can be used
1160 to provide a uniform protocol for positioning elements in HTML
1161 pages:</p>
1163 <dl>
1164 <dt><code>
1165 <pre>(defsetf left (el) (offset)
1166 `(setf (@ ,el style left) ,offset))
1168 (defmacro left (el)
1169 `(@ ,el offset-left))
1171 (setf (left some-div) (+ 123 "px"))
1172 (left some-div)</pre>
1173 </code>
1174 </dt>
1175 <dd><code>
1176 <pre>var _js2 = someDiv;
1177 var _js1 = 123 + 'px';
1178 _js2.style.left = _js1;
1179 someDiv.offsetLeft;</pre>
1180 </code>
1181 </dd>
1182 </dl>
1184 <h2 id="section-iteration">Iteration</h2>
1185 <ul>
1186 <li>(<code id="do">DO</code> ({var | (var {init}? {step}?)}*) (end-test {result}?) body)</li>
1187 <li>(<code id="do*">DO*</code> ({var | (var {init}? {step}?)}*) (end-test {result}?) body)</li>
1188 <li>(<code id="dotimes">DOTIMES</code> (var numeric-form {result}?) body)</li>
1189 <li>(<code id="dolist">DOLIST</code> (var list-form {result}?) body)</li>
1190 <li>(<code id="for-in">FOR-IN</code> (var object) body)</li>
1191 <li>(<code id="while">WHILE</code> end-test body)</li>
1192 <li>(<code id="loop">LOOP</code> {loop clauses}*)</li>
1193 </ul>
1195 <dl>
1196 <dt>var</dt> <dd>a symbol</dd>
1197 <dt>numeric-form</dt> <dd>a number yielding expression</dd>
1198 <dt>list-form</dt> <dd>an array yielding expression</dd>
1199 <dt>object-form</dt> <dd>an object yielding expression</dd>
1200 <dt>init</dt> <dd>an expression</dd>
1201 <dt>step</dt> <dd>an expression</dd>
1202 <dt>end-test</dt> <dd>an expression</dd>
1203 <dt>result</dt> <dd>an expression</dd>
1204 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
1205 </dl>
1207 <p>Parenscript comes with a wide array of Common Lisp iteration
1208 constructs that compile to efficient JavaScript code,
1209 including a partial implementation of <code>LOOP</code>.</p>
1211 <h2 id="section-macros">Macros</h2>
1212 <h3 id="ssection-defining-macros">Defining macros</h3>
1213 <ul>
1214 <li>(<code id="defmacro">DEFMACRO</code> name lambda-list macro-body)</li>
1215 <li>(<code id="defpsmacro">DEFPSMACRO</code> name lambda-list macro-body)</li>
1216 <li>(<code id="defmacro+ps">DEFMACRO+PS</code> name lambda-list macro-body)</li>
1217 <li>(<code id="import-macros-from-lisp">IMPORT-MACROS-FROM-LISP</code> symbol*)</li>
1218 <li>(<code id="macrolet">MACROLET</code> ({name lambda-list macro-body}*) body)</li>
1219 </ul>
1221 <dl>
1222 <dt>name</dt> <dd>a symbol</dd>
1223 <dt>lambda-list</dt> <dd>a lambda list</dd>
1224 <dt>macro-body</dt> <dd>Lisp code evaluating to Parenscript code</dd>
1225 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
1226 <dt>symbol</dt> <dd>symbol with a Lisp macro function definition</dd>
1227 </dl>
1229 <p>Parenscript macros are like Lisp macros in that they have
1230 access to the full Lisp language, but different in that they must
1231 produce Parenscript code. Since Parenscript provides a large
1232 subset of Common Lisp, many Lisp macros already produce valid
1233 Parenscript code, and vice-versa. Parenscript provides several
1234 different ways to define new macros, and to use already existing
1235 Common Lisp macros.</p>
1237 <p><code>DEFMACRO</code> and <code>MACROLET</code> can be used to
1238 define new macros in Parenscript code. Note that macros defined
1239 this way are defined in a null lexical environment (ex
1240 - <code>(let ((x 1)) (defmacro baz (y) `(+ ,y ,x)))</code> will
1241 not work), since the surrounding Parenscript code is just
1242 translated to JavaScript and not actually evaluated.</p>
1244 <p><code>DEFPSMACRO</code> is a Lisp form (not a Parenscript one!)
1245 that can be used by Lisp code to define Parenscript macros without
1246 calling the Parenscript compiler.</p>
1248 <p>The representation of Parenscript macro functions is the same
1249 as that of Common Lisp, and in fact Parenscript can use already
1250 defined macros this way.
1252 <p><code>DEFMACRO+PS</code> defines two macros with the same name
1253 and expansion, one in Parenscript and one in
1254 Lisp. <code>DEFMACRO+PS</code> is used when the full macroexpansion of
1255 the Lisp macro yields code that cannot be used by Parenscript.</p>
1257 <p>Parenscript also supports the use of macros defined in the
1258 underlying Lisp environment. Existing Lisp macros can be imported into
1259 the Parenscript macro environment
1260 by <code>IMPORT-MACROS-FROM-LISP</code>. This functionality enables
1261 code sharing between Parenscript and Lisp, and is useful in debugging
1262 since the full power of Lisp macroexpanders, editors and other
1263 supporting facilities can be used. However, it is important to note
1264 that the macroexpansion of Lisp macros and Parenscript macros takes
1265 place in their own respective environments, and many Lisp macros
1266 (especially those provided by the Lisp implementation) expand into
1267 code that is not usable by Parenscript. To make it easy for users to
1268 take advantage of these features, two additional macro definition
1269 facilities are provided by Parenscript: </p>
1271 <h3 id="ssection-symbol-macros">Symbol macros</h3>
1272 (<code id="define-ps-symbol-macro">DEFINE-PS-SYMBOL-MACRO</code> symbol expansion)
1273 (<code id="symbol-macrolet">SYMBOL-MACROLET</code> ({name macro-body}*) body)
1275 <p>Symbol macros can be introduced using <code>SYMBOL-MACROLET</code>
1276 or defined in Lisp with <code>DEFINE-PS-SYMBOL-MACRO</code>. For
1277 example, the Parenscript
1278 <code>WITH-SLOTS</code> is implemented using symbol macros:</p>
1280 <pre><code>
1281 (defpsmacro with-slots (slots object &rest body)
1282 `(symbol-macrolet ,(mapcar #'(lambda (slot)
1283 `(,slot '(getprop ,object ',slot)))
1284 slots)
1285 ,@body))
1286 </code></pre>
1288 <h3 id="ssection-gensym">Gensym</h3>
1289 <ul>
1290 <li>(<code id="ps-gensym">PS-GENSYM</code> {string})</li>
1291 <li>(<code id="with-ps-gensyms">WITH-PS-GENSYMS</code> symbols &body body)</li>
1292 <li>(<code id="ps-once-only">PS-ONCE-ONLY</code> (&rest vars) &body body)</li>
1294 <li><code id="*ps-gensym-counter*">*PS-GENSYM-COUNTER*</code></li>
1295 </ul>
1297 <p>JavaScript identifier equality is based on string
1298 representations, as opposed to Common Lisp, where two uninterned
1299 symbols with the same name are different objects. Therefore
1300 Parenscript <code>GENSYM</code> depends
1301 on <code>*PS-GENSYM-COUNTER*</code> values only for generating
1302 unique identifiers. <code>*PS-GENSYM-COUNTER*</code> does not
1303 persist and is not guaranteed to be thread-safe, so care should be
1304 taken to avoid writing code where gensymed identifiers may clash
1305 (for example, this could happen if you concatenate JS code from PS
1306 compilers running in two different Lisp images, where the values
1307 of <code>*PS-GENSYM-COUNTER*</code> overlap).
1309 <h2 id="section-utilities">Utilities</h2>
1311 <h3 id="ssection-dom">DOM</h3>
1312 <ul>
1313 <li>(<code>INNER-HTML</code> el)</li>
1314 <li>(<code>URI-ENCODE</code> el)</li>
1315 <li>(<code>ATTRIBUTE</code> el)</li>
1316 <li>(<code>OFFSET</code> compass el)</li>
1317 <li>(<code>SCROLL</code> compass el)</li>
1318 <li>(<code>INNER</code> wh el)</li>
1319 <li>(<code>CLIENT</code> wh el)</li>
1320 </ul>
1322 <dl>
1323 <dt>el</dt> <dd>an expression that yields a DOM element</dd>
1324 <dt>compass</dt> <dd>one of <code>:TOP, :LEFT, :HEIGHT, :WIDTH, :BOTTOM, :RIGHT</code></dd>
1325 <dt>wh</dt> <dd>one of <code>:WIDTH, :HEIGHT</code></dd>
1326 </dl>
1328 <h3 id="ssection-html-gen">HTML generation</h3>
1329 <ul>
1330 <li>(<code id="ps-html">PS-HTML</code> html-expression)</li>
1331 <li>(<code id="who-ps-html">WHO-PS-HTML</code> html-expression)</li>
1332 <li><code id="*ps-html-empty-tag-aware-p*">*PS-HTML-EMPTY-TAG-AWARE-P*</code></li>
1333 <li><code id="*ps-html-mode*">*PS-HTML-MODE*</code></li>
1334 </ul>
1336 <p>Parenscript comes with two HTML markup generation facilities
1337 that produce Parenscript code - <code>PS-HTML</code>
1338 and <code>WHO-PS-HTML</code>. The former
1339 accepts <a href="http://opensource.franz.com/aserve/htmlgen.html">LHTML</a>
1340 style markup, while the latter
1341 accepts <a href="http://weitz.de/cl-who/">CL-WHO</a> style
1342 markup.</p>
1344 <p><code>*PS-HTML-EMPTY-TAG-AWARE-P*</code>
1345 and <code>*PS-HTML-MODE*</code> control how tags are closed when an
1346 HTML element has no
1347 content. When <code>*PS-HTML-EMPTY-TAG-AWARE-P*</code> is nil, all
1348 tags are fully closed (ex - <code>:BR</code> is translated
1349 as <code>&lt;BR&gt;&lt;/BR&gt;</code>). When <code>*PS-HTML-EMPTY-TAG-AWARE-P*</code>
1350 has a non-nil value and <code>*PS-HTML-MODE*</code>
1351 is <code>:SGML</code>, tags such as <code>BR</code> are output without
1352 being closed; when <code>*PS-HTML-MODE*</code> is <code>:XML</code>,
1353 the XML-style closing tags are used (ex - <code>:BR</code> is
1354 translated as <code>&lt;BR /&gt;</code>).</p>
1356 <dl>
1357 <dt><code>(ps-html ((:a :href "foobar") "blorg"))</code></dt>
1358 <dd><code>'&lt;A HREF=\"foobar\"&gt;blorg&lt;/A&gt;';</code></dd>
1360 <dt><code>(who-ps-html (:a :href (generate-a-link) "blorg"))</code></dt>
1361 <dd><code>'&lt;A HREF=\"' + generateALink() + '\"&gt;blorg&lt;/A&gt;';</code></dd>
1362 </dl>
1364 <p>The Parenscript compiler can be recursively called in an HTML
1365 expression:</p>
1367 <dl>
1368 <dt><code>
1369 <pre>((@ document write)
1370 (ps-html ((:a :href "#"
1371 :onclick (ps-inline (transport))) "link")))</pre>
1372 </code>
1373 </dt>
1374 <dd><code>document.write('&lt;A HREF=\"#\" ONCLICK=\"' + ('javascript:' + 'transport()') + '\"&gt;link&lt;/A&gt;');</code></dd>
1375 </dl>
1377 <p>Forms may be used in attribute lists to conditionally generate
1378 the next attribute. In this example the textarea is sometimes
1379 disabled.</p>
1381 <dl>
1382 <dt><code>
1383 <pre>(let ((disabled nil)
1384 (authorized t))
1385 (setf (@ element inner-h-t-m-l)
1386 (ps-html ((:textarea (or disabled (not authorized)) :disabled "disabled")
1387 "Edit me"))))</pre>
1388 </code>
1389 </dt>
1391 <dd><code>
1392 <pre>var disabled = null;
1393 var authorized = true;
1394 element.innerHTML =
1395 '&lt;TEXTAREA'
1396 + (disabled || !authorized ? ' DISABLED=\"' + 'disabled' + '\"' : '')
1397 + '&gt;Edit me&lt;/TEXTAREA&gt;';</pre>
1398 </code>
1399 </dd>
1400 </dl>
1402 <h2 id="section-runtime-library">Runtime library</h2>
1403 <ul>
1404 <li>(<code id="">MEMBER</code> object array)</li>
1405 <li>(<code id="">MAP</code> function array)</li>
1406 <li>(<code id="">MAPCAR</code> function {array}*)</li>
1407 <li>(<code id="">REDUCE</code> function array object)</li>
1408 <li>(<code id="">MAP-INTO</code> function array)</li>
1409 <li>(<code id="">SET-DIFFERENCE</code> array1 array2)</li>
1410 <li><code id="*ps-lisp-library*">*PS-LISP-LIBRARY*</code></li>
1411 </ul>
1413 <p>All the Parenscript constructs presented so far have been free
1414 of any runtime dependencies. Parenscript also comes with a library
1415 of useful predefined functions that can be added to your
1416 project. These functions are kept as Parenscript code in
1417 the <code>*PS-LISP-LIBRARY*</code> special variable.</p>
1419 <p><code>MAP</code> differs from its Common Lisp counterpart by
1420 virtue of being a <code>MAPCAR</code> that only accepts a single
1421 sequence to map over. <code>MAP-UNTIL</code> is
1422 like <code>MAP</code> but replaces the contents of the given
1423 array in-place.</p>
1425 <h2 id="section-slime-integration">SLIME integration</h2>
1427 <p>The <code>extras</code> folder in the Parenscript distribution
1428 contains <code>js-expander.el</code>, which when loaded in Emacs
1429 with SLIME adds the ability to quickly see the translation of
1430 any Lisp form in JavaScript, and works much like the Slime '<code>C-c
1431 M-m</code>' macroexpansion feature.</p>
1433 <p>'<code>C-c j</code>' (<a href="#ps"><code>PS</code></a>) or
1434 '<code>C-c d</code>' (<a href="#ps-doc"><code>PS-DOC</code></a>)
1435 at a ParenScript expression in a <code>slime-mode</code> buffer
1436 will bring up a buffer with the resulting Javascript code. Note
1437 that the extension does not work
1438 in <code>slime-repl-mode</code>, which is intentional.</p>
1440 <p><tt>extras/swank-parenscript.lisp</tt> shows how to add support
1441 to SLIME for printing hints about Parenscript-defined macro and
1442 function argument lists to the Emacs minibuffer, like SLIME
1443 already does for Common Lisp functions and macros.</p>
1445 <p style="font-size:xxx-small"><i>Last modified: 2012-09-22</i></p>
1446 </body>
1447 </html>