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