Deprecated DO-SET-TIMEOUT.
[parenscript.git] / docs / reference.html
blobd3e80f87169ae237770ce0d9b9af25373533182c
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-statements-expressions">Statements, expressions, and return</a></li>
33 <li><a href="#section-symbolconv">Symbol conversion</a></li>
34 <li><a href="#reserved-symbols">Reserved symbols</a></li>
35 <li><a href="#section-types">Types and type predicates</a></li>
36 <li><a href="#section-literals">Literals</a>
37 <ul>
38 <li><a href="#ssection-numbers">Numbers</a></li>
39 <li><a href="#ssection-strings-chars">Strings and characters</a></li>
40 <li><a href="#ssection-regex">Regular expressions</a></li>
41 <li><a href="#ssection-booleans">Booleans and undefined</a></li>
42 </ul>
43 </li>
44 <li><a href="#section-objects">Objects</a></li>
45 <li><a href="#section-arrays">Arrays</a></li>
46 <li><a href="#section-arithmetic">Arithmetic and boolean operators</a></li>
47 <li><a href="#section-math">Mathematical functions and constants</a></li>
48 <li><a href="#section-blocks">Blocks</a></li>
49 <li><a href="#section-functions">Functions and multiple values</a></li>
50 <li><a href="#section-control-transfer">Control transfer and exceptions</a></li>
51 <li><a href="#section-conditionals">Conditionals</a></li>
52 <li><a href="#section-variables">Variable binding and declaration</a></li>
53 <li><a href="#section-assignment">Assignment</a></li>
54 <li><a href="#section-iteration">Iteration</a></li>
55 <li><a href="#section-macros">Macros</a>
56 <ul>
57 <li><a href="#ssection-defining-macros">Defining macros</a></li>
58 <li><a href="#ssection-symbol-macros">Symbol macros</a></li>
59 <li><a href="#ssection-gensym">Gensym</a></li>
60 </ul>
61 </li>
62 <li><a href="#section-namespace">The Parenscript namespace system</a>
63 <ul>
64 <li><a href="#section-obfuscation">Identifier obfuscation</a></li>
65 </ul>
66 </li>
67 <li><a href="#section-utilities">Utilities</a>
68 <ul>
69 <li><a href="#ssection-dom">DOM</a></li>
70 <li><a href="#ssection-html-gen">HTML generation</a></li>
71 </ul>
72 </li>
73 <li><a href="#section-runtime-library">Runtime library</a></li>
74 <li><a href="#section-slime-integration">SLIME integration</a></li>
75 </ol>
77 <h2 id="section-ps-compiler">The Parenscript compiler</h2>
78 <ul>
79 <li>(<code id="ps">PS</code> &body body)</li>
80 <li>(<code id="ps-to-stream">PS-TO-STREAM</code> stream &body body)</li>
81 <li>(<code id="ps*">PS*</code> &rest body)</li>
82 <li>(<code id="ps-doc">PS-DOC</code> &body body)</li>
83 <li>(<code id="ps-doc*">PS-DOC*</code> &body body)</li>
84 <li>(<code id="ps-inline">PS-INLINE</code> form &optional <code>*JS-STRING-DELIMITER*</code>)</li>
85 <li>(<code id="ps-inline*">PS-INLINE*</code> form &optional <code>*JS-STRING-DELIMITER*</code>)</li>
86 <li>(<code id="ps-compile-stream">PS-COMPILE-STREAM</code> stream)</li>
87 <li>(<code id="ps-compile-file">PS-COMPILE-FILE</code> file)</li>
88 <li>(<code id="lisp">LISP</code> lisp-forms)</li>
89 <li>(<code id="symbol-to-js-string">SYMBOL-TO-JS-STRING</code> symbol)</li>
91 <li><code id="*js-target-version*">*JS-TARGET-VERSION*</code></li>
92 <li><code id="*parenscript-stream*">*PARENSCRIPT-STREAM*</code></li>
93 <li><code id="*js-string-delimiter*">*JS-STRING-DELIMITER*</code></li>
94 <li><code id="*js-inline-string-delimiter*">*JS-INLINE-STRING-DELIMITER*</code></li>
95 <li><code id="*ps-print-pretty*">*PS-PRINT-PRETTY*</code></li>
96 <li><code id="*indent-num-spaces*">*INDENT-NUM-SPACES*</code></li>
97 <li><code id="*ps-read-function*">*PS-READ-FUNCTION*</code></li>
98 </ul>
100 <dl>
101 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
102 </dl>
104 <p>The difference between the regular and <code>*</code> versions
105 of the Parenscript compiler forms is roughly the difference
106 between <code>COMPILE</code>
107 and <code>EVAL</code>. The <code>*</code> forms are functions
108 that do all compilation when they are evaluated, while the
109 regular forms are macros that do almost all (except for the use
110 of the <code>LISP</code> special form, see below) compilation at
111 macro-expansion time.</p>
113 <p><code>PS</code> and <code>PS*</code> are the main interfaces to
114 the Parenscript compiler. They come with <code>PS-DOC</code>
115 and <code>PS-DOC*</code> counterparts which compile the given
116 code
117 with <a href="#*ps-gensym-counter*"><code>*PS-GENSYM-COUNTER*</code></a>
118 bound to 0, and are useful for writing automated tests.</p>
120 <p>By default, Parenscript writes output to a string. You can
121 output directly to a stream in one of two ways: either by
122 using <code>PS-TO-STREAM</code> instead of <code>PS</code>, or by
123 binding <code>*PARENSCRIPT-STREAM*</code> before
124 calling <code>PS*</code>.</p>
126 <p><code>PS-INLINE</code> and <code>PS-INLINE*</code> take a single
127 Parenscript form and output a string starting
128 with <code>javascript:</code> that can be used in HTML node
129 attributes. As well, they provide an argument to bind the value of
130 <code>*JS-STRING-DELIMITER*</code> to control the value of the
131 JavaScript string escape character to be compatible with
132 whatever the HTML generation mechanism is used (for example, if
133 HTML strings are delimited using <code>#\'</code>,
134 using <code>#\&quot;</code> will avoid conflicts without
135 requiring the output JavaScript code to be escaped). By default
136 the value is taken
137 from <code>*JS-INLINE-STRING-DELIMITER*</code>.</p>
139 <p>Parenscript code can be compiled from a stream or file
140 via <code>PS-COMPILE-STREAM</code>
141 and <code>PS-COMPILE-FILE</code>, respectively. The special
142 variable <code>*PS-READ-FUNCTION*</code> is bound to the function
143 used to read the forms from the file/stream (<code>READ</code> by
144 default), and can be used to provide completely customizable
145 syntax for Parenscript files.</p>
147 <p><code>*PS-PRINT-PRETTY*</code>
148 and <code>*INDENT-NUM-SPACES*</code> control whether the resulting
149 JavaScript code is pretty-printed, and if so, how many spaces go
150 into each indent level, respectively. By default the code is
151 pretty-printed with 4 spaces per indent level.</p>
153 <p>Parenscript can also call out to arbitrary Common Lisp code at
154 <i>output time</i> (that is, every time an expression containing
155 a call to the Parenscript compiler is evaluated, compared
156 to <i>compile time</i>, where the effect is accomplished using
157 macros) using the special form <code>LISP</code>. The form
158 provided to <code>LISP</code> is evaluated, and its result is
159 compiled as though it were Parenscript code. For <code>PS</code>
160 and <code>PS-INLINE</code>, the Parenscript output code is
161 generated at macro-expansion time, and the <code>LISP</code>
162 statements are inserted inline into the output and have access
163 to the enclosing Common Lisp lexical
164 environment. <code>PS*</code> and <code>PS1*</code> evaluate the
165 <code>LISP</code> forms using <code>EVAL</code>, providing them
166 access to the current dynamic environment only (of course,
167 using <code>LISP</code> when calling the <code>*</code> forms is
168 not strictly necessary, as the values can be inserted inline
169 into code).</p>
171 <p><code>*JS-TARGET-VERSION*</code> (<code>1.3</code> by default)
172 controls which version of JavaScript that Parenscript
173 targets. For newer versions of JS, some Parenscript special
174 forms may compile to more concise and/or efficient expressions
175 that are not present in earlier versions of JavaScript.</p>
177 <p><code>SYMBOL-TO-JS-STRING</code> is the Parenscript function
178 responsible for translating Common Lisp symbols to JavaScript
179 identifiers (see the section
180 on <a href="#section-symbolconv">symbol conversion</a> for the
181 translation rules). It is helpful for writing libraries or other
182 pieces of code that will interface with Parenscript-generated
183 JavaScript.</p>
185 <h2 id="section-statements-expressions">Statements, expressions, and return</h2>
187 <p>In contrast to Lisp, where everything is an expression,
188 JavaScript makes an arbitrary distinction between expressions,
189 which yield a value and can be nested in other expressions, and
190 statements, which have no value and cannot occur in
191 expressions.</p>
193 <p>Some Parenscript special forms compile to expressions, while
194 others can only compile to statements. Certain Parenscript
195 forms, like <code>IF</code> and <code>PROGN</code>, generate
196 different JavaScript depending on if they are used in an
197 expression context or a statement context. In such cases,
198 Parenscript tries to generate statement code if possible to
199 increase readability, only falling back to the expression code
200 if it is necessary.</p>
202 <dl><dt><code>(+ i (if x (foo) (bar)))</code></dt>
203 <dd><code>i + (x ? foo() : bar());</code></dd>
205 <dt><code>(if x (foo) (bar))</code></dt>
206 <dd><code>
207 <pre>if (x) {
208 foo();
209 } else {
210 bar();
211 };</pre>
212 </code>
213 </dd>
214 </dl>
216 <p>One important feature found in Lisp but absent in JavaScript is
217 implicit return in functions. Parenscript supports implicit
218 return by having a <code>RETURN</code> special form that works
219 around the statement-expression dichotomy:</p>
221 <dl>
222 <dt><code>
223 <pre>(defun foo (x)
224 (1+ x))</pre>
225 </code>
226 </dt>
227 <dd><code>
228 <pre>function foo(x) {
229 return x + 1;
230 };</pre>
231 </code>
232 </dd>
234 <dt><code>
235 <pre>(lambda (x)
236 (case x
237 (1 (loop repeat 3 do (alert "foo")))
238 (:bar (alert "bar"))
239 (otherwise 4)))</pre>
240 </code>
241 </dt>
242 <dd><code>
243 <pre>function (x) {
244 switch (x) {
245 case 1:
246 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
247 alert('foo');
249 return null;
250 case 'bar':
251 return alert('bar');
252 default:
253 return 4;
255 };</pre>
256 </code>
257 </dd>
258 </dl>
260 <p>Note that Parenscript does not enforce the statement-expression
261 dichotomy, so it is possible to generate syntactically incorrect
262 JavaScript by nesting special forms that only compile to
263 statements in a context that calls for an expression:</p>
265 <dl>
266 <dt><code>(+ 1 (dotimes (x 3) (+ x x)))</code></dt>
267 <dd>
268 <code>
269 <pre>1 + for (var x = 0; x < 3; x += 1) {
270 x + x;
271 };</pre>
272 </code>
273 </dd>
274 </dl>
276 <h2 id="section-symbolconv">Symbol conversion</h2>
278 <p>Lisp symbols (except for keywords) are converted to JavaScript
279 symbols by following a few simple rules. Special
280 characters <code>!, ?, #, @, %, /, *</code> and <code>+</code>
281 get replaced by their written-out equivalents "bang", "what",
282 "hash", "at", "percent", "slash", "start" and "plus"
283 respectively. The <code>$</code> character is untouched.</p>
285 <dl>
286 <dt><code>!?#@%</code></dt>
287 <dd><code>bangwhathashatpercent;</code></dd>
288 </dl>
290 <p>The <code>-</code> is an indication that the following
291 character should be converted to uppercase.</p>
293 <dl>
294 <dt><code>bla-foo-bar</code></dt>
295 <dd><code>blaFooBar;</code></dd>
296 </dl>
298 <p>JavaScript identifiers that begin with an uppercase letter can
299 be obtained with a leading <code>-</code> or <code>*</code>.</p>
301 <dl>
302 <dt><code>*array</code></dt>
303 <dd><code>Array;</code></dd>
304 </dl>
306 <p>A symbol starting and ending with <code>+</code>
307 or <code>*</code> is converted to all uppercase, to signify that
308 this is a constant or a global variable.</p>
310 <dl>
311 <dt><code>*global-array*</code></dt>
312 <dd><code>GLOBALARRAY;</code></dd>
313 </dl>
315 <p>Keywords are not translated to JavaScript identifiers, but are
316 printed in lower case without any character substitution as
317 strings. This is done because strings are the closest equivalent
318 to Common Lisp keywords (being self-evaluating objects in
319 JavaScript), and to permit keywords to be used for identifying
320 various symbols (for example, as tokens in a parser).</p>
322 <dl>
323 <dt><code>:+</code></dt>
324 <dd><code>'+';</code></dd>
326 <dt><code>:foo-Bar</code></dt>
327 <dd><code>'foo-bar';</code></dd>
328 </dl>
330 <h2 id="reserved-symbols">Reserved symbols</h2>
332 <p>The following symbols are reserved in Parenscript, and should not
333 be used as variable names.</p>
335 <code>
336 ! ~ ++ -- * / % + - &lt;&lt; &gt;&gt; &gt;&gt;&gt; &lt; &gt;
337 &lt;= &gt;= == != === !== & ^ | && || *= /= %= += -= &lt;&lt;=
338 &gt;&gt;= &gt;&gt;&gt;= &= ^= |= 1- 1+ @ ABSTRACT AND AREF ARRAY
339 BOOLEAN BREAK BYTE CASE CATCH CHAR CLASS COMMA CONST CONTINUE
340 CREATE DEBUGGER DECF DEFAULT DEFUN DEFVAR DELETE DO DO* DOEACH
341 DOLIST DOTIMES DOUBLE ELSE ENUM EQL EXPORT EXTENDS F FALSE FINAL
342 FINALLY FLOAT FLOOR FOR FOR-IN FUNCTION GOTO IF IMPLEMENTS
343 IMPORT IN INCF INSTANCEOF INT INTERFACE JS LABELED-FOR LAMBDA
344 LET LET* LISP LIST LONG MAKE-ARRAY NATIVE NEW NIL NOT OR PACKAGE
345 PRIVATE PROGN PROTECTED PUBLIC RANDOM REGEX RETURN SETF SHORT
346 GETPROP STATIC SUPER SWITCH SYMBOL-MACROLET SYNCHRONIZED T THIS
347 THROW THROWS TRANSIENT TRY TYPEOF UNDEFINED UNLESS VAR VOID
348 VOLATILE WHEN WHILE WITH WITH-SLOTS
349 </code>
351 <h2 id="section-types">Types and type predicates</h2>
352 <ul>
353 <li>(<code id="typeof">TYPEOF</code> object)</li>
354 <li>(<code id="instanceof">INSTANCEOF</code> object type)</li>
355 <li>(<code id="null">NULL</code> object)</li>
356 <li>(<code id="undefined">UNDEFINED</code> object)</li>
357 <li>(<code id="defined">DEFINED</code> object)</li>
358 <li>(<code id="stringp">STRINGP</code> object)</li>
359 <li>(<code id="numberp">NUMBERP</code> object)</li>
360 <li>(<code id="functionp">FUNCTIONP</code> object)</li>
361 <li>(<code id="objectp">OBJECTP</code> object)</li>
362 </ul>
364 <dl>
365 <dt>object</dt> <dd>an expression yielding an object</dd>
366 <dt>type</dt> <dd>a type designator</dd>
367 </dl>
369 <p>Parenscript is based around the JavaScript type system, and
370 does not introduce any new types or objects, nor does it attempt
371 to provide a Common Lisp-like interface to the type system.</p>
373 <h2 id="section-literals">Literals</h2>
375 <h3 id="ssection-numbers">Numbers</h3>
377 <p>Parenscript prints all integer literals as integers, and floats
378 and rationals as floats, in base 10.</p>
380 <dl>
381 <dt><code>1</code></dt>
382 <dd><code>1;</code></dd>
384 <dt><code>123.123</code></dt>
385 <dd><code>123.123;</code></dd>
387 <dt><code>3/4</code></dt>
388 <dd><code>0.75;</code></dd>
390 <dt><code>#x10</code></dt>
391 <dd><code>16;</code></dd>
392 </dl>
394 <h3 id="ssection-strings-chars">Strings and characters</h3>
396 <p>Lisp strings are converted to JavaScript strings.</p>
398 <dl>
399 <dt><code>"foobar"</code></dt>
400 <dd><code>'foobar';</code></dd>
401 </dl>
403 <p>Parenscript makes no effort to interpolate C-style escape
404 strings. Rather, non-printable characters in Lisp strings are
405 output using escape sequences:</p>
407 <dl>
408 <dt><code>#\Tab</code></dt>
409 <dd><code>'\t';</code></dd>
411 <dt><code>"\\n"</code></dt>
412 <dd><code>'\\n';</code></dd>
413 </dl>
415 <h3 id="ssection-regex">Regular expressions</h3>
416 <ul>
417 <li>(<code id="regex">REGEX</code> regex)</li>
418 </ul>
420 <dl>
421 <dt>regex</dt> <dd>a string</dd>
422 </dl>
424 <p>Regular expressions can be created by using
425 the <code>REGEX</code> form. If the argument does not start with
426 <code>/</code>, it is surrounded by <code>/</code>, otherwise it
427 is left as it is.</p>
429 <dl>
430 <dt><code>(regex "foobar")</code></dt>
431 <dd><code>/foobar/;</code></dd>
433 <dt><code>(regex "/foobar/i")</code></dt>
434 <dd><code>/foobar/i;</code></dd>
435 </dl>
437 <p><a href="http://weitz.de/cl-interpol/">CL-INTERPOL</a> is
438 convenient for writing regular expressions:</p>
440 <dl>
441 <dt><code>(regex #?r"/([^\s]+)foobar/i")</code></dt>
442 <dd><code>/([^\s]+)foobar/i;</code></dd>
443 </dl>
445 <h3 id="ssection-booleans">Booleans and undefined</h3>
446 <ul>
447 <li><code id="t">T</code></li>
448 <li><code id="f">F</code></li>
449 <li><code if="false">FALSE</code></li>
450 <li><code id="nil">NIL</code></li>
451 <li><code id="undefined">UNDEFINED</code></li>
452 </ul>
454 <p><code>T</code> and <code>FALSE</code> (or <code>F</code>) are
455 converted to their JavaScript boolean
456 equivalents <code>true</code> and <code>false</code>.</p>
458 <p><code>NIL</code> is converted to the JavaScript keyword
459 <code>null</code>.</p>
461 <p><code>UNDEFINED</code> is converted to the JavaScript global
462 variable <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Properties/undefined"><code>undefined</code></a>.</p>
464 <h2 id="section-objects">Objects</h2>
465 <ul>
466 <li>(<code id="new">NEW</code> constructor)</li>
467 <li>(<code id="create">CREATE</code> {name value}*)</li>
468 <li>(<code id="getprop">GETPROP</code> object {slot-specifier}*)</li>
469 <li>(<code id="@">@</code> {slot-specifier}*)</li>
470 <li>(<code id="chain">CHAIN</code> {slot-specifier | function-call}*)</li>
471 <li>(<code id="with-slots">WITH-SLOTS</code> ({slot-name}*) object body)</li>
472 <li>(<code id="delete">DELETE</code> object)</li>
473 </ul>
475 <dl>
476 <dt>constructor</dt> <dd>a function call to an object constructor</dd>
477 <dt>name</dt> <dd>symbol, string or keyword</dd>
478 <dt>value</dt> <dd>an expression</dd>
479 <dt>object</dt> <dd>an expression yielding an object</dd>
480 <dt>slot-specifier</dt> <dd>a quoted symbol, a string, a number, or an expression yielding a string or number</dd>
481 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
482 </dl>
484 <p>Object literals can be create
485 using <code>CREATE</code>. <code>CREATE</code> takes a property
486 list of property names and values.</p>
488 <dl>
489 <dt><code>(create foo "bar" :blorg 1)</code></dt>
490 <dd><code>{ foo : 'bar', 'blorg' : 1 };</code></dd>
492 <dt><code>
493 <pre>(create foo "hihi"
494 blorg (array 1 2 3)
495 another-object (create :schtrunz 1))</pre>
496 </code>
497 </dt>
498 <dd><code>
499 <pre>{ foo : 'hihi',
500 blorg : [ 1, 2, 3 ],
501 anotherObject : { 'schtrunz' : 1 } };</pre>
502 </code>
503 </dd>
504 </dl>
506 <p>Object properties can be accessed using
507 <code>GETPROP</code>, which takes an object and a list of
508 properties.</p>
510 <dl>
511 <dt><code>(getprop obj 'foo)</code></dt>
512 <dd><code>obj.foo;</code></dd>
514 <dt><code>(getprop obj foo)</code></dt>
515 <dd><code>obj[foo];</code></dd>
517 <dt><code>(getprop element i 'child-node 0 'node-value)</code></dt>
518 <dd><code>element[i].childNode[0].nodeValue;</code></dd>
519 </dl>
521 <p>The convenience macro <code>@</code> quotes all its given
522 symbol slot-specifiers to save typing:</p>
524 <dl>
525 <dt><code>(@ an-object foo bar)</code></dt>
526 <dd><code>anObject.foo.bar;</code></dd>
528 <dt><code>(@ foo bar child-node 0 node-value)</code></dt>
529 <dd><code>foo.bar.childNode[0].nodeValue;</code></dd>
530 </dl>
532 <p><code>CHAIN</code> can be used to conveniently chain together
533 accessors and function calls:</p>
535 <dl>
536 <dt><code>(chain foo (bar x y) 0 baz)</code></dt>
537 <dd><code>foo.bar(x, y)[0].baz;</code></dd>
538 </dl>
540 <p><code>WITH-SLOTS</code> can be used to bind the given
541 slot-names to a symbol macro that will expand into
542 a <code>GETPROP</code> form at expansion time:</p>
544 <dl>
545 <dt><code>
546 <pre>(with-slots (a b c) this
547 (+ a b c))</pre>
548 </code>
549 </dt>
550 <dd><code>this.a + this.b + this.c;</code></dd>
551 </dl>
553 <h2 id="section-arrays">Arrays</h2>
554 <ul>
555 <li>(<code id="array">ARRAY</code> {values}*)</li>
556 <li>(<code id="list">LIST</code> {values}*)</li>
557 <li>(<code id="[]">[]</code> {values}*)</li>
558 <li>(<code id="make-array">MAKE-ARRAY</code> {values}*)</li>
559 <li>(<code id="length">LENGTH</code> array)</li>
560 <li>(<code id="aref">AREF</code> array index)</li>
561 <li>(<code id="elt">ELT</code> array index)</li>
562 <li>(<code id="destructuring-bind">DESTRUCTURING-BIND</code> bindings array body)</li>
563 <li>(<code id="concatenate">CONCATENATE 'STRING</code> {values}*)</li>
564 <li>(<code id="append">APPEND</code> {values}*)</li>
565 </ul>
567 <dl>
568 <dt>values</dt> <dd>an expression</dd>
569 <dt>array</dt> <dd>an expression</dd>
570 <dt>index</dt> <dd>an expression</dd>
571 </dl>
573 <p>Array literals can be created using the <code>ARRAY</code>
574 or <code>LIST</code> forms.</p>
576 <dl>
577 <dt><code>(array)</code></dt>
578 <dd><code>[];</code></dd>
580 <dt><code>(array 1 2 3)</code></dt>
581 <dd><code>[1, 2, 3];</code></dd>
583 <dt><code>(list (foo) (bar) 3)</code></dt>
584 <dd><code>[foo(), bar(), 3];</code></dd>
586 <dt><code>
587 <pre>(array (array 2 3)
588 (array "foo" "bar"))</pre>
589 </code>
590 </dt>
591 <dd><code>[[ 2, 3 ], ['foo', 'bar']];</code></dd>
592 </dl>
594 <p>Arrays can also be created with a call to the <code>Array</code>
595 function using <code>MAKE-ARRAY</code>.</p>
597 <dl>
598 <dt><code>(make-array)</code></dt>
599 <dd><code>new Array();</code></dd>
601 <dt><code>(make-array 1 2 3)</code></dt>
602 <dd><code>new Array(1, 2, 3);</code></dd>
604 <dt><code>
605 <pre>(make-array
606 (make-array 2 3)
607 (make-array "foobar" "bratzel bub"))</pre>
608 </code>
609 </dt>
610 <dd><code>new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));</code></dd>
611 </dl>
613 <p>Array elements can be accessed using <code>AREF</code> or <code>ELT</code>.</p>
615 <h2 id="section-arithmetic">Arithmetic and boolean operators</h2>
616 <ul>
617 <li>(&lt;operator&gt; {argument}*)</li>
618 <li>(&lt;single-operator&gt; argument)</li>
619 </ul>
621 <dl>
622 <dt>&lt;operator&gt;</dt>
623 <dd>one of <code>*, /, %, +, -, <<, >>, >>>, < >, EQL,
624 ==, !=, =, ===, !==, &, ^, |, &&, AND, ||, OR</code>
625 </dd>
627 <dt>&lt;single-operator&gt;</dt>
628 <dd>one of <code>INCF, DECF, ++, --, NOT, !</code></dd>
630 <dt>argument</dt> <dd>an expression</dd>
631 </dl>
633 <p>Operator forms are similar to function call forms, but have an
634 operator as function name.</p>
636 <p>Please note that <code>=</code> is converted to <code>==</code> in
637 JavaScript. The <code>=</code> Parenscript operator is not the
638 assignment operator.</p>
640 <dl>
641 <dt><code>(* 1 2)</code></dt>
642 <dd><code>1 * 2;</code></dd>
644 <dt><code>(= 1 2)</code></dt>
645 <dd><code>1 === 2;</code></dd>
646 </dl>
648 <h2 id="section-math">Mathematical functions and constants</h2>
649 <ul>
650 <li>(<code id="max">MAX</code> {number}*)</li>
651 <li>(<code id="min">MIN</code> {number}*)</li>
652 <li>(<code id="floor">FLOOR</code> number &optional divisor)</li>
653 <li>(<code id="ceiling">CEILING</code> number &optional divisor)</li>
654 <li>(<code id="round">ROUND</code> number &optional divisor)</li>
655 <li>(<code id="sin">SIN</code> number)</li>
656 <li>(<code id="cos">COS</code> number)</li>
657 <li>(<code id="tan">TAN</code> number)</li>
658 <li>(<code id="asin">ASIN</code> number)</li>
659 <li>(<code id="acos">ACOS</code> number)</li>
660 <li>(<code id="atan">ATAN</code> number1 &optional number2)</li>
661 <li>(<code id="sinh">SINH</code> number)</li>
662 <li>(<code id="cosh">COSH</code> number)</li>
663 <li>(<code id="tanh">TANH</code> number)</li>
664 <li>(<code id="asinh">ASINH</code> number)</li>
665 <li>(<code id="acosh">ACOSH</code> number)</li>
666 <li>(<code id="atanh">ATANH</code> number)</li>
667 <li>(<code id="1+">1+</code> number)</li>
668 <li>(<code id="1-">1-</code> number)</li>
669 <li>(<code id="abs">ABS</code> number)</li>
670 <li>(<code id="evenp">EVENP</code> number)</li>
671 <li>(<code id="oddp">ODDP</code> number)</li>
672 <li>(<code id="exp">EXP</code> number)</li>
673 <li>(<code id="expt">EXPT</code> base power)</li>
674 <li>(<code id="log">LOG</code> number &optional base)</li>
675 <li>(<code id="sqrt">SQRT</code> number)</li>
676 <li>(<code id="random">RANDOM</code> &optional limit)</li>
678 <li><code id="pi">PI</code></li>
679 </ul>
681 <p>The mathematical functions listed above work mostly like their
682 Common Lisp counterparts when called directly, with the
683 exception that complex numbers are not supported. However, most
684 of them are implemented as macros, and as such cannot be treated
685 as first-class functions.</p>
687 <h2 id="section-blocks">Blocks</h2>
688 <ul>
689 <li>(<code id="progn">PROGN</code> {statement}*) in statement context</li>
690 <li>(<code>PROGN</code> {expression}*) in expression context</li>
691 <li>(<code id="prog1">PROG1</code> {expression | statement}*)</li>
692 <li>(<code ud="prog2">PROG2</code> {expression | statement}*)</li>
693 </ul>
695 <dl>
696 <dt>statement</dt> <dd>a form that compiles to a statement</dd>
697 <dt>expression</dt> <dd>a form that compiles to an expression</dd>
698 </dl>
700 <p>The translation of <code>PROGN</code> depends on whether it is
701 found in a statement or expression context:</p>
703 <dl>
704 <dt><code>(progn (blorg i) (blafoo i))</code></dt>
705 <dd><code>
706 <pre>blorg(i);
707 blafoo(i);</pre>
708 </code>
709 </dd>
711 <dt><code>(+ i (progn (blorg i) (blafoo i)))</code></dt>
712 <dd><code>i + (blorg(i), blafoo(i));</code></dd>
713 </dl>
715 <h2 id="section-functions">Functions and multiple values</h2>
716 <ul>
717 <li>(<code id="defun">DEFUN</code> name lambda-list body)</li>
718 <li>(<code id="lambda">LAMBDA</code> lambda-list body)</li>
719 <li>(<code id="flet">FLET</code> ({(name lambda-list body)}*) body)</li>
720 <li>(<code id="labels">LABELS</code> ({(name lambda-list body)}*) body)</li>
721 <li>(<code id="values">VALUES</code> {expression}*)</li>
722 <li>(<code id="multiple-value-bind">MULTIPLE-VALUE-BIND</code> (var*) expression body)</li>
723 <li>(<code id="apply">APPLY</code> function expression*)</li>
724 <li>(<code id="funcall">FUNCALL</code> function expression*)</li>
725 <li><code id="this">THIS</code></li>
726 </ul>
728 <dl>
729 <dt>expression</dt> <dd>a form that compiles to an expression</dd>
730 <dt>name</dt> <dd>a symbol</dd>
731 <dt>lambda-list</dt> <dd>a lambda list</dd>
732 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
733 <dt>var</dt> <dd>a symbol naming a variable</dd>
734 <dt>function</dt> <dd>an expression that yields a function</dd>
735 </dl>
737 <p>New function definitions can be introduced using all the
738 regular Lisp forms
739 - <code>DEFUN</code>, <code>LAMBDA</code>, <code>FLET</code>,
740 and <code>LABELS</code>. Function lambda lists
741 support <code>&optional</code>, <code>&rest</code> and
742 <code>&key</code> arguments.</p>
744 <p>The Parenscript multiple value facility passes the first return
745 value using the regular JavaScript convention, therefore functions
746 returning multiple values can be called by regular JavaScript code
747 and <code>MULTIPLE-VALUE-BIND</code> works with regular JavaScript
748 functions.</p>
750 <p><code>APPLY</code> is a macro that expands into a call to the
751 JavaScript <code>apply</code> method.</p>
753 <h2 id="section-control-transfer">Control transfer and exceptions</h2>
754 <ul>
755 <li>(<code id="return">RETURN</code> {value}?)</li>
756 <li>(<code id="trow">THROW</code> {exp}?)</li>
757 <li>(<code id="try">TRY</code> form
758 {(<code id="catch">:CATCH</code> (var) body)}?
759 {(<code id="finaly">:FINALLY</code> body)}?)</li>
760 <li>(<code>IGNORE-ERRORS</code> body)</li>
761 </ul>
763 <dl>
764 <dt>value</dt> <dd>a statement or expression</dd>
765 <dt>exp</dt> <dd>an expression</dd>
766 <dt>var</dt> <dd>variable to which the value of the caught <code>THROW</code> is bound</dd>
767 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
768 </dl>
770 <p>Parenscript <code>RETURN</code> and <code>THROW</code> forms do
771 not work like the Common Lisp forms with the same names.</p>
773 <p><code>RETURN</code> can only be used to return a value from
774 a function - Parenscript has no analogue of Common Lisp's
775 blocks. <code>RETURN</code> works when given either expressions or
776 statements (in which case it performs semantic analysis to
777 determine what should be returned).</p>
779 <dl>
780 <dt><code>
781 <pre>(lambda (x)
782 (return (case x
783 (1 :a)
784 (2 :b))))</pre>
785 </code>
786 </dt>
787 <dd><code>
788 <pre>function (x) {
789 switch (x) {
790 case 1:
791 return 'a';
792 case 2:
793 return 'b';
795 };</pre>
796 </code>
797 </dd>
798 </dl>
800 <p>Likewise, <code>THROW</code> translates directly into the
801 JavaScript <code>throw</code>, to be used with <code>TRY</code>,
802 which is translated to the JavaScript <code>try</code>.</p>
804 <dl>
805 <dt><code>
806 <pre>(try (throw "i")
807 (:catch (error)
808 (alert (+ "an error happened: " error)))
809 (:finally
810 (alert "Leaving the try form")))</pre>
811 </code>
812 </dt>
813 <dd><code>
814 <pre>try {
815 throw 'i';
816 } catch (error) {
817 alert('an error happened: ' + error);
818 } finally {
819 alert('Leaving the try form');
820 };</pre>
821 </code>
822 </dd>
823 </dl>
825 <h2 id="section-conditionals">Conditionals</h2>
826 <ul>
827 <li>(<code id="if">IF</code> condition then {else})</li>
828 <li>(<code id="when">WHEN</code> condition then)</li>
829 <li>(<code id="unless">UNLESS</code> condition then)</li>
830 <li>(<code id="cond">COND</code> {clauses}*)</li>
831 <li>(<code id="case">CASE</code> case-value clause*)</li>
832 <li>(<code id="switch">SWITCH</code> case-value clause*)</li>
833 <li><code id="break">BREAK</code></li>
834 </ul>
836 <dl>
837 <dt>condition</dt> <dd>an expression</dd>
838 <dt>then</dt> <dd>a statement in statement context, or an expression in expression context</dd>
839 <dt>else</dt> <dd>a statement in statement context, or an expression in expression context</dd>
840 <dt>clause</dt> <dd>(&lt;value&gt; body) | (default body)</dd>
841 </dl>
843 <p><code>IF, WHEN, UNLESS</code> and <code>COND</code> work like
844 their Lisp counterparts, and are compiled either into statements
845 or expressions, depending on the context:</p>
847 <dl>
848 <dt><code>(cond ((= x 1) (+ x (if (foo y) 2 3))))</code>
849 </dt>
850 <dd><code>
851 <pre>if (x == 1) {
852 x + (foo(y) ? 2 : 3);
853 };</pre>
854 </code>
855 </dd>
856 </dl>
858 <p><code>CASE</code> works like its Common Lisp equivalent. An
859 additional form, <code>SWITCH</code>, takes the same syntax
860 as <code>CASE</code>, but the individual branches must be
861 terminated with the
862 symbol <a href="#break"><code>BREAK</code></a>. This allows
863 C-style case "fall-throughs" in <code>switch</code> statements:</p>
865 <dl>
866 <dt><code>
867 <pre>(switch (aref blorg i)
868 (1 (alert "If I get here"))
869 (2 (alert "I also get here")
870 break)
871 (default (alert "I always get here")))</pre>
872 </code>
873 </dt>
874 <dd><code>
875 <pre>switch (blorg[i]) {
876 case 1:
877 alert('If I get here');
878 case 2:
879 alert('I also get here');
880 break;
881 default:
882 alert('I always get here');
883 };</pre>
884 </code>
885 </dd>
886 </dl>
888 <p>Note that the default case in a <code>SWITCH</code> statement
889 must be named <code id="default">DEFAULT</code>.</p>
891 <h2 id="section-variables">Variable binding and declaration</h2>
892 <ul>
893 <li>(<code id="let">LET</code> ({var | (var value)}*) body)</li>
894 <li>(<code id="let*">LET*</code> ({var | (var value)}*) body)</li>
895 <li>(<code id="defvar">DEFVAR</code> var {value}?)</li>
896 <li>(<code id="var">VAR</code> var {value}?)</li>
897 <li>(<code id="with">WITH</code> object body)</li>
898 </ul>
900 <dl>
901 <dt>var</dt> <dd>a symbol</dd>
902 <dt>value</dt> <dd>an expression</dd>
903 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
904 <dt>object</dt> <dd>an expression evaluating to an object</dd>
905 </dl>
907 <p>Parenscript provides the <code>LET</code> and <code>LET*</code>
908 special forms for creating new variable bindings. Both special
909 forms implement lexical scope by renaming the provided variables
910 via <a href="#ps-gensym"><code>GENSYM</code></a>, and implement
911 dynamic binding
912 using <a href="#try"><code>TRY-FINALLY</code></a>.</p>
914 <p>Top-level <code>LET</code> and <code>LET*</code> forms will
915 create new global variables, or overwrite the values of already
916 existing global variables with the same name.</p>
918 <p>The JavaScript <code>with</code> statement can be generated
919 using <code>WITH</code>.</p>
921 <p>Beware that lexical scoping rules in JavaScript differ from
922 Lisp, and may even be implemented incorrectly in certain browser
923 JavaScript implementations. This applies particularly to lexical
924 closures.</p>
926 <p>Special variables can be declared using
927 <code>DEFVAR</code>. Note that the result is undefined
928 if <code>DEFVAR</code> does not occur as a top-level form.</p>
930 <p>One Parenscript feature that is not part of Common Lisp is the
931 lexically-scoped global variable, which is declared using
932 the <code>VAR</code> special form. The result is undefined
933 if <code>VAR</code> does not occur as a top-level form.</p>
935 <p>An example of variable declaration and binding:</p>
937 <dl>
938 <dt><code>
939 <pre>(defvar *a* 4)
940 (var *b* 3)
941 (lambda ()
942 (let ((x 1)
943 (*a* 2)
944 (*b* 6))
945 (let* ((y (+ x 1))
946 (x (+ x y)))
947 (+ *a* *b* x y))))</pre>
948 </code>
949 </dt>
950 <dd><code>
951 <pre>var A = 4;
952 var B = 3;
953 function () {
954 var x = 1;
955 var B = 6;
956 var A_TMPSTACK1;
957 try {
958 A_TMPSTACK1 = A;
959 A = 2;
960 var y = x + 1;
961 var x2 = x + y;
962 return A + B + x2 + y;
963 } finally {
964 A = A_TMPSTACK1;
966 };</pre>
967 </code>
968 </dd>
969 </dl>
971 <h2 id="section-assignment">Assignment</h2>
973 <p>Parenscript assignment is done via the
974 standard <code id="setf">SETF</code>, <code id="SETQ">SETQ</code>,
975 <code id="PSETF">PSETF</code>, and <code id="PSETQ">PSETQ</code>
976 Lisp special forms. Parenscript supports the Common Lisp
977 protocol of <code>SETF</code>able places.</p>
979 <p>New places can be defined in one of two ways: using
980 <code>DEFSETF</code> or using <code>DEFUN</code> with a setf
981 function name; both are analogous to their Common Lisp
982 counterparts. <code>DEFSETF</code> supports both long and short
983 forms, while <code>DEFUN</code> of a setf place generates a
984 JavaScript function name with the <code>__setf_</code>
985 prefix:</p>
987 <dl>
988 <dt><code>
989 <pre>(defun (setf color) (new-color el)
990 (setf (@ el style color) new-color))</pre>
991 </code>
992 </dt>
993 <dd><code>
994 <pre>function __setf_color(newColor, el) {
995 return el.style.color = newColor;
996 };</pre>
997 </code>
998 </dd>
1000 <dt><code>(setf (color some-div) (+ 23 "em"))</code></dt>
1001 <dd><code>
1002 <pre>var _js2 = someDiv;
1003 var _js1 = 23 + 'em';
1004 __setf_color(_js1, _js2);</pre>
1005 </code>
1006 </dd>
1007 </dl>
1009 <p>The following example illustrates how setf places can be used
1010 to provide a uniform protocol for positioning elements in HTML
1011 pages:</p>
1013 <dl>
1014 <dt><code>
1015 <pre>(defsetf left (el) (offset)
1016 `(setf (@ ,el style left) ,offset))
1018 (defmacro left (el)
1019 `(@ ,el offset-left))
1021 (setf (left some-div) (+ 123 "px"))
1022 (left some-div)</pre>
1023 </code>
1024 </dt>
1025 <dd><code>
1026 <pre>var _js2 = someDiv;
1027 var _js1 = 123 + 'px';
1028 _js2.style.left = _js1;
1029 someDiv.offsetLeft;</pre>
1030 </code>
1031 </dd>
1032 </dl>
1034 <h2 id="section-iteration">Iteration</h2>
1035 <ul>
1036 <li>(<code id="do">DO</code> ({var | (var {init}? {step}?)}*) (end-test {result}?) body)</li>
1037 <li>(<code id="do*">DO*</code> ({var | (var {init}? {step}?)}*) (end-test {result}?) body)</li>
1038 <li>(<code id="dotimes">DOTIMES</code> (var numeric-form {result}?) body)</li>
1039 <li>(<code id="dolist">DOLIST</code> (var list-form {result}?) body)</li>
1040 <li>(<code id="for-in">FOR-IN</code> (var object) body)</li>
1041 <li>(<code id="while">WHILE</code> end-test body)</li>
1042 <li>(<code id="loop">LOOP</code> {loop clauses}*)</li>
1043 </ul>
1045 <dl>
1046 <dt>var</dt> <dd>a symbol</dd>
1047 <dt>numeric-form</dt> <dd>a number yielding expression</dd>
1048 <dt>list-form</dt> <dd>an array yielding expression</dd>
1049 <dt>object-form</dt> <dd>an object yielding expression</dd>
1050 <dt>init</dt> <dd>an expression</dd>
1051 <dt>step</dt> <dd>an expression</dd>
1052 <dt>end-test</dt> <dd>an expression</dd>
1053 <dt>result</dt> <dd>an expression</dd>
1054 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
1055 </dl>
1057 <p>Parenscript comes with a wide array of Common Lisp iteration
1058 constructs that compile to efficient JavaScript code,
1059 including a partial implementation of <code>LOOP</code>.</p>
1061 <h2 id="section-macros">Macros</h2>
1062 <h3 id="ssection-defining-macros">Defining macros</h3>
1063 <ul>
1064 <li>(<code id="defmacro">DEFMACRO</code> name lambda-list macro-body)</li>
1065 <li>(<code id="defpsmacro">DEFPSMACRO</code> name lambda-list macro-body)</li>
1066 <li>(<code id="defmacro+ps">DEFMACRO+PS</code> name lambda-list macro-body)</li>
1067 <li>(<code id="import-macros-from-lisp">IMPORT-MACROS-FROM-LISP</code> symbol*)</li>
1068 <li>(<code id="macrolet">MACROLET</code> ({name lambda-list macro-body}*) body)</li>
1069 </ul>
1071 <dl>
1072 <dt>name</dt> <dd>a symbol</dd>
1073 <dt>lambda-list</dt> <dd>a lambda list</dd>
1074 <dt>macro-body</dt> <dd>Lisp code evaluating to Parenscript code</dd>
1075 <dt>body</dt> <dd>implicit <code>PROGN</code></dd>
1076 <dt>symbol</dt> <dd>symbol with a Lisp macro function definition</dd>
1077 </dl>
1079 <p>Parenscript macros are like Lisp macros in that they have
1080 access to the full Lisp language, but different in that they must
1081 produce Parenscript code. Since Parenscript provides a large
1082 subset of Common Lisp, many Lisp macros already produce valid
1083 Parenscript code, and vice-versa. Parenscript provides several
1084 different ways to define new macros, and to use already existing
1085 Common Lisp macros.</p>
1087 <p><code>DEFMACRO</code> and <code>MACROLET</code> can be used to
1088 define new macros in Parenscript code. Note that macros defined
1089 this way are defined in a null lexical environment (ex
1090 - <code>(let ((x 1)) (defmacro baz (y) `(+ ,y ,x)))</code> will
1091 not work), since the surrounding Parenscript code is just
1092 translated to JavaScript and not actually evaluated.</p>
1094 <p><code>DEFPSMACRO</code> is a Lisp form (not a Parenscript one!)
1095 that can be used by Lisp code to define Parenscript macros without
1096 calling the Parenscript compiler.</p>
1098 <p>The representation of Parenscript macro functions is the same
1099 as that of Common Lisp, and in fact Parenscript can use already
1100 defined macros this way.
1102 <p><code>DEFMACRO+PS</code> defines two macros with the same name
1103 and expansion, one in Parenscript and one in
1104 Lisp. <code>DEFMACRO+PS</code> is used when the full macroexpansion of
1105 the Lisp macro yields code that cannot be used by Parenscript.</p>
1107 <p>Parenscript also supports the use of macros defined in the
1108 underlying Lisp environment. Existing Lisp macros can be imported into
1109 the Parenscript macro environment
1110 by <code>IMPORT-MACROS-FROM-LISP</code>. This functionality enables
1111 code sharing between Parenscript and Lisp, and is useful in debugging
1112 since the full power of Lisp macroexpanders, editors and other
1113 supporting facilities can be used. However, it is important to note
1114 that the macroexpansion of Lisp macros and Parenscript macros takes
1115 place in their own respective environments, and many Lisp macros
1116 (especially those provided by the Lisp implementation) expand into
1117 code that is not usable by Parenscript. To make it easy for users to
1118 take advantage of these features, two additional macro definition
1119 facilities are provided by Parenscript: </p>
1121 <h3 id="ssection-symbol-macros">Symbol macros</h3>
1122 (<code id="define-ps-symbol-macro">DEFINE-PS-SYMBOL-MACRO</code> symbol expansion)
1123 (<code id="symbol-macrolet">SYMBOL-MACROLET</code> ({name macro-body}*) body)
1125 <p>Symbol macros can be introduced using <code>SYMBOL-MACROLET</code>
1126 or defined in Lisp with <code>DEFINE-PS-SYMBOL-MACRO</code>. For
1127 example, the Parenscript
1128 <code>WITH-SLOTS</code> is implemented using symbol macros:</p>
1130 <pre><code>
1131 (defpsmacro with-slots (slots object &rest body)
1132 `(symbol-macrolet ,(mapcar #'(lambda (slot)
1133 `(,slot '(getprop ,object ',slot)))
1134 slots)
1135 ,@body))
1136 </code></pre>
1138 <h3 id="ssection-gensym">Gensym</h3>
1139 <ul>
1140 <li>(<code id="ps-gensym">PS-GENSYM</code> {string})</li>
1141 <li>(<code id="with-ps-gensyms">WITH-PS-GENSYMS</code> symbols &body body)</li>
1142 <li>(<code id="ps-once-only">PS-ONCE-ONLY</code> (&rest vars) &body body)</li>
1144 <li><code id="*ps-gensym-counter*">*PS-GENSYM-COUNTER*</code></li>
1145 </ul>
1147 <p>JavaScript identifier equality is based on string
1148 representations, as opposed to Common Lisp, where two uninterned
1149 symbols with the same name are different objects. Therefore
1150 Parenscript <code>GENSYM</code> depends
1151 on <code>*PS-GENSYM-COUNTER*</code> values only for generating
1152 unique identifiers. <code>*PS-GENSYM-COUNTER*</code> does not
1153 persist and is not guaranteed to be thread-safe, so care should be
1154 taken to avoid writing code where gensymed identifiers may clash
1155 (for example, this could happen if you concatenate JS code from PS
1156 compilers running in two different Lisp images, where the values
1157 of <code>*PS-GENSYM-COUNTER*</code> overlap).
1159 <h2 id="section-namespace">The Parenscript namespace system</h2>
1160 <ul>
1161 <li>(setf (<code id="ps-package-prefix">PS-PACKAGE-PREFIX</code> package-designator) string)</li>
1162 </ul>
1164 <p>Although JavaScript does not offer namespacing or a package system,
1165 Parenscript does provide a namespace mechanism for generated
1166 JavaScript by integrating with the Common Lisp package system. Since
1167 Parenscript code is normally read in by the Lisp reader, all symbols
1168 (except for uninterned ones, ie - those specified with
1169 the <code>#:</code> reader macro) have a Lisp package. By default, no
1170 packages are prefixed. You can specify that symbols in a particular
1171 package receive a prefix when translated to JavaScript with the
1172 <code>PS-PACKAGE-PREFIX</code> place.</p>
1174 <code>
1175 <pre>(defpackage "PS-REF.MY-LIBRARY"
1176 (:use "PARENSCRIPT"))
1177 (setf (ps-package-prefix "PS-REF.MY-LIBRARY") "my_library_")</pre>
1178 </code>
1180 <dl>
1181 <dt><code>
1182 <pre>(defun ps-ref.my-library::library-function (x y)
1183 (return (+ x y)))</pre>
1184 </code>
1185 </dt>
1186 <dd><code>
1187 <pre>function my_library_libraryFunction(x, y) {
1188 return x + y;
1189 };</pre>
1190 </code>
1191 </dd>
1192 </dl>
1194 <h3 id="section-obfuscation">Identifier obfuscation</h3>
1195 <ul>
1196 <li>(<code id="obfuscate-package">OBFUSCATE-PACKAGE</code> package-designator &optional symbol-map)</li>
1197 <li>(<code id="unobfuscate-package">UNOBFUSCATE-PACKAGE</code> package-designator)</li>
1198 </ul>
1200 <p>Similar to the namespace mechanism, Parenscript provides a
1201 facility to generate obfuscated identifiers in specified CL
1202 packages. The function <code>OBFUSCATE-PACKAGE</code> may
1203 optionally be passed a closure that maps symbols to their
1204 obfuscated counterparts. By default, the mapping is done
1205 using <code><a href="#ps-gensym">PS-GENSYM</a></code>.</p>
1207 <code>
1208 <pre>(defpackage "PS-REF.OBFUSCATE-ME")
1209 (obfuscate-package "PS-REF.OBFUSCATE-ME"
1210 (let ((code-pt-counter #x8CF6)
1211 (symbol-map (make-hash-table)))
1212 (lambda (symbol)
1213 (or (gethash symbol symbol-map)
1214 (setf (gethash symbol symbol-map)
1215 (make-symbol (string (code-char (incf code-pt-counter)))))))))</pre>
1216 </code>
1218 <dl>
1219 <dt><code>
1220 <pre>(defun ps-ref.obfuscate-me::a-function (a b ps-ref.obfuscate-me::foo)
1221 (+ a (ps-ref.my-library::library-function b ps-ref.obfuscate-me::foo)))</pre>
1222 </code>
1223 </dt>
1224 <dd><code>
1225 <pre>function 賷(a, b, 賸) {
1226 return a + libraryFunction(b, 賸);
1227 };</pre>
1228 </code>
1229 </dd>
1230 </dl>
1232 <p>The obfuscation and namespace facilities can be used on packages
1233 at the same time.</p>
1235 <h2 id="section-utilities">Utilities</h2>
1237 <h3 id="ssection-dom">DOM</h3>
1238 <ul>
1239 <li>(<code>INNER-HTML</code> el)</li>
1240 <li>(<code>URI-ENCODE</code> el)</li>
1241 <li>(<code>ATTRIBUTE</code> el)</li>
1242 <li>(<code>OFFSET</code> compass el)</li>
1243 <li>(<code>SCROLL</code> compass el)</li>
1244 <li>(<code>INNER</code> wh el)</li>
1245 <li>(<code>CLIENT</code> wh el)</li>
1246 </ul>
1248 <dl>
1249 <dt>el</dt> <dd>an expression that yields a DOM element</dd>
1250 <dt>compass</dt> <dd>one of <code>:TOP, :LEFT, :HEIGHT, :WIDTH, :BOTTOM, :RIGHT</code></dd>
1251 <dt>wh</dt> <dd>one of <code>:WIDTH, :HEIGHT</code></dd>
1252 </dl>
1254 <h3 id="ssection-html-gen">HTML generation</h3>
1255 <ul>
1256 <li>(<code id="ps-html">PS-HTML</code> html-expression)</li>
1257 <li>(<code id="who-ps-html">WHO-PS-HTML</code> html-expression)</li>
1258 <li><code id="*ps-html-empty-tag-aware-p*">*PS-HTML-EMPTY-TAG-AWARE-P*</code></li>
1259 <li><code id="*ps-html-mode*">*PS-HTML-MODE*</code></li>
1260 </ul>
1262 <p>Parenscript comes with two HTML markup generation facilities
1263 that produce Parenscript code - <code>PS-HTML</code>
1264 and <code>WHO-PS-HTML</code>. The former
1265 accepts <a href="http://opensource.franz.com/aserve/htmlgen.html">LHTML</a>
1266 style markup, while the latter
1267 accepts <a href="http://weitz.de/cl-who/">CL-WHO</a> style
1268 markup.</p>
1270 <p><code>*PS-HTML-EMPTY-TAG-AWARE-P*</code>
1271 and <code>*PS-HTML-MODE*</code> control how tags are closed when an
1272 HTML element has no
1273 content. When <code>*PS-HTML-EMPTY-TAG-AWARE-P*</code> is nil, all
1274 tags are fully closed (ex - <code>:BR</code> is translated
1275 as <code>&lt;BR&gt;&lt;/BR&gt;</code>). When <code>*PS-HTML-EMPTY-TAG-AWARE-P*</code>
1276 has a non-nil value and <code>*PS-HTML-MODE*</code>
1277 is <code>:SGML</code>, tags such as <code>BR</code> are output without
1278 being closed; when <code>*PS-HTML-MODE*</code> is <code>:XML</code>,
1279 the XML-style closing tags are used (ex - <code>:BR</code> is
1280 translated as <code>&lt;BR /&gt;</code>).</p>
1282 <dl>
1283 <dt><code>(ps-html ((:a :href "foobar") "blorg"))</code></dt>
1284 <dd><code>'&lt;A HREF=\"foobar\"&gt;blorg&lt;/A&gt;';</code></dd>
1286 <dt><code>(who-ps-html (:a :href (generate-a-link) "blorg"))</code></dt>
1287 <dd><code>'&lt;A HREF=\"' + generateALink() + '\"&gt;blorg&lt;/A&gt;';</code></dd>
1288 </dl>
1290 <p>The Parenscript compiler can be recursively called in an HTML
1291 expression:</p>
1293 <dl>
1294 <dt><code>
1295 <pre>((@ document write)
1296 (ps-html ((:a :href "#"
1297 :onclick (ps-inline (transport))) "link")))</pre>
1298 </code>
1299 </dt>
1300 <dd><code>document.write('&lt;A HREF=\"#\" ONCLICK=\"' + ('javascript:' + 'transport()') + '\"&gt;link&lt;/A&gt;');</code></dd>
1301 </dl>
1303 <p>Forms may be used in attribute lists to conditionally generate
1304 the next attribute. In this example the textarea is sometimes
1305 disabled.</p>
1307 <dl>
1308 <dt><code>
1309 <pre>(let ((disabled nil)
1310 (authorized t))
1311 (setf (@ element inner-h-t-m-l)
1312 (ps-html ((:textarea (or disabled (not authorized)) :disabled "disabled")
1313 "Edit me"))))</pre>
1314 </code>
1315 </dt>
1317 <dd><code>
1318 <pre>var disabled = null;
1319 var authorized = true;
1320 element.innerHTML =
1321 '&lt;TEXTAREA'
1322 + (disabled || !authorized ? ' DISABLED=\"' + 'disabled' + '\"' : '')
1323 + '&gt;Edit me&lt;/TEXTAREA&gt;';</pre>
1324 </code>
1325 </dd>
1326 </dl>
1328 <h2 id="section-runtime-library">Runtime library</h2>
1329 <ul>
1330 <li>(<code id="">MEMBER</code> object array)</li>
1331 <li>(<code id="">MAP</code> function array)</li>
1332 <li>(<code id="">MAPCAR</code> function {array}*)</li>
1333 <li>(<code id="">REDUCE</code> function array object)</li>
1334 <li>(<code id="">MAP-INTO</code> function array)</li>
1335 <li>(<code id="">SET-DIFFERENCE</code> array1 array2)</li>
1336 <li><code id="*ps-lisp-library*">*PS-LISP-LIBRARY*</code></li>
1337 </ul>
1339 <p>All the Parenscript constructs presented so far have been free
1340 of any runtime dependencies. Parenscript also comes with a library
1341 of useful predefined functions that can be added to your
1342 project. These functions are kept as Parenscript code in
1343 the <code>*PS-LISP-LIBRARY*</code> special variable.</p>
1345 <p><code>MAP</code> differs from its Common Lisp counterpart by
1346 virtue of being a <code>MAPCAR</code> that only accepts a single
1347 sequence to map over. <code>MAP-UNTIL</code> is
1348 like <code>MAP</code> but replaces the contents of the given
1349 array in-place.</p>
1351 <h2 id="section-slime-integration">SLIME integration</h2>
1353 <p>The <code>extras</code> folder in the Parenscript distribution
1354 contains <code>js-expander.el</code>, which when loaded in Emacs
1355 with SLIME adds the ability to quickly see the translation of
1356 any Lisp form in JavaScript, and works much like the Slime '<code>C-c
1357 M-m</code>' macroexpansion feature.</p>
1359 <p>'<code>C-c j</code>' (<a href="#ps"><code>PS</code></a>) or
1360 '<code>C-c d</code>' (<a href="#ps-doc"><code>PS-DOC</code></a>)
1361 at a ParenScript expression in a <code>slime-mode</code> buffer
1362 will bring up a buffer with the resulting Javascript code. Note
1363 that the extension does not work
1364 in <code>slime-repl-mode</code>, which is intentional.</p>
1366 <p style="font-size:xxx-small"><i>Last modified: 2010-08-13</i></p>
1367 </body>
1368 </html>