Updated the ParenScript tutorial.
[clinton/parenscript.git] / docs / introduction.lisp
CommitLineData
1e92094a 1(in-package :js)
8e198a08
MB
2;;;# Introduction
3;;;
4;;; ParenScript is a simple language that looks a lot like Lisp, but
5;;; actually is JavaScript in disguise. Actually, it is JavaScript
6;;; embedded in a host Lisp. This way, JavaScript programs can be
7;;; seamlessly integrated in a Lisp web application. The programmer
8;;; doesn't have to resort to a different syntax, and JavaScript code
9;;; can easily be generated without having to resort to complicated
10;;; string generation or `FORMAT' expressions.
11;;;
12;;; An example is worth more than a thousand words. The following Lisp
13;;; expression is a call to the ParenScript "compiler". The
14;;; ParenScript "compiler" transforms the expression in ParenScript
15;;; into an equivalent, human-readable expression in JavaScript.
16
17(js
18 (defun foobar (a b)
19 (return (+ a b))))
20
21;;; The resulting javascript is:
1e92094a 22"
8e198a08
MB
23function foobar(a, b) {
24 return a + b;
25}
1e92094a 26"
8e198a08
MB
27;;; Great care has been given to the indentation and overall
28;;; readability of the generated JavaScript code.
29
30;;;# Features
31;;;
32;;; ParenScript supports all the statements and expressions defined by
33;;; the EcmaScript 262 standard. Lisp symbols are converted to
34;;; camelcase, javascript-compliant syntax. This idea is taken from
35;;; Linj by Antonio Menezes Leitao. Here are a few examples of Lisp
36;;; symbol to JavaScript name conversion:
37
38(js-to-string 'foobar) => "foobar"
39(js-to-string 'foo-bar) => "fooBar"
40(js-to-string 'foo-b-@-r) => "fooBAtR"
41(js-to-string 'foo-b@r) => "fooBatr"
42(js-to-string '*array) => "Array"
43(js-to-string '*math.floor) => "Math.floor"
44
45;;; It also supports additional iteration constructs, relieving the
46;;; programmer of the burden of iterating over arrays.
47;;; `for' loops can be written using the customary `DO' syntax.
48
49(js
50 (do ((i 0 (incf i))
51 (j (aref arr i) (aref arr i)))
52 ((>= i 10))
53 (alert (+ "i is " i " and j is " j))))
54
55; compiles to
1e92094a 56"
8e198a08 57for (var i = 0, j = arr[i]; i < 10; i = ++i, j = arr[i]) {
1e92094a 58 alert('i is ' + i + ' and j is ' + j);
8e198a08 59}
1e92094a 60"
8e198a08
MB
61;;; ParenScript uses the Lisp reader, allowing for reader macros. It
62;;; also comes with its own macro environment, allowing host macros
63;;; and ParenScript to coexist without interfering with each other.
64;;; Furthermore, ParenScript uses its own compiler macro system,
65;;; allowing for an even further customization of the generation of
66;;; JavaScript. For example, the `1+' construct is implemented using a
67;;; ParenScript macro:
68
69(defjsmacro 1+ (form)
70 `(+ ,form 1))
71
72;;; ParenScript allows the creation of JavaScript objects in a Lispy
73;;; way, using keyword arguments.
74
75(js
76 (create :foo "foo"
77 :bla "bla"))
78
79; compiles to
1e92094a 80"
94a05cdf 81{ foo : 'foo',
1e92094a
HH
82 bla : 'bla' }
83"
8e198a08
MB
84;;; ParenScript features a HTML generator. Using the same syntax as
85;;; the `HTMLGEN' package of Franz, Inc., it can generate JavaScript
86;;; string expressions. This allows for a clean integration of HTML in
87;;; ParenScript code, instead of writing the tedious and error-prone
88;;; string generation code generally found in JavaScript.
89
90(js
91 (defun add-div (name href link-text)
92 (document.write
93 (html ((:div :id name)
94 "The link is: "
95 ((:a :href href) link-text))))))
96
97; compiles to
1e92094a 98"
8e198a08 99function addDiv(name, href, linkText) {
1e92094a
HH
100 document.write('<div id=\"' + name + '\">The link is: <a href=\"'
101 + href + '\">'
102 + linkText + '</a></div>');
8e198a08 103}
1e92094a 104"
8e198a08
MB
105;;; In order to have a complete web application framework available in
106;;; Lisp, ParenScript also provides a sexp-based syntax for CSS
107;;; files. Thus, a complete web application featuring HTML, CSS and
108;;; JavaScript documents can be generated using Lisp syntax, allowing
109;;; the programmer to use Lisp macros to factor out the redundancies
110;;; and complexities of Web syntax. For example, to generate a CSS
111;;; inline node in a HTML document:
112
94a05cdf 113(html-stream *standard-output*
8e198a08
MB
114 (html
115 (:html
116 (:head
117 (css (* :border "1px solid black")
118 (div.bl0rg :font-family "serif")
119 (("a:active" "a:hoover") :color "black" :size "200%"))))))
120
121; which produces
122
123<html><head><style type="text/css">
124<!--
125* {
126 border:1px solid black;
127}
128
129div.bl0rg {
130 font-family:serif;
131}
132
133a:active,a:hoover {
134 color:black;
135 size:200%;
136}
137
138-->
139</style>
140</head>
141</html>
142
143;;;# Getting ParenScript
144;;;
145;;; ParenScript can be obtained from the BKNR subversion repository at
146
147 svn://bknr.net/trunk/bknr/src/js
148
149;;; ParenScript does not depend on any part of BKNR though. You can
150;;; download snapshots of ParenScript at the webpage
151
152 http://bknr.net/parenscript
153
154;;; or using asdf-install.
155
156 (asdf-install:install 'parenscript)
157
158;;;
159;;; After downloading the ParenScript sourcecode, set up the ASDF
160;;; central registry by adding a symlink to "parenscript.asd". Then
161;;; use ASDF to load ParenScript. You may want to edit the ASDF file
162;;; to remove the dependency on the Allegroserve HTMLGEN facility.
163
164 (asdf:oos 'asdf:load-op :parenscript)
165
166;;; ParenScript was written by Manuel Odendahl. He can be reached at
167
168 manuel@bknr.net
169