Fixed two broken anchor links in the reference manual
[parenscript.git] / docs / reference.html
blobf4031cabde4e9d572124b74a64617b4602e41238
1 <!DOCTYPE html>
3 <html lang="en">
5 <head>
6 <meta charset="utf-8">
7 <meta name="viewport"
8 content="width=device-width, initial-scale=1"
11 <title>Parenscript Reference Manual</title>
13 <style type="text/css">
14 body {
15 max-width: 70ex;
16 margin: auto;
18 dl {
19 margin-left: 2em;
21 dt {
22 margin-top: 0.5ex;
23 border: 1px solid #d5d5d5;
24 background: #f9f9f9;
26 dd {
27 margin-top: 0.5ex;
29 p {
30 margin-left: 1em;
32 pre {
33 margin: 0;
35 samp {
36 color: #60a;
37 font-weight: bolder;
39 </style>
40 </head>
42 <body>
43 <h1 style="text-align:center;">Parenscript Reference Manual</h1>
45 <p>
46 Copyright 2005 Marco Baringer.<br/>
47 Copyright 2006 Henrik Hjelte.<br/>
48 Copyright 2009-2012, 2018 Vladimir Sedach.<br/>
50 Permission is granted to copy, distribute and/or modify this
51 document under the terms of the GNU Free Documentation License,
52 Version 1.3 or any later version published by the Free Software
53 Foundation; with no Invariant Sections, no Front-Cover Texts,
54 and no Back-Cover Texts. A copy of the license can be
55 found <a href="https://www.gnu.org/licenses/fdl.html">on the
56 GNU website</a>.
57 </p>
59 <h2>Table of Contents</h2>
61 <ol>
62 <li><a href="#section-notation">Notation used in this manual</a></li>
63 <li><a href="#section-ps-compiler">The Parenscript compiler</a></li>
64 <li><a href="#section-symbolconv">Symbol conversion</a></li>
65 <li><a href="#section-namespace">The Parenscript namespace system</a>
66 <ul>
67 <li><a href="#section-obfuscation">Identifier obfuscation</a></li>
68 <li><a href="#section-minification">Minification</a></li>
69 </ul>
70 </li>
71 <li><a href="#reserved-symbols">Reserved symbols</a></li>
72 <li><a href="#section-statements-expressions">Statements, expressions, and return</a></li>
73 <li><a href="#section-types">Types and type predicates</a></li>
74 <li><a href="#section-literals">Literals</a>
75 <ul>
76 <li><a href="#ssection-numbers">Numbers</a></li>
77 <li><a href="#ssection-strings-chars">Strings and characters</a></li>
78 <li><a href="#ssection-regex">Regular expressions</a></li>
79 <li><a href="#ssection-booleans">Booleans and undefined</a></li>
80 </ul>
81 </li>
82 <li><a href="#section-objects">Objects</a></li>
83 <li><a href="#section-arrays">Arrays</a></li>
84 <li><a href="#section-arithmetic">Arithmetic and boolean operators</a></li>
85 <li><a href="#section-math">Mathematical functions and constants</a></li>
86 <li><a href="#section-blocks">Blocks</a></li>
87 <li><a href="#section-functions">Functions and multiple values</a></li>
88 <li><a href="#section-control-transfer">Control transfer and exceptions</a></li>
89 <li><a href="#section-conditionals">Conditionals</a></li>
90 <li><a href="#section-variables">Variable binding and declaration</a></li>
91 <li><a href="#section-assignment">Assignment</a></li>
92 <li><a href="#section-iteration">Iteration</a></li>
93 <li><a href="#section-macros">Macros</a>
94 <ul>
95 <li><a href="#ssection-defining-macros">Defining macros</a></li>
96 <li><a href="#ssection-symbol-macros">Symbol macros</a></li>
97 <li><a href="#ssection-gensym">Gensym</a></li>
98 </ul>
99 </li>
100 <li><a href="#section-utilities">Utilities</a>
101 <ul>
102 <li><a href="#ssection-dom">DOM</a></li>
103 <li><a href="#ssection-html-gen">HTML generation</a></li>
104 </ul>
105 </li>
106 <li><a href="#section-runtime-library">Run-time library</a></li>
107 <li><a href="#section-slime-integration">SLIME integration</a></li>
108 </ol>
110 <h2 id="section-notation">Notation used in this manual</h2>
111 <ul>
112 <li><code>Lisp form</code></li>
113 <li><var>Lisp variable</var></li>
114 <li>(<code>lisp-function-name</code> <var>lisp-function-argument</var>)</li>
115 <li><samp>JavaScript code</samp></li>
116 <li><dl><dt>Term</dt><dd>Definition of term</dd></dl></li>
117 <li><dl><dt><code>(Lisp forms)</code></dt><dd><samp>Lisp forms compiled to JavaScript;</samp></dd></dl></li>
118 </ul>
120 <h2 id="section-ps-compiler">The Parenscript compiler</h2>
122 <ul>
123 <li>(<code id="ps">PS</code> &amp;body <var>body</var>)</li>
124 <li>(<code id="ps-to-stream">PS-TO-STREAM</code> <var>stream</var> &amp;body <var>body</var>)</li>
125 <li>(<code id="ps*">PS*</code> &amp;rest <var>body</var>)</li>
126 <li>(<code id="ps-doc">PS-DOC</code> &amp;body <var>body</var>)</li>
127 <li>(<code id="ps-doc*">PS-DOC*</code> &amp;body <var>body</var>)</li>
128 <li>(<code id="ps-inline">PS-INLINE</code> <var>form</var> &amp;optional <var>*JS-STRING-DELIMITER*</var>)</li>
129 <li>(<code id="ps-inline*">PS-INLINE*</code> <var>form</var> &amp;optional <var>*JS-STRING-DELIMITER*</var>)</li>
130 <li>(<code id="ps-compile-stream">PS-COMPILE-STREAM</code> <var>stream</var>)</li>
131 <li>(<code id="ps-compile-file">PS-COMPILE-FILE</code> <var>file</var>)</li>
132 <li>(<code id="lisp">LISP</code> <var>lisp-form</var>)</li>
133 <li>(<code id="symbol-to-js-string">SYMBOL-TO-JS-STRING</code> <var>symbol</var>)</li>
135 <li><var id="*js-target-version*">*JS-TARGET-VERSION*</var></li>
136 <li><var id="*parenscript-stream*">*PARENSCRIPT-STREAM*</var></li>
137 <li><var id="*js-string-delimiter*">*JS-STRING-DELIMITER*</var></li>
138 <li><var id="*js-inline-string-delimiter*">*JS-INLINE-STRING-DELIMITER*</var></li>
139 <li><var id="*ps-read-function*">*PS-READ-FUNCTION*</var></li>
140 <li><var id="*version*">*VERSION*</var></li>
141 <li><var id="*defined-operators*">*DEFINED-OPERATORS*</var></li>
142 </ul>
144 <dl>
145 <dt><var>body</var></dt> <dd>implicit <code>PROGN</code></dd>
146 </dl>
148 <p>The difference between the regular and <code>*</code> versions
149 of the Parenscript compiler forms is roughly the difference
150 between <code>COMPILE</code>
151 and <code>EVAL</code>. The <code>*</code> forms are functions
152 that do all compilation when they are evaluated, while the
153 regular forms are macros that do almost all (except for the use
154 of the <code>LISP</code> special form, see below) compilation at
155 macro-expansion time.</p>
157 <p><code>PS</code> and <code>PS*</code> are the main interfaces to
158 the Parenscript compiler. They come with <code>PS-DOC</code>
159 and <code>PS-DOC*</code> counterparts which compile the given
160 code
161 with <a href="#*ps-gensym-counter*"><var>*PS-GENSYM-COUNTER*</var></a>
162 bound to <kbd>0</kbd>, and are useful for writing automated
163 tests.</p>
165 <p>By default, Parenscript writes output to a string. You can
166 output directly to a stream in one of two ways: either by
167 using <code>PS-TO-STREAM</code> instead of <code>PS</code>, or by
168 binding <var>*PARENSCRIPT-STREAM*</var> before
169 calling <code>PS*</code>.</p>
171 <p><code>PS-INLINE</code> and <code>PS-INLINE*</code> take a single
172 Parenscript form and output a string starting
173 with <samp>javascript:</samp> that can be used in HTML node
174 attributes. As well, they provide an argument to bind the value of
175 <var>*JS-STRING-DELIMITER*</var> to control the value of the
176 JavaScript string escape character to be compatible with
177 whatever the HTML generation mechanism is used (for example, if
178 HTML strings are delimited using <code>#\'</code>,
179 using <code>#\&quot;</code> will avoid conflicts without
180 requiring the output JavaScript code to be escaped). By default
181 the value is taken
182 from <var>*JS-INLINE-STRING-DELIMITER*</var>.</p>
184 <p>Parenscript code can be compiled from a stream or file
185 via <code>PS-COMPILE-STREAM</code>
186 and <code>PS-COMPILE-FILE</code>, respectively. The special
187 variable <var>*PS-READ-FUNCTION*</var> is bound to the function
188 used to read the forms from the file/stream (<code>READ</code> by
189 default), and can be used to provide completely customizable
190 syntax for Parenscript files.</p>
192 <p>Parenscript can also call out to arbitrary Common Lisp code at
193 <em>output time</em> (that is, every time an expression containing
194 a call to the Parenscript compiler is evaluated, compared
195 to <em>compile time</em>, where the effect is accomplished using
196 macros) using the special form <code>LISP</code>. The form
197 provided to <code>LISP</code> is evaluated, and its result is
198 compiled as though it were Parenscript code. For <code>PS</code>
199 and <code>PS-INLINE</code>, the Parenscript output code is
200 generated at macro-expansion time, and the <code>LISP</code>
201 statements are inserted inline into the output and have access
202 to the enclosing Common Lisp lexical
203 environment. <code>PS*</code> and <code>PS1*</code> evaluate the
204 <code>LISP</code> forms using <code>EVAL</code>, providing them
205 access to the current dynamic environment only
206 (using <code>LISP</code> when calling the <code>*</code> forms
207 is not strictly necessary, as the values can be inserted inline
208 into code).</p>
210 <p><var>*JS-TARGET-VERSION*</var> (<kbd>"1.3"</kbd> by default)
211 controls which version of JavaScript that Parenscript
212 targets. For newer versions of JS, some Parenscript special
213 forms may compile to more concise and/or efficient expressions
214 that are not present in earlier versions of JavaScript.</p>
216 <p><code>SYMBOL-TO-JS-STRING</code> is the Parenscript function
217 responsible for translating Common Lisp symbols to JavaScript
218 identifiers (see the section
219 on <a href="#section-symbolconv">symbol conversion</a> for the
220 translation rules). It is helpful for writing libraries or other
221 pieces of code that will interface with Parenscript-generated
222 JavaScript.</p>
224 <p>Newer versions of Parenscript may implement Common Lisp special
225 forms, functions or macros that were left unimplemented by earlier
226 versions. This can cause problems if your code provides
227 implementations for those forms itself. To help deal with
228 this, <var>*DEFINED-OPERATORS*</var> provides a list of special
229 forms, macros, and symbol macros defined by Parenscript
230 itself. <var>*VERSION*</var> is bound to the current release
231 version number of Parenscript.</p>
233 <h2 id="section-symbolconv">Symbol conversion</h2>
235 <p>Parenscript supports output for both case-sensitive and
236 case-insensitive symbols. By default the Lisp reader up-cases all
237 symbols. By setting <code>readtable-case</code>
238 to <a href="http://www.lispworks.com/documentation/lw50/CLHS/Body/23_ab.htm"><code>:invert</code></a>
239 (you can use
240 the <a href="https://common-lisp.net/project/named-readtables/">named-readtables</a>
241 library to make this more convenient) symbol case is preserved,
242 and Parenscript will output mixed-case symbols
243 (like <samp>encodeURIComponent</samp>) correctly.</p>
245 <p>Lisp symbols (other than keywords) that are all uppercase or
246 contain special characters are converted to JavaScript
247 identifiers by following a few simple rules. Special
248 characters <code>!, ?, #, @, %, /, *</code> and <code>+</code>
249 get replaced by their written-out equivalents "bang", "what",
250 "hash", "at", "percent", "slash", "start" and "plus"
251 respectively. The <code>$</code> character is untouched.</p>
253 <dl>
254 <dt><code>!?#@%</code></dt>
255 <dd><samp>bangwhathashatpercent;</samp></dd>
256 </dl>
258 <p>The <code>-</code> is an indication that the following
259 character should be converted to uppercase.</p>
261 <dl>
262 <dt><code>bla-foo-bar</code></dt>
263 <dd><samp>blaFooBar;</samp></dd>
264 </dl>
266 <p>JavaScript identifiers that begin with an uppercase letter can
267 be obtained with a leading <code>-</code> or <code>*</code>.</p>
269 <dl>
270 <dt><code>*array</code></dt>
271 <dd><samp>Array;</samp></dd>
272 </dl>
274 <p>A symbol starting and ending with <code>+</code>
275 or <code>*</code> is converted to all uppercase, to signify that
276 this is a constant or a global variable.</p>
278 <dl>
279 <dt><code>*global-array*</code></dt>
280 <dd><samp>GLOBALARRAY;</samp></dd>
281 </dl>
283 <p>Keywords are not translated to JavaScript identifiers, but are
284 printed in lower case without any character substitution as
285 strings. This is done because strings are the closest equivalent
286 to Common Lisp keywords (being self-evaluating objects in
287 JavaScript), and to permit keywords to be used for identifying
288 various symbols (for example, as tokens in a parser).</p>
290 <dl>
291 <dt><code>:+</code></dt>
292 <dd><samp>'+';</samp></dd>
294 <dt><code>:foo-Bar</code></dt>
295 <dd><samp>'foo-bar';</samp></dd>
296 </dl>
298 <h2 id="section-namespace">The Parenscript namespace system</h2>
299 <ul>
300 <li>
301 (<code id="in-package">in-package</code> <var>package-designator</var>)
302 </li>
303 <li>
304 (<code id="use-package">use-package</code> <var>package-designator</var>)
305 </li>
306 <li>
307 (setf (<code id="ps-package-prefix">PS-PACKAGE-PREFIX</code> <var>package-designator</var>) <var>string</var>)
308 </li>
309 </ul>
312 Although JavaScript does not offer namespacing or a package
313 system, Parenscript does provide a namespace mechanism for
314 generated JavaScript by integrating with the Common Lisp package
315 system. Since Parenscript code is normally read in by the Lisp
316 reader, all symbols (except for uninterned ones, i.e. - those
317 specified with the <code>#:</code> reader macro) have a Lisp
318 package. By default, no packages are prefixed. You can specify
319 that symbols in a particular package receive a prefix when
320 translated to JavaScript with the
321 <var>PS-PACKAGE-PREFIX</var> place.
322 </p>
324 <dl>
325 <dt>
326 <pre><code>(defpackage "PS-REF.MY-LIBRARY"
327 (:use "PARENSCRIPT"))
329 (setf (ps-package-prefix "PS-REF.MY-LIBRARY") "my_library_")
331 (ps (defun ps-ref.my-library::library-function (x y)
332 (+ x y)))</code></pre>
333 </dt>
335 <dd>
336 <pre><samp>function my_library_libraryFunction(x, y) {
337 return x + y;
338 };</samp></pre>
339 </dd>
340 </dl>
343 Parenscript provides <code>IN-PACKAGE</code>
344 and <code>USE-PACKAGE</code> special forms, primarily useful
345 with <a href="#ps-compile-file"><code>PS-COMPILE-FILE</code></a>
346 and <a href="#ps-compile-stream"><code>PS-COMPILE-STREAM</code></a>.
347 </p>
349 <h3 id="section-obfuscation">Identifier obfuscation</h3>
350 <ul>
351 <li>
352 (<code id="obfuscate-package">OBFUSCATE-PACKAGE</code> <var>package-designator</var> &amp;optional <var>symbol-map</var>)
353 </li>
354 <li>
355 (<code id="unobfuscate-package">UNOBFUSCATE-PACKAGE</code> <var>package-designator</var>)
356 </li>
357 </ul>
359 <p>Similar to the namespace mechanism, Parenscript provides a
360 facility to generate obfuscated identifiers in specified CL
361 packages. The function <code>OBFUSCATE-PACKAGE</code> may
362 optionally be passed a closure that maps symbols to their
363 obfuscated counterparts. By default, the mapping is done
364 using <code><a href="#ps-gensym">PS-GENSYM</a></code>.</p>
366 <dl>
367 <dt>
368 <pre><code>(defpackage "PS-REF.OBFUSCATE-ME")
370 (obfuscate-package "PS-REF.OBFUSCATE-ME"
371 (let ((code-pt-counter #x8CF6)
372 (symbol-map (make-hash-table)))
373 (lambda (symbol)
374 (or (gethash symbol symbol-map)
375 (setf (gethash symbol symbol-map)
376 (make-symbol (string (code-char (incf code-pt-counter)))))))))
378 (defun ps-ref.obfuscate-me::a-function (a b ps-ref.obfuscate-me::foo)
379 (+ a (ps-ref.my-library::library-function b ps-ref.obfuscate-me::foo)))</code></pre>
380 </dt>
382 <dd>
383 <pre><samp>function 賷(a, b, 賸) {
384 return a + libraryFunction(b, 賸);
385 };</samp></pre>
386 </dd>
387 </dl>
389 <p>The obfuscation and namespace facilities can be used on packages
390 at the same time.</p>
392 <p>Since Parenscript doesn't know anything about the DOM or other
393 JavaScript libraries, library function and property names might be
394 inadvertently obfuscated. To help prevent that, Parenscript comes
395 with
396 the <code>ps-dom1-symbols</code>, <code>ps-dom2-symbols</code>, <code>ps-window-wd-symbols</code>, <code>ps-dom-nonstandard-symbols</code>
397 and <code>ps-dhtml-symbols</code> symbol packages that define
398 various DOM property and function identifiers as exported symbols
399 (in both case-sensitive and insensitive variants), which you can
400 import into your packages to help prevent symbols
401 like <code>pageXOffset</code> from being
402 obfuscated. The <code>ps-dhtml-symbols</code> package contains the
403 broadest range of symbols and is most generally useful.</p>
405 <p>If you use obfuscation and external JavaScript libraries, you
406 can use the same technique to define your own packages with
407 symbols that will not be obfuscated.</p>
409 <h3 id="section-minification">Minification</h3>
410 <ul>
411 <li><var id="*ps-print-pretty*">*PS-PRINT-PRETTY*</var></li>
412 <li><var id="*indent-num-spaces*">*INDENT-NUM-SPACES*</var></li>
413 </ul>
415 <p><var>*PS-PRINT-PRETTY*</var> and <var>*INDENT-NUM-SPACES*</var>
416 control whether the resulting JavaScript code is pretty-printed,
417 and if so, how many spaces go into each indent level,
418 respectively. By default the code is pretty-printed
419 with <kbd>4</kbd> spaces per indent level.</p>
421 <p>Setting <var>*PS-PRINT-PRETTY*</var> to nil and turning
422 on <a href="#section-obfuscation">obfuscation</a> will minify the
423 generated JavaScript code.</p>
425 <h2 id="reserved-symbols">Reserved symbols</h2>
427 <p>The following symbols are reserved in Parenscript, and should not
428 be used as variable names.</p>
430 <code>
431 ! ~ ++ -- * / % + - &lt;&lt; &gt;&gt; &gt;&gt;&gt; &lt; &gt;
432 &lt;= &gt;= == != === !== & ^ | && || *= /= %= += -= &lt;&lt;=
433 &gt;&gt;= &gt;&gt;&gt;= &= ^= |= 1- 1+ @ ABSTRACT AND AREF ARRAY
434 BOOLEAN BREAK BYTE CASE CATCH CHAR CLASS COMMA CONST CONTINUE
435 CREATE DEBUGGER DECF DEFAULT DEFUN DEFVAR DELETE DO DO* DOEACH
436 DOLIST DOTIMES DOUBLE ELSE ENUM EQL EXPORT EXTENDS F FALSE FINAL
437 FINALLY FLOAT FLOOR FOR FOR-IN FUNCTION GOTO IF IMPLEMENTS
438 IMPORT IN INCF INSTANCEOF INT INTERFACE JS LABELED-FOR LAMBDA
439 LET LET* LISP LIST LONG MAKE-ARRAY NATIVE NEW NIL NOT OR PACKAGE
440 PRIVATE PROGN PROTECTED PUBLIC RANDOM REGEX RETURN SETF SHORT
441 GETPROP STATIC SUPER SWITCH SYMBOL-MACROLET SYNCHRONIZED T THIS
442 THROW THROWS TRANSIENT TRY TYPEOF UNDEFINED UNLESS VAR VOID
443 VOLATILE WHEN WHILE WITH WITH-SLOTS
444 </code>
446 <h2 id="section-statements-expressions">Statements, expressions, and return</h2>
449 In contrast to Lisp, where everything is an expression,
450 JavaScript makes an arbitrary distinction between expressions,
451 which yield a value and can be nested in other expressions, and
452 statements, which have no value and cannot occur in expressions.
453 </p>
456 Some Parenscript special forms compile to expressions, while
457 others can only compile to statements. Certain Parenscript
458 forms, like <code>IF</code> and <code>PROGN</code>, generate
459 different JavaScript depending on if they are used in an
460 expression context or a statement context. In such cases,
461 Parenscript tries to generate statement code if possible to
462 increase readability, only falling back to the expression code
463 if it is necessary.
464 </p>
466 <dl>
467 <dt>
468 <code>(+ i (if x (foo) (bar)))</code>
469 </dt>
471 <dd>
472 <samp>i + (x ? foo() : bar());</samp>
473 </dd>
475 <dt>
476 <code>(if x (foo) (bar))</code>
477 </dt>
479 <dd>
480 <pre><samp>if (x) {
481 foo();
482 } else {
483 bar();
484 };</samp></pre>
485 </dd>
486 </dl>
489 One important feature found in Lisp but absent from JavaScript
490 is implicit return from functions. Parenscript automatically
491 provides implicit return for JavaScript statements and
492 expressions:
493 </p>
495 <dl>
496 <dt>
497 <pre><code>(defun foo (x)
498 (1+ x))</code></pre>
499 </dt>
501 <dd>
502 <pre><samp>function foo(x) {
503 return x + 1;
504 };</samp></pre>
505 </dd>
507 <dt>
508 <pre><code>(lambda (x)
509 (case x
510 (1 (loop repeat 3 do (alert "foo")))
511 (:bar (alert "bar"))
512 (otherwise 4)))</code></pre>
513 </dt>
515 <dd>
516 <pre><samp>function (x) {
517 switch (x) {
518 case 1:
519 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
520 alert('foo');
522 return null;
523 case 'bar':
524 return alert('bar');
525 default:
526 return 4;
528 };</samp></pre>
529 </dd>
530 </dl>
533 Parenscript generates code that works around the JavaScript
534 expression-statement dichotomy in an unobtrusive way:
535 </p>
537 <dl>
538 <dt>
539 <pre><code>(+ 1 (dotimes (x 3) (if (= x 2) (return (+ x x)))))</code></pre>
540 </dt>
542 <dd>
543 <pre><samp>(function () {
544 for (var x = 0; x < 3; x += 1) {
545 if (x === 2) {
546 return x + x;
549 })() + 1;</samp></pre>
550 </dd>
551 </dl>
553 <h2 id="section-types">Types and type predicates</h2>
554 <ul>
555 <li>(<code id="typeof">TYPEOF</code> <var>object</var>)</li>
556 <li>(<code id="instanceof">INSTANCEOF</code> <var>object</var> <var>type</var>)</li>
557 <li>(<code id="null">NULL</code> <var>object</var>)</li>
558 <li>(<code id="undefined_1">UNDEFINED</code> <var>object</var>)</li>
559 <li>(<code id="defined">DEFINED</code> <var>object</var>)</li>
560 <li>(<code id="stringp">STRINGP</code> <var>object</var>)</li>
561 <li>(<code id="numberp">NUMBERP</code> <var>object</var>)</li>
562 <li>(<code id="functionp">FUNCTIONP</code> <var>object</var>)</li>
563 <li>(<code id="objectp">OBJECTP</code> <var>object</var>)</li>
564 </ul>
566 <dl>
567 <dt><var>object</var></dt> <dd>an expression yielding an object</dd>
568 <dt><var>type</var></dt> <dd>a type designator</dd>
569 </dl>
571 <p>Parenscript is based around the JavaScript type system, and
572 does not introduce any new types or objects, nor does it attempt
573 to provide a Common Lisp-like interface to the type system.</p>
575 <h2 id="section-literals">Literals</h2>
577 <h3 id="ssection-numbers">Numbers</h3>
579 <p>Parenscript prints all integer literals as integers, and floats
580 and rationals as floats, in base 10.</p>
582 <dl>
583 <dt><code>1</code></dt>
584 <dd><samp>1;</samp></dd>
586 <dt><code>123.123</code></dt>
587 <dd><samp>123.123;</samp></dd>
589 <dt><code>3/4</code></dt>
590 <dd><samp>0.75;</samp></dd>
592 <dt><code>#x10</code></dt>
593 <dd><samp>16;</samp></dd>
594 </dl>
596 <h3 id="ssection-strings-chars">Strings and characters</h3>
598 <p>Lisp strings are converted to JavaScript strings.</p>
600 <dl>
601 <dt><code>"foobar"</code></dt>
602 <dd><samp>'foobar';</samp></dd>
603 </dl>
605 <p>Parenscript makes no effort to interpolate C-style escape
606 strings. Rather, non-printable characters in Lisp strings are
607 output using escape sequences:</p>
609 <dl>
610 <dt><code>#\Tab</code></dt>
611 <dd><samp>'\t';</samp></dd>
613 <dt><code>"\\n"</code></dt>
614 <dd><samp>'\\n';</samp></dd>
615 </dl>
617 <h3 id="ssection-regex">Regular expressions</h3>
618 <ul>
619 <li>(<code id="regex">REGEX</code> <var>regex</var>)</li>
620 </ul>
622 <dl>
623 <dt><var>regex</var></dt> <dd>a string</dd>
624 </dl>
626 <p>Regular expressions can be created by using
627 the <code>REGEX</code> form. If the argument does not start with
628 <code>/</code>, it is surrounded by <code>/</code>, otherwise it
629 is left as it is.</p>
631 <dl>
632 <dt><code>(regex "foobar")</code></dt>
633 <dd><samp>/foobar/;</samp></dd>
635 <dt><code>(regex "/foobar/i")</code></dt>
636 <dd><samp>/foobar/i;</samp></dd>
637 </dl>
639 <p><a href="https://edicl.github.io/cl-interpol/">CL-INTERPOL</a> is
640 convenient for writing regular expressions:</p>
642 <dl>
643 <dt><code>(regex #?r"/([^\s]+)foobar/i")</code></dt>
644 <dd><samp>/([^\s]+)foobar/i;</samp></dd>
645 </dl>
647 <h3 id="ssection-booleans">Booleans and undefined</h3>
648 <ul>
649 <li><code id="t">T</code></li>
650 <li><code id="f">F</code></li>
651 <li><code id="false">FALSE</code></li>
652 <li><code id="nil">NIL</code></li>
653 <li><code id="undefined">UNDEFINED</code></li>
654 </ul>
656 <p><code>T</code> and <code>FALSE</code> (or <code>F</code>) are
657 converted to their JavaScript boolean
658 equivalents <samp>true</samp> and <samp>false</samp>.</p>
660 <p><code>NIL</code> is converted to the JavaScript keyword
661 <samp>null</samp>.</p>
663 <p><code>UNDEFINED</code> is converted to the JavaScript global
664 variable <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Properties/undefined"><samp>undefined</samp></a>.</p>
666 <h2 id="section-objects">Objects</h2>
667 <ul>
668 <li>(<code id="new">NEW</code> <var>constructor</var>)</li>
669 <li>(<code id="create">CREATE</code> {<var>name</var> <var>value</var>}*)</li>
670 <li>(<code id="getprop">GETPROP</code> <var>object</var> {<var>slot-specifier</var>}*)</li>
671 <li>(<code id="@">@</code> {<var>slot-specifier</var>}*)</li>
672 <li>(<code id="chain">CHAIN</code> {<var>slot-specifier</var> | <var>function-call</var>}*)</li>
673 <li>(<code id="with-slots">WITH-SLOTS</code> ({<var>slot-name</var>}*) <var>object</var> <var>body</var>)</li>
674 <li>(<code id="delete">DELETE</code> <var>object</var>)</li>
675 </ul>
677 <dl>
678 <dt><var>constructor</var></dt> <dd>a function call to an object constructor</dd>
679 <dt><var>name</var></dt> <dd>symbol, string or keyword</dd>
680 <dt><var>value</var></dt> <dd>an expression</dd>
681 <dt><var>object</var></dt> <dd>an expression yielding an object</dd>
682 <dt><var>slot-specifier</var></dt> <dd>a quoted symbol, a string, a number, or an expression yielding a string or number</dd>
683 <dt><var>body</var></dt> <dd>implicit <code>PROGN</code></dd>
684 </dl>
686 <p>The <code>NEW</code> operator maps to JavaScript like:</p>
688 <dl>
689 <dt><code>(new (-Person age shoe-size))</code></dt>
690 <dd><samp>new Person(age, shoeSize);</samp></dd>
691 </dl>
693 <p>Object literals are created
694 with <code>CREATE</code>. <code>CREATE</code> takes a property
695 list of property names and values.</p>
697 <dl>
698 <dt>
699 <code>(create foo "bar" :blorg 1)</code>
700 </dt>
702 <dd>
703 <samp>{ foo : 'bar', 'blorg' : 1 };</samp>
704 </dd>
706 <dt>
707 <pre><code>(create foo "hihi"
708 blorg (array 1 2 3)
709 another-object (create :schtrunz 1))</code></pre>
710 </dt>
712 <dd>
713 <pre><samp>{ foo : 'hihi',
714 blorg : [ 1, 2, 3 ],
715 anotherObject : { 'schtrunz' : 1 } };</samp></pre>
716 </dd>
717 </dl>
719 <p>Object properties can be accessed using
720 <code>GETPROP</code>, which takes an object and a list of
721 properties.</p>
723 <dl>
724 <dt><code>(getprop obj 'foo)</code></dt>
725 <dd><samp>obj.foo;</samp></dd>
727 <dt><code>(getprop obj foo)</code></dt>
728 <dd><samp>obj[foo];</samp></dd>
730 <dt><code>(getprop element i 'child-node 0 'node-value)</code></dt>
731 <dd><samp>element[i].childNode[0].nodeValue;</samp></dd>
732 </dl>
734 <p>The convenience macro <code>@</code> quotes all its given
735 symbol slot-specifiers to save typing:</p>
737 <dl>
738 <dt><code>(@ an-object foo bar)</code></dt>
739 <dd><samp>anObject.foo.bar;</samp></dd>
741 <dt><code>(@ foo bar child-node 0 node-value)</code></dt>
742 <dd><samp>foo.bar.childNode[0].nodeValue;</samp></dd>
743 </dl>
745 <p><code>CHAIN</code> can be used to conveniently chain together
746 accessors and function calls:</p>
748 <dl>
749 <dt><code>(chain foo (bar x y) 0 baz)</code></dt>
750 <dd><samp>foo.bar(x, y)[0].baz;</samp></dd>
751 </dl>
753 <p><code>WITH-SLOTS</code> can be used to bind the given
754 slot-names to a symbol macro that will expand into
755 a <code>GETPROP</code> form at expansion time:</p>
757 <dl>
758 <dt>
759 <pre><code>(with-slots (a b c) this
760 (+ a b c))</code></pre>
761 </dt>
763 <dd>
764 <samp>this.a + this.b + this.c;</samp>
765 </dd>
766 </dl>
768 <h2 id="section-arrays">Arrays</h2>
769 <ul>
770 <li>(<code id="array">ARRAY</code> {<var>value</var>}*)</li>
771 <li>(<code id="list">LIST</code> {<var>value</var>}*)</li>
772 <li>(<code id="[]">[]</code> {<var>value</var>}*)</li>
773 <li>(<code id="make-array">MAKE-ARRAY</code> {<var>value</var>}*)</li>
774 <li>(<code id="length">LENGTH</code> <var>array</var>)</li>
775 <li>(<code id="aref">AREF</code> <var>array</var> <var>index</var>)</li>
776 <li>(<code id="elt">ELT</code> <var>array</var> <var>index</var>)</li>
777 <li>(<code id="destructuring-bind">DESTRUCTURING-BIND</code> <var>bindings</var> <var>array</var> <var>body</var>)</li>
778 <li>(<code id="concatenate">CONCATENATE 'STRING</code> {<var>value</var>}*)</li>
779 <li>(<code id="append">APPEND</code> {<var>value</var>}*)</li>
780 </ul>
782 <dl>
783 <dt><var>value</var></dt> <dd>an expression</dd>
784 <dt><var>array</var></dt> <dd>an expression</dd>
785 <dt><var>index</var></dt> <dd>an expression</dd>
786 </dl>
788 <p>Array literals can be created using the <code>ARRAY</code>
789 or <code>LIST</code> forms.</p>
791 <dl>
792 <dt><code>(array)</code></dt>
793 <dd><samp>[];</samp></dd>
795 <dt><code>(array 1 2 3)</code></dt>
796 <dd><samp>[1, 2, 3];</samp></dd>
798 <dt><code>(list (foo) (bar) 3)</code></dt>
799 <dd><samp>[foo(), bar(), 3];</samp></dd>
801 <dt>
802 <pre><code>(array (array 2 3)
803 (array "foo" "bar"))</code></pre>
804 </dt>
806 <dd>
807 <samp>[[ 2, 3 ], ['foo', 'bar']];</samp>
808 </dd>
809 </dl>
811 <p>The <code>[]</code> macro treats list arguments as quoted,
812 making it easy to write nested array literals:</p>
814 <dl>
815 <dt><code>([] 1 2 (3 4) 5 6)</code></dt>
816 <dd><samp>[1, 2, [3, 4], 5, 6];</samp></dd>
817 </dl>
819 <p>Arrays can also be created with a call to the <code>Array</code>
820 function using <code>MAKE-ARRAY</code>.</p>
822 <dl>
823 <dt><code>(make-array)</code></dt>
824 <dd><samp>new Array();</samp></dd>
826 <dt><code>(make-array 1 2 3)</code></dt>
827 <dd><samp>new Array(1, 2, 3);</samp></dd>
829 <dt>
830 <pre><code>(make-array
831 (make-array 2 3)
832 (make-array "foobar" "bratzel bub"))</code></pre>
833 </dt>
835 <dd>
836 <samp>new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));</samp>
837 </dd>
838 </dl>
840 <p>Array elements can be accessed using <code>AREF</code> or <code>ELT</code>.</p>
842 <h2 id="section-arithmetic">Arithmetic and boolean operators</h2>
843 <ul>
844 <li>(&lt;operator&gt; {<var>argument</var>}*)</li>
845 <li>(&lt;single-operator&gt; <var>argument</var>)</li>
846 </ul>
848 <dl>
849 <dt>&lt;operator&gt;</dt>
850 <dd>one of <code>*, /, +, -, <, >, <=, >=, =, AND, ASH, EQ, EQL, EQUAL, LOGAND, LOGIOR, LOGXOR, MOD, OR, REM, SETF</code>
851 </dd>
852 <dt>&lt;single-operator&gt;</dt>
853 <dd>one of <code>DECF, INCF, LOGNOT, NOT</code></dd>
855 <dt><var>argument</var></dt> <dd>an expression</dd>
856 </dl>
858 <p>Operator forms are similar to function call forms, but have an
859 operator as function name.</p>
861 <p>Please note that <code>=</code> is converted to <samp>===</samp> in
862 JavaScript. The <code>=</code> Parenscript operator is not the
863 assignment operator.</p>
865 <dl>
866 <dt><code>(* 1 2)</code></dt>
867 <dd><samp>1 * 2;</samp></dd>
869 <dt><code>(= 1 2)</code></dt>
870 <dd><samp>1 === 2;</samp></dd>
871 </dl>
873 <p>The negation of equality operators are obtained by through <code>NOT</code>. For example:</p>
875 <dl>
876 <dt><code>(not (eql 1 2))</code></dt>
877 <dd><samp>1 !== 2</samp></dd>
878 </dl>
880 <p>The operators that in CL have variable arity convert into multiple calls
881 to the equivalent operators in JavaScript</p>
883 <dl>
884 <dt><code>(logxor 1 3 7 15)</code></dt>
885 <dd><samp>1 ^ 3 ^ 7 ^ 15 </samp></dd>
886 </dl>
888 <h2 id="section-math">Mathematical functions and constants</h2>
889 <ul>
890 <li>(<code id="max">MAX</code> {<var>number</var>}*)</li>
891 <li>(<code id="min">MIN</code> {<var>number</var>}*)</li>
892 <li>(<code id="floor">FLOOR</code> <var>number</var> &amp;optional <var>divisor</var>)</li>
893 <li>(<code id="ceiling">CEILING</code> <var>number</var> &amp;optional <var>divisor</var>)</li>
894 <li>(<code id="round">ROUND</code> <var>number</var> &amp;optional <var>divisor</var>)</li>
895 <li>(<code id="sin">SIN</code> <var>number</var>)</li>
896 <li>(<code id="cos">COS</code> <var>number</var>)</li>
897 <li>(<code id="tan">TAN</code> <var>number</var>)</li>
898 <li>(<code id="asin">ASIN</code> <var>number</var>)</li>
899 <li>(<code id="acos">ACOS</code> <var>number</var>)</li>
900 <li>(<code id="atan">ATAN</code> <var>number1</var> &amp;optional <var>number2</var>)</li>
901 <li>(<code id="sinh">SINH</code> <var>number</var>)</li>
902 <li>(<code id="cosh">COSH</code> <var>number</var>)</li>
903 <li>(<code id="tanh">TANH</code> <var>number</var>)</li>
904 <li>(<code id="asinh">ASINH</code> <var>number</var>)</li>
905 <li>(<code id="acosh">ACOSH</code> <var>number</var>)</li>
906 <li>(<code id="atanh">ATANH</code> <var>number</var>)</li>
907 <li>(<code id="1+">1+</code> <var>number</var>)</li>
908 <li>(<code id="1-">1-</code> <var>number</var>)</li>
909 <li>(<code id="abs">ABS</code> <var>number</var>)</li>
910 <li>(<code id="evenp">EVENP</code> <var>number</var>)</li>
911 <li>(<code id="oddp">ODDP</code> <var>number</var>)</li>
912 <li>(<code id="exp">EXP</code> <var>number</var>)</li>
913 <li>(<code id="expt">EXPT</code> <var>base</var> <var>power</var>)</li>
914 <li>(<code id="log">LOG</code> <var>number</var> &amp;optional <var>base</var>)</li>
915 <li>(<code id="sqrt">SQRT</code> <var>number</var>)</li>
916 <li>(<code id="random">RANDOM</code> &amp;optional <var>limit</var>)</li>
918 <li><var id="pi">PI</var></li>
919 </ul>
922 The mathematical functions listed above work mostly like their
923 Common Lisp counterparts when called directly, with the
924 exception that complex numbers are not supported. However, most
925 of them are implemented as macros, and as such cannot be treated
926 as first-class functions.
927 </p>
929 <h2 id="section-blocks">Blocks</h2>
930 <ul>
931 <li>
932 (<code id="block">BLOCK</code> <var>name</var> {<var>expression</var> | <var>statement</var>}*)
933 </li>
934 <li>
935 (<code id="progn">PROGN</code> {<var>statement</var>}*) in statement context
936 </li>
937 <li>
938 (<code>PROGN</code> {<var>expression</var>}*) in expression context
939 </li>
940 <li>
941 (<code id="prog1">PROG1</code> {<var>expression</var> | <var>statement</var>}*)
942 </li>
943 <li>
944 (<code id="prog2">PROG2</code> {<var>expression</var> | <var>statement</var>}*)
945 </li>
946 <li>
947 (<code id="eval-when">EVAL-WHEN</code> {<var>expression</var> | <var>statement</var>}*)
948 </li>
949 </ul>
951 <dl>
952 <dt><var>name</var></dt> <dd>Name/tag of the block. A symbol or nil.</dd>
953 <dt><var>statement</var></dt> <dd>a form that compiles to a statement</dd>
954 <dt><var>expression</var></dt> <dd>a form that compiles to an expression</dd>
955 </dl>
958 The translation of <code>PROGN</code> depends on whether it is
959 found in a statement or expression context:
960 </p>
962 <dl>
963 <dt><code>(progn (blorg i) (blafoo i))</code></dt>
964 <dd>
965 <pre><samp>blorg(i);
966 blafoo(i);</samp></pre>
967 </dd>
969 <dt><code>(+ i (progn (blorg i) (blafoo i)))</code></dt>
970 <dd><samp>i + (blorg(i), blafoo(i));</samp></dd>
971 </dl>
974 The Parenscript <code>EVAL-WHEN</code> special operator has a
975 slightly different meaning from the Common Lisp one. The code in
976 the <code>EVAL-WHEN</code> special form is assumed to be Common
977 Lisp code in <code>:compile-toplevel</code>
978 and <code>:load-toplevel</code> situations, and is executed by
979 the Parenscript compiler, and is assumed to be Parenscript code
980 in the <code>:execute</code> situation, when it is run as
981 JavaScript.
982 </p>
984 <h2 id="section-functions">Functions and multiple values</h2>
985 <ul>
986 <li>(<code id="defun">DEFUN</code> <var>name</var> <var>lambda-list</var> <var>body</var>)</li>
987 <li>(<code id="lambda">LAMBDA</code> <var>lambda-list</var> <var>body</var>)</li>
988 <li>(<code id="flet">FLET</code> ({(<var>name</var> <var>lambda-list</var> <var>body</var>)}*) <var>body</var>)</li>
989 <li>(<code id="labels">LABELS</code> ({(<var>name</var> <var>lambda-list</var> <var>body</var>)}*) <var>body</var>)</li>
990 <li>(<code id="values">VALUES</code> {<var>expression</var>}*)</li>
991 <li>(<code id="multiple-value-bind">MULTIPLE-VALUE-BIND</code> ({<var>var</var>}*) <var>expression</var> <var>body</var>)</li>
992 <li>(<code id="apply">APPLY</code> <var>function</var> {<var>expression</var>}*)</li>
993 <li>(<code id="funcall">FUNCALL</code> <var>function</var> {<var>expression</var>}*)</li>
994 <li><var id="this">THIS</var></li>
995 </ul>
997 <dl>
998 <dt><var>expression</var></dt> <dd>a form that compiles to an expression</dd>
999 <dt><var>name</var></dt> <dd>a symbol</dd>
1000 <dt><var>lambda-list</var></dt> <dd>a lambda list</dd>
1001 <dt><var>body</var></dt> <dd>implicit <code>PROGN</code></dd>
1002 <dt><var>var</var></dt> <dd>a symbol naming a variable</dd>
1003 <dt><var>function</var></dt> <dd>an expression that yields a function</dd>
1004 </dl>
1007 New function definitions can be introduced using all the regular
1008 Lisp forms
1009 - <code>DEFUN</code>, <code>LAMBDA</code>, <code>FLET</code>,
1010 and <code>LABELS</code>. Function lambda lists
1011 support <code>&amp;optional</code>, <code>&amp;rest</code> and
1012 <code>&amp;key</code> arguments.
1013 </p>
1016 The Parenscript multiple value facility passes the first return
1017 value using the regular JavaScript convention, therefore
1018 functions returning multiple values can be called by regular
1019 JavaScript code and <code>MULTIPLE-VALUE-BIND</code> works with
1020 regular JavaScript functions.
1021 </p>
1024 <code>APPLY</code> is a macro that expands into a call to the
1025 JavaScript <code>apply</code> method.
1026 </p>
1028 <h2 id="section-control-transfer">Control transfer and exceptions</h2>
1029 <ul>
1030 <li>
1031 (<code id="return">RETURN</code> {<var>value</var>}?)
1032 </li>
1033 <li>
1034 (<code id="return-from">RETURN-FROM</code> <var>name</var> {<var>value</var>}?)
1035 </li>
1036 <li>
1037 (<code id="throw">THROW</code> {<var>exp</var>}?)
1038 </li>
1039 <li>
1040 (<code id="try">TRY</code> <var>form</var>
1041 {(<code id="catch">:CATCH</code> (<var>var</var>) <var>body</var>)}?
1042 {(<code id="finally">:FINALLY</code> <var>body</var>)}?)
1043 </li>
1044 <li>
1045 (<code id="unwind-protect">UNWIND-PROTECT</code> <var>protected-form</var> <var>cleanup-form</var>)
1046 </li>
1047 <li>
1048 (<code id="ignore-errors">IGNORE-ERRORS</code> <var>body</var>)
1049 </li>
1050 </ul>
1052 <dl>
1053 <dt><var>value</var></dt> <dd>a statement or expression</dd>
1054 <dt><var>name</var></dt> <dd>name of block to return from</dd>
1055 <dt><var>exp</var></dt> <dd>an expression</dd>
1056 <dt><var>var</var></dt> <dd>variable to which the value of the caught <code>THROW</code> is bound</dd>
1057 <dt><var>body</var></dt> <dd>implicit <code>PROGN</code></dd>
1058 </dl>
1061 Parenscript support nested blocks and the <code>RETURN</code>
1062 and <code>RETURN-FROM</code> special forms.
1063 </p>
1065 <dl>
1066 <dt>
1067 <pre><code>(defun foo (x)
1068 (progn
1069 (abc)
1070 (return-from foo
1071 (case x
1072 (1 :a)
1073 (2 :b)))
1074 (xyz)))</code></pre>
1075 </dt>
1077 <dd>
1078 <pre><samp>function foo(x) {
1079 abc();
1080 switch (x) {
1081 case 1:
1082 return 'a';
1083 case 2:
1084 return 'b';
1086 return xyz();
1087 };</samp></pre>
1088 </dd>
1089 </dl>
1092 Currently, <code>THROW</code> translates directly into the
1093 JavaScript <samp>throw</samp>, to be used with <code>TRY</code>,
1094 which is translated to the JavaScript <samp>try</samp>.
1095 </p>
1097 <dl>
1098 <dt>
1099 <pre><code>(try (throw "i")
1100 (:catch (error)
1101 (alert (+ "an error happened: " error)))
1102 (:finally
1103 (alert "Leaving the try form")))</code></pre>
1104 </dt>
1106 <dd>
1107 <pre><samp>try {
1108 throw 'i';
1109 } catch (error) {
1110 alert('an error happened: ' + error);
1111 } finally {
1112 alert('Leaving the try form');
1113 };</samp></pre>
1114 </dd>
1115 </dl>
1117 <h2 id="section-conditionals">Conditionals</h2>
1118 <ul>
1119 <li>(<code id="if">IF</code> <var>condition</var> <var>then</var> {<var>else</var>})</li>
1120 <li>(<code id="when">WHEN</code> <var>condition</var> <var>then</var>)</li>
1121 <li>(<code id="unless">UNLESS</code> <var>condition</var> <var>then</var>)</li>
1122 <li>(<code id="cond">COND</code> {<var>clause</var>}*)</li>
1123 <li>(<code id="case">CASE</code> <var>case-value</var> <var>clause</var>*)</li>
1124 <li>(<code id="switch">SWITCH</code> <var>case-value</var> <var>clause</var>*)</li>
1125 <li><code id="break">BREAK</code></li>
1126 </ul>
1128 <dl>
1129 <dt><var>condition</var></dt> <dd>an expression</dd>
1130 <dt><var>then</var></dt> <dd>a statement in statement context, or an expression in expression context</dd>
1131 <dt><var>else</var></dt> <dd>a statement in statement context, or an expression in expression context</dd>
1132 <dt><var>clause</var></dt> <dd>(&lt;<var>value</var>&gt; <var>body</var>) | (<var>default</var> <var>body</var>)</dd>
1133 </dl>
1135 <p><code>IF, WHEN, UNLESS</code> and <code>COND</code> work like
1136 their Lisp counterparts, and are compiled either into statements
1137 or expressions, depending on the context:</p>
1139 <dl>
1140 <dt>
1141 <code>(cond ((= x 1) (+ x (if (foo y) 2 3))))</code>
1142 </dt>
1144 <dd>
1145 <pre><samp>if (x == 1) {
1146 x + (foo(y) ? 2 : 3);
1147 };</samp></pre>
1148 </dd>
1149 </dl>
1152 <code>CASE</code> works similar to its Common Lisp equivalent.
1153 </p>
1156 An additional form, <code>SWITCH</code>, takes the same syntax
1157 as <code>CASE</code>, but the individual branches must be
1158 terminated with the
1159 symbol <a href="#break"><code>BREAK</code></a>. This allows
1160 C-style case "fall-throughs" in <code>switch</code> statements:
1161 </p>
1163 <dl>
1164 <dt>
1165 <pre><code>(switch (aref blorg i)
1166 (1 (alert "If I get here"))
1167 (2 (alert "I also get here")
1168 break)
1169 (default (alert "I always get here")))</code></pre>
1170 </dt>
1172 <dd>
1173 <pre><samp>switch (blorg[i]) {
1174 case 1:
1175 alert('If I get here');
1176 case 2:
1177 alert('I also get here');
1178 break;
1179 default:
1180 alert('I always get here');
1181 };</samp></pre>
1182 </dd>
1183 </dl>
1185 <p>Note that the default case in a <code>SWITCH</code> statement
1186 must be named <code id="default">DEFAULT</code>.</p>
1188 <h2 id="section-variables">Variable binding and declaration</h2>
1189 <ul>
1190 <li>(<code id="let">LET</code> ({<var>var</var> | (<var>var</var> <var>value</var>)}*) <var>body</var>)</li>
1191 <li>(<code id="let*">LET*</code> ({<var>var</var> | (<var>var</var> <var>value</var>)}*) <var>body</var>)</li>
1192 <li>(<code id="defvar">DEFVAR</code> <var>var</var> {<var>value</var>}?)</li>
1193 <li>(<code id="defparameter">DEFPARAMETER</code> <var>var</var> {<var>value</var>}?)</li>
1194 <li>(<code id="var">VAR</code> <var>var</var> {<var>value</var>}?)</li>
1195 </ul>
1197 <dl>
1198 <dt><var>var</var></dt> <dd>a symbol</dd>
1199 <dt><var>value</var></dt> <dd>an expression</dd>
1200 <dt><var>body</var></dt> <dd>implicit <code>PROGN</code></dd>
1201 <dt><var>object</var></dt> <dd>an expression evaluating to an object</dd>
1202 </dl>
1204 <p>Parenscript provides the <code>LET</code> and <code>LET*</code>
1205 special forms for creating new variable bindings. Both special
1206 forms implement lexical scope by renaming the provided variables
1207 via <a href="#ps-gensym"><code>GENSYM</code></a>, and implement
1208 dynamic binding
1209 using <a href="#try"><code>TRY-FINALLY</code></a>.</p>
1211 <p>Special variables can be declared using
1212 <code>DEFVAR</code>. Note that the result is undefined
1213 if <code>DEFVAR</code> does not occur as a top-level form.</p>
1215 <p>One Parenscript feature that is not part of Common Lisp is the
1216 lexically-scoped global variable, which is declared using
1217 the <code>VAR</code> special form. The result is undefined
1218 if <code>VAR</code> does not occur as a top-level form.</p>
1220 <p>An example of variable declaration and binding:</p>
1222 <dl>
1223 <dt>
1224 <pre><code>(defvar *a* 4)
1225 (var *b* 3)
1226 (lambda ()
1227 (let ((x 1)
1228 (*a* 2)
1229 (*b* 6))
1230 (let* ((y (+ x 1))
1231 (x (+ x y)))
1232 (+ *a* *b* x y))))</code></pre>
1233 </dt>
1235 <dd>
1236 <pre><samp>var A = 4;
1237 var B = 3;
1238 function () {
1239 var x = 1;
1240 var B = 6;
1241 var A_TMPSTACK1;
1242 try {
1243 A_TMPSTACK1 = A;
1244 A = 2;
1245 var y = x + 1;
1246 var x2 = x + y;
1247 return A + B + x2 + y;
1248 } finally {
1249 A = A_TMPSTACK1;
1251 };</samp></pre>
1252 </dd>
1253 </dl>
1255 <h2 id="section-assignment">Assignment</h2>
1257 <p>Parenscript assignment is done via the
1258 standard <code id="setf">SETF</code>, <code id="SETQ">SETQ</code>,
1259 <code id="PSETF">PSETF</code>, and <code id="PSETQ">PSETQ</code>
1260 Lisp special forms. Parenscript supports the Common Lisp
1261 protocol of <code>SETF</code>able places.</p>
1263 <p>New places can be defined in one of two ways: using
1264 <code>DEFSETF</code> or using <code>DEFUN</code> with a setf
1265 function name; both are analogous to their Common Lisp
1266 counterparts. <code>DEFSETF</code> supports both long and short
1267 forms, while <code>DEFUN</code> of a setf place generates a
1268 JavaScript function name with the <samp>__setf_</samp>
1269 prefix:</p>
1271 <dl>
1272 <dt>
1273 <pre><code>(defun (setf color) (new-color el)
1274 (setf (@ el style color) new-color))</code></pre>
1275 </dt>
1277 <dd>
1278 <pre><samp>function __setf_color(newColor, el) {
1279 return el.style.color = newColor;
1280 };</samp></pre>
1281 </dd>
1283 <dt>
1284 <code>(setf (color some-div) (+ 23 "em"))</code>
1285 </dt>
1287 <dd>
1288 <pre><samp>var _js2 = someDiv;
1289 var _js1 = 23 + 'em';
1290 __setf_color(_js1, _js2);</samp></pre>
1291 </dd>
1292 </dl>
1294 <p>The following example illustrates how setf places can be used
1295 to provide a uniform protocol for positioning elements in HTML
1296 pages:</p>
1298 <dl>
1299 <dt>
1300 <pre><code>(defsetf left (el) (offset)
1301 `(setf (@ ,el style left) ,offset))
1303 (defmacro left (el)
1304 `(@ ,el offset-left))
1306 (setf (left some-div) (+ 123 "px"))
1307 (left some-div)</code></pre>
1308 </dt>
1310 <dd>
1311 <pre><samp>var _js2 = someDiv;
1312 var _js1 = 123 + 'px';
1313 _js2.style.left = _js1;
1314 someDiv.offsetLeft;</samp></pre>
1315 </dd>
1316 </dl>
1318 <h2 id="section-iteration">Iteration</h2>
1319 <ul>
1320 <li>(<code id="do">DO</code> ({<var>var</var> | (<var>var</var> {<var>init</var>}? {<var>step</var>}?)}*) (<var>end-test</var> {<var>result</var>}?) <var>body</var>)</li>
1321 <li>(<code id="do*">DO*</code> ({<var>var</var> | (<var>var</var> {<var>init</var>}? {<var>step</var>}?)}*) (<var>end-test</var> {<var>result</var>}?) <var>body</var>)</li>
1322 <li>(<code id="dotimes">DOTIMES</code> (<var>var</var> <var>numeric-form</var> {<var>result</var>}?) <var>body</var>)</li>
1323 <li>(<code id="dolist">DOLIST</code> (<var>var</var> <var>list-form</var> {<var>result</var>}?) <var>body</var>)</li>
1324 <li>(<code id="for-in">FOR-IN</code> (<var>var</var> <var>object</var>) <var>body</var>)</li>
1325 <li>(<code id="loop">LOOP</code> {&lt;loop clauses&gt;}*)</li>
1326 </ul>
1328 <dl>
1329 <dt><var>var</var></dt> <dd>a symbol</dd>
1330 <dt><var>numeric-form</var></dt> <dd>a number yielding expression</dd>
1331 <dt><var>list-form</var></dt> <dd>an array yielding expression</dd>
1332 <dt><var>object-form</var></dt> <dd>an object yielding expression</dd>
1333 <dt><var>init</var></dt> <dd>an expression</dd>
1334 <dt><var>step</var></dt> <dd>an expression</dd>
1335 <dt><var>end-test</var></dt> <dd>an expression</dd>
1336 <dt><var>result</var></dt> <dd>an expression</dd>
1337 <dt><var>body</var></dt> <dd>implicit <code>PROGN</code></dd>
1338 </dl>
1340 <p>Parenscript comes with a wide array of Common Lisp iteration
1341 constructs that compile to efficient JavaScript code,
1342 including a partial implementation of <code>LOOP</code>.</p>
1344 <h2 id="section-macros">Macros</h2>
1345 <h3 id="ssection-defining-macros">Defining macros</h3>
1346 <ul>
1347 <li>(<code id="defmacro">DEFMACRO</code> <var>name</var> <var>lambda-list</var> <var>macro-body</var>)</li>
1348 <li>(<code id="defpsmacro">DEFPSMACRO</code> <var>name</var> <var>lambda-list</var> <var>macro-body</var>)</li>
1349 <li>(<code id="defmacro+ps">DEFMACRO+PS</code> <var>name</var> <var>lambda-list</var> <var>macro-body</var>)</li>
1350 <li>(<code id="import-macros-from-lisp">IMPORT-MACROS-FROM-LISP</code> {<var>symbol</var>}*)</li>
1351 <li>(<code id="macrolet">MACROLET</code> ({<var>name</var> <var>lambda-list</var> <var>macro-body</var>}*) <var>body</var>)</li>
1352 </ul>
1354 <dl>
1355 <dt><var>name</var></dt> <dd>a symbol</dd>
1356 <dt><var>lambda-list</var></dt> <dd>a lambda list</dd>
1357 <dt><var>macro-body</var></dt> <dd>Lisp code evaluating to Parenscript code</dd>
1358 <dt><var>body</var></dt> <dd>implicit <code>PROGN</code></dd>
1359 <dt><var>symbol</var></dt> <dd>symbol with a Lisp macro function definition</dd>
1360 </dl>
1362 <p>Parenscript macros are like Lisp macros in that they have
1363 access to the full Lisp language, but different in that they must
1364 produce Parenscript code. Since Parenscript provides a large
1365 subset of Common Lisp, many Lisp macros already produce valid
1366 Parenscript code, and vice-versa. Parenscript provides several
1367 different ways to define new macros, and to use already existing
1368 Common Lisp macros.</p>
1370 <p><code>DEFMACRO</code> and <code>MACROLET</code> can be used to
1371 define new macros in Parenscript code. Note that macros defined
1372 this way are defined in a null lexical environment (ex
1373 - <code>(let ((x 1)) (defmacro baz (y) `(+ ,y ,x)))</code> will
1374 not work), since the surrounding Parenscript code is just
1375 translated to JavaScript and not actually evaluated.</p>
1377 <p><code>DEFPSMACRO</code> is a Lisp form (not a Parenscript one!)
1378 that can be used by Lisp code to define Parenscript macros without
1379 calling the Parenscript compiler.</p>
1381 <p>The representation of Parenscript macro functions is the same
1382 as that of Common Lisp, and in fact Parenscript can use already
1383 defined macros this way.
1385 <p><code>DEFMACRO+PS</code> defines two macros with the same name
1386 and expansion, one in Parenscript and one in
1387 Lisp. <code>DEFMACRO+PS</code> is used when the full
1388 macro-expansion of the Lisp macro yields code that cannot be used
1389 by Parenscript.</p>
1391 <p>Parenscript also supports the use of macros defined in the
1392 underlying Lisp environment. Existing Lisp macros can be
1393 imported into the Parenscript macro environment
1394 by <code>IMPORT-MACROS-FROM-LISP</code>. This functionality
1395 enables code sharing between Parenscript and Lisp, and is useful
1396 in debugging since the full power of Lisp macro-expanders,
1397 editors and other supporting facilities can be used. However, it
1398 is important to note that the macro-expansion of Lisp macros and
1399 Parenscript macros takes place in their own respective
1400 environments, and many Lisp macros (especially those provided by
1401 the Lisp implementation) expand into code that is not usable by
1402 Parenscript. To make it easy for users to take advantage of
1403 these features, two additional macro definition facilities are
1404 provided by Parenscript: </p>
1406 <h3 id="ssection-symbol-macros">Symbol macros</h3>
1408 <ul>
1409 <li>(<code id="define-ps-symbol-macro">DEFINE-PS-SYMBOL-MACRO</code> <var>symbol</var> <var>expansion</var>)</li>
1410 <li>(<code id="symbol-macrolet">SYMBOL-MACROLET</code> ({<var>name</var> <var>macro-body</var>}*) <var>body</var>)</li>
1411 </ul>
1413 <p>Symbol macros can be introduced
1414 using <code>SYMBOL-MACROLET</code> or defined in Lisp
1415 with <code>DEFINE-PS-SYMBOL-MACRO</code>. For example, the
1416 Parenscript
1417 <code>WITH-SLOTS</code> is implemented using symbol macros:</p>
1419 <dl>
1420 <dt>
1421 <pre><code>(defpsmacro with-slots (slots object &amp;rest body)
1422 `(symbol-macrolet ,(mapcar #'(lambda (slot)
1423 `(,slot '(getprop ,object ',slot)))
1424 slots)
1425 ,@body))</code></pre>
1426 </dt>
1427 </dl>
1429 <h3 id="ssection-gensym">Gensym</h3>
1430 <ul>
1431 <li>(<code id="ps-gensym">PS-GENSYM</code> {<var>string</var>})</li>
1432 <li>(<code id="with-ps-gensyms">WITH-PS-GENSYMS</code> <var>symbols</var> &amp;body <var>body</var>)</li>
1433 <li>(<code id="ps-once-only">PS-ONCE-ONLY</code> (&amp;rest <var>vars</var>) &amp;body <var>body</var>)</li>
1434 <li>(<code id="maybe-once-only">MAYBE-ONCE-ONLY</code> (&amp;rest <var>vars</var>) &amp;body <var>body</var>)</li>
1436 <li><var id="*ps-gensym-counter*">*PS-GENSYM-COUNTER*</var></li>
1437 </ul>
1439 <p>JavaScript identifier equality is based on string
1440 representations, as opposed to Common Lisp, where two uninterned
1441 symbols with the same name are different objects. Therefore
1442 Parenscript <code>GENSYM</code> depends
1443 on <var>*PS-GENSYM-COUNTER*</var> values only for generating
1444 unique identifiers. <var>*PS-GENSYM-COUNTER*</var> does not
1445 persist and is not guaranteed to be thread-safe, so care should be
1446 taken to avoid writing var where gensymed identifiers may clash
1447 (for example, this could happen if you concatenate JS var from PS
1448 compilers running in two different Lisp images, where the values
1449 of <var>*PS-GENSYM-COUNTER*</var> overlap).
1451 <h2 id="section-utilities">Utilities</h2>
1453 <h3 id="ssection-dom">DOM</h3>
1454 <ul>
1455 <li>(<code>INNER-HTML</code> <var>el</var>)</li>
1456 <li>(<code>URI-ENCODE</code> <var>el</var>)</li>
1457 <li>(<code>ATTRIBUTE</code> <var>el</var>)</li>
1458 <li>(<code>OFFSET</code> <var>compass</var> <var>el</var>)</li>
1459 <li>(<code>SCROLL</code> <var>compass</var> <var>el</var>)</li>
1460 <li>(<code>INNER</code> <var>wh</var> <var>el</var>)</li>
1461 <li>(<code>CLIENT</code> <var>wh</var> <var>el</var>)</li>
1462 </ul>
1464 <dl>
1465 <dt><var>el</var></dt> <dd>an expression that yields a DOM element</dd>
1466 <dt><var>compass</var></dt> <dd>one of <code>:TOP, :LEFT, :HEIGHT, :WIDTH, :BOTTOM, :RIGHT</code></dd>
1467 <dt><var>wh</var></dt> <dd>one of <code>:WIDTH, :HEIGHT</code></dd>
1468 </dl>
1470 <h3 id="ssection-html-gen">HTML generation</h3>
1471 <ul>
1472 <li>(<code id="ps-html">PS-HTML</code> <var>html-expression</var>)</li>
1473 <li>(<code id="who-ps-html">WHO-PS-HTML</code> <var>html-expression</var>)</li>
1474 <li><var id="*ps-html-empty-tag-aware-p*">*PS-HTML-EMPTY-TAG-AWARE-P*</var></li>
1475 <li><var id="*ps-html-mode*">*PS-HTML-MODE*</var></li>
1476 </ul>
1478 <p>Parenscript comes with two HTML markup generation facilities
1479 that produce Parenscript code - <code>PS-HTML</code>
1480 and <code>WHO-PS-HTML</code>. The former
1481 accepts <a href="https://franz.com/support/documentation/current/doc/aserve/htmlgen.html">LHTML</a>
1482 style markup; the latter
1483 accepts <a href="https://edicl.github.io/cl-who/">CL-WHO</a>
1484 style markup.</p>
1486 <p><var>*PS-HTML-EMPTY-TAG-AWARE-P*</var>
1487 and <var>*PS-HTML-MODE*</var> control how tags are closed when an
1488 HTML element has no
1489 content. When <var>*PS-HTML-EMPTY-TAG-AWARE-P*</var> is <code>nil</code>, all
1490 tags are fully closed (ex - <code>:BR</code> is translated
1491 as <samp>&lt;BR&gt;&lt;/BR&gt;</samp>). When <var>*PS-HTML-EMPTY-TAG-AWARE-P*</var>
1492 has a non-nil value and <var>*PS-HTML-MODE*</var>
1493 is <code>:SGML</code>, tags such as <code>BR</code> are output without
1494 being closed. When <var>*PS-HTML-MODE*</var> is <code>:XML</code>,
1495 XML-style closing tags are used (ex - <code>:BR</code> is
1496 translated as <samp>&lt;BR /&gt;</samp>).</p>
1498 <dl>
1499 <dt><code>(ps-html ((:a :href "foobar") "blorg"))</code></dt>
1500 <dd><samp>'&lt;A HREF=\"foobar\"&gt;blorg&lt;/A&gt;';</samp></dd>
1502 <dt><code>(who-ps-html (:a :href (generate-a-link) "blorg"))</code></dt>
1503 <dd><samp>'&lt;A HREF=\"' + generateALink() + '\"&gt;blorg&lt;/A&gt;';</samp></dd>
1504 </dl>
1506 <p>The Parenscript compiler can be recursively called in an HTML
1507 expression:</p>
1509 <dl>
1510 <dt>
1511 <pre><code>((@ document write)
1512 (ps-html ((:a :href "#"
1513 :onclick (ps-inline (transport))) "link")))</code></pre>
1514 </dt>
1516 <dd><samp>document.write('&lt;A HREF=\"#\" ONCLICK=\"' + ('javascript:' + 'transport()') + '\"&gt;link&lt;/A&gt;');</samp></dd>
1517 </dl>
1519 <p>Forms may be used in attribute lists to conditionally generate
1520 the next attribute. In this example the textarea is sometimes
1521 disabled.</p>
1523 <dl>
1524 <dt>
1525 <pre><code>(let ((disabled nil)
1526 (authorized t))
1527 (setf (@ element inner-h-t-m-l)
1528 (ps-html ((:textarea (or disabled (not authorized)) :disabled "disabled")
1529 "Edit me"))))</code></pre>
1530 </dt>
1532 <dd>
1533 <pre><samp>var disabled = null;
1534 var authorized = true;
1535 element.innerHTML =
1536 '&lt;TEXTAREA'
1537 + (disabled || !authorized ? ' DISABLED=\"' + 'disabled' + '\"' : '')
1538 + '&gt;Edit me&lt;/TEXTAREA&gt;';</samp></pre>
1539 </dd>
1540 </dl>
1542 <h2 id="section-runtime-library">Run-time library</h2>
1543 <ul>
1544 <li>(<code id="member">MEMBER</code> <var>object</var> <var>array</var>)</li>
1545 <li>(<code id="map">MAP</code> <var>function</var> <var>array</var>)</li>
1546 <li>(<code id="mapcar">MAPCAR</code> <var>function</var> {<var>array</var>}*)</li>
1547 <li>(<code id="reduce">REDUCE</code> <var>function</var> <var>array</var> <var>object</var>)</li>
1548 <li>(<code id="map-into">MAP-INTO</code> <var>function</var> <var>array</var>)</li>
1549 <li>(<code id="set-difference">SET-DIFFERENCE</code> <var>array1</var> <var>array2</var>)</li>
1550 <li><var id="*ps-lisp-library*">*PS-LISP-LIBRARY*</var></li>
1551 </ul>
1553 <p>All the Parenscript constructs presented so far have been free
1554 of any run-time dependencies. Parenscript also comes with a library
1555 of useful predefined functions that can be added to your
1556 project. These functions are kept as Parenscript code in
1557 the <var>*PS-LISP-LIBRARY*</var> special variable.</p>
1559 <p><code>MAP</code> differs from its Common Lisp counterpart by
1560 virtue of being a <code>MAPCAR</code> that only accepts a single
1561 sequence to map over. <code>MAP-INTO</code> is
1562 like <code>MAP</code> but replaces the contents of the given
1563 array in-place.</p>
1565 <h2 id="section-slime-integration">SLIME integration</h2>
1567 <p>The <kbd>extras</kbd> folder in the Parenscript distribution
1568 contains <kbd>js-expander.el</kbd>, which when loaded in Emacs
1569 with SLIME adds the ability to quickly see the translation of
1570 any Lisp form in JavaScript, and works much like the Slime '<kbd>C-c
1571 M-m</kbd>' macro-expansion feature.</p>
1573 <p>'<kbd>C-c j</kbd>' (<a href="#ps"><code>PS</code></a>) or
1574 '<kbd>C-c d</kbd>' (<a href="#ps-doc"><code>PS-DOC</code></a>)
1575 at a Parenscript expression in a <code>slime-mode</code> buffer
1576 will bring up a buffer with the resulting JavaScript code. Note
1577 that the extension does not work
1578 in <code>slime-repl-mode</code>, which is intentional.</p>
1580 <p><kbd>extras/swank-parenscript.lisp</kbd> shows how to add support
1581 to SLIME for printing hints about Parenscript-defined macro and
1582 function argument lists to the Emacs minibuffer, like SLIME
1583 already does for Common Lisp functions and macros.</p>
1585 <p style="font-size:xx-small;float:right;">Last updated: 2019-10-15</p>
1586 </body>
1587 </html>