Fix missing `without-special-symbol-access' in `funcall-with-attribute-context'
[clinton/lisp-on-lines.git] / doc / manual.html
CommitLineData
fb50e621 1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml"
4lang="en" xml:lang="en">
5<head>
6<title>Lisp on Lines : The Missing Manual.</title>
7<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
8<meta name="generator" content="Org-mode"/>
9<meta name="generated" content="2009/07/27 01:46:25 PM"/>
10<meta name="author" content="Drew Crampsie"/>
11<style type="text/css">
12 html {
13 font-family: Times, serif;
14 font-size: 12pt;
15 }
16 .title { text-align: center; }
17 .todo { color: red; }
18 .done { color: green; }
19 .timestamp { color: grey }
20 .timestamp-kwd { color: CadetBlue }
21 .tag { background-color:lightblue; font-weight:normal }
22 .target { }
23 pre {
24 border: 1pt solid #AEBDCC;
25 background-color: #F3F5F7;
26 padding: 5pt;
27 font-family: courier, monospace;
28 font-size: 90%;
29 }
30 table { border-collapse: collapse; }
31 td, th {
32 vertical-align: top;
33 <!--border: 1pt solid #ADB9CC;-->
34 }
35 dt { font-weight: bold; }
36</style>
37</head><body>
38<h1 class="title">Lisp on Lines : The Missing Manual.</h1>
39<i>Abstract</i>: Lisp on Lines is a Common Lisp based framework for rapid
40development of data-driven applications. It is particularly useful
41for producing Web based applications, but is also useful elsewhere.
42
43
44
45<div id="table-of-contents">
46<h2>Table of Contents</h2>
47<div id="text-table-of-contents">
48<ul>
49<li><a href="#sec-1">1 Introduction</a></li>
50<li><a href="#sec-2">2 Installation</a></li>
51<li><a href="#sec-3">3 Describing the domain with the MAO protocol.</a>
52<ul>
53<li><a href="#sec-3.1">3.1 Descriptions</a></li>
54<li><a href="#sec-3.2">3.2 Attributes and Properties</a></li>
55<li><a href="#sec-3.3">3.3 Contexts</a></li>
56</ul>
57</li>
58<li><a href="#sec-4">4 Defining and Using Descriptions</a>
59<ul>
60<li><a href="#sec-4.1">4.1 Defining a simple description </a></li>
61<li><a href="#sec-4.2">4.2 Using descriptions as and with contexts.</a></li>
62<li><a href="#sec-4.3">4.3 T : The root of all descriptions.</a></li>
63<li><a href="#sec-4.4">4.4 DESCRIPTION-OF : Permanently Associate a description with a class.</a></li>
64</ul>
65</li>
66<li><a href="#sec-5">5 The DISPLAY Protocol</a></li>
67<li><a href="#sec-6">6 Automatic Descriptions for CLOS classes.</a>
68<ul>
69<li><a href="#sec-6.1">6.1 Described CLOS objects an the EDITABLE description</a></li>
70<li><a href="#sec-6.2">6.2 Extending the generated description</a></li>
71</ul>
72</li>
73<li><a href="#sec-7">7 Using Lisp-on-Lines for the Web.</a></li>
74</ul>
75</div>
76</div>
77
78<div id="outline-container-1" class="outline-2">
79<h2 id="sec-1">1 Introduction</h2>
80<div id="text-1">
81
82
83<p>
84Lisp on Lines (LoL) is a framework for rapid development of data-driven
85applications, with a particular focus on web-based applications. It
86builds on the UncommonWeb engine and Contextl, and uses CLOS and the
87MOP extensively. Most of LoL can be used both at the REPL and through
88the browser, offering many options for development and testing.
89</p>
90<p>
91While the target audience for LoL is developers experienced with both
92web technologies and common lisp, a good programmer with a little
93experience in either should be able to pick things up fairly quickly.
94</p>
95</div>
96
97</div>
98
99<div id="outline-container-2" class="outline-2">
100<h2 id="sec-2">2 Installation</h2>
101<div id="text-2">
102
103
104<p>
105LoL has a load of dependencies, which themselves depend on others,
106etc. The best way to deal with this is to use <a href="http://common-lisp.net/project/clbuild/">clbuild</a>, a library
107management tool.
108</p>
109<p>
110If you'd prefer to manage your libraries manually, the dependencies,
111according to clbuild, are :
112</p>
113<p>
114alexandria arnesi bordeaux-threads cl-base64 cl-fad cl-mime cl-ppcre
115cl-qprint closer-mop contextl iterate lift local-time lw-compat
116net-telent-date parenscript parse-number portable-threads puri rfc2109
117slime split-sequence trivial-garbage ucw usocket yaclml
118</p>
119<p>
120All libraries should be installed from version control where available.
121</p>
122</div>
123
124</div>
125
126<div id="outline-container-3" class="outline-2">
127<h2 id="sec-3">3 Describing the domain with the MAO protocol.</h2>
128<div id="text-3">
129
130
131<p>
132LoL uses a protocol it calls Meta-Attributed Objects, or MAO, as the
133basis of its display mechanism. In MAO, we create context-aware
134DESCRIPTIONs of objects, and those descriptions are used to generate
135the display of the object itself. By having these external
136descriptions change based on the context in which they are used, a few
137generic components can come together to create complex interfaces.
138</p>
139
140</div>
141
142<div id="outline-container-3.1" class="outline-3">
143<h3 id="sec-3.1">3.1 Descriptions</h3>
144<div id="text-3.1">
145
146<p>Descriptions are a similar conceptually to classes. Every Lisp object
147has one, and the root description that all descriptions inherit from
148is known as T. FIND-DESCRIPTION is used to, well, find descriptions.
149</p>
150
151
152<pre class="src"> (find-description t)
153 =&gt; #&lt;DESCRIPTION T {B7B9861}&gt;
154</pre>
155
156
157</div>
158
159</div>
160
161<div id="outline-container-3.2" class="outline-3">
162<h3 id="sec-3.2">3.2 Attributes and Properties</h3>
163<div id="text-3.2">
164
165<p>A description is a collection of ATTRIBUTEs, among other things. Each
166attribute describes a part of an object, and any number of attributes
167may or may not be active. The ATTRIBUTES function is used to find a
168the list attributes that are both active and applicable in the current
169context.
170</p>
171
172
173<pre class="src">(attributes (find-description t))
174=&gt;(#&lt;ATTRIBUTE IDENTITY {BBC9691}&gt;
175 #&lt;ATTRIBUTE TYPE {BBC96A1}&gt;
176 #&lt;ATTRIBUTE CLASS {BBC96B1}&gt;)
177</pre>
178
179
180<p>
181The functions DESCRIPTION-ATTRIBUTES, DESCRIPTION-ACTIVE-ATTRIBUTES
182and DESCRIPTION-CURRENT-ATTRIBUTES return all the descriptions
183attributes, Attributes that are currently active regardless of
184context, and attributes that exist in the current context but may or
185may not be active, respectively.
186</p>
187<p>
188Attributes have properties, for example ATTRIBUTE-LABEL and
189ATTRIBUTE-VALUE. By simply iterating through the attributes of a
190described object, we can create a generic display for any lisp
191object. This is very similar, and was inspired by the technique
192outlined by Adrian Lienhard in <a href="http://www.adrian-lienhard.ch/files/mewa.pdf">MEWA: A Meta-level Architecture for Generic Web-Application Construction_</a>.
193</p>
194
195<p>
196For attribute properties to be useful, the description must be
197associated with the object it is meant to describe.
198</p>
199<p>
200The function FUNCALL-WITH-DESCRIBED-OBJECT takes care of setting up
201the proper context. There is some syntax for it in the form of
202WITH-DESCRIBED-OBJECT :
203</p>
204
205
206<pre class="src">
207(<span style="color: #a020f0;">let</span> ((description (find-description t))
208 (object <span style="color: #bc8f8f;">"Hello World"</span>))
209 (<span style="color: #a020f0;">with-described-object</span> (object description)
210 (<span style="color: #a020f0;">dolist</span> (a (attributes description))
211 (format t <span style="color: #bc8f8f;">"~@[~A: ~]~A~%"</span>
212 (attribute-label a)
213 (attribute-value a)))))
214=&gt;
215Hello World
216Type: (SIMPLE-ARRAY CHARACTER (11))
217Class: #&lt;BUILT-IN-CLASS SB-KERNEL::SIMPLE-CHARACTER-STRING&gt;
218
219NIL
220</pre>
221
222
223<p>
224FUNCALL-WITH-DESCRIBED-OBJECT binds two specials, <b>DESCRIPTION</b> and
225<b>OBJECT</b>, to its arguments. Knowing this, we can shorten our code
226somewhat. Later on we'll be far away from the lexical bindings of
227description and object, so these special variables are essential.
228</p>
229<p>
230Another reason for the <b>description</b> variable is that
231WITH-DESCRIBED-OBJECT will use DESCRIPTION-OF to determine the
232description if the DESCRIPTION argument is NIL
233</p>
234
235
236<pre class="src">(<span style="color: #a020f0;">with-described-object</span> (<span style="color: #bc8f8f;">"Hello World"</span> nil)
237 (<span style="color: #a020f0;">dolist</span> (a (attributes *description*))
238 (format t <span style="color: #bc8f8f;">"~@[~A: ~]~A~%"</span>
239 (attribute-label a)
240 (attribute-value a))))
241
242Lets wrap that up in a function that we can re-use. LoL includes an
243entire DISPLAY mechanism that is slightly more involved, but this
244serves as an excellent example with not bogging us down in details.
245
246<span style="color: #b22222;">#+BEGIN_SRC lisp</span>
247(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">present</span> (object <span style="color: #228b22;">&amp;optional</span> description)
248 (<span style="color: #a020f0;">with-described-object</span> (object description)
249 (<span style="color: #a020f0;">dolist</span> (a (attributes *description*))
250 (format t <span style="color: #bc8f8f;">"~@[~A: ~]~A~%"</span>
251 (attribute-label a)
252 (attribute-value a)))))
253</pre>
254
255
256</div>
257
258</div>
259
260<div id="outline-container-3.3" class="outline-3">
261<h3 id="sec-3.3">3.3 Contexts</h3>
262<div id="text-3.3">
263
264
265<p>
266MAO adds to MEWA the concept of dynamic context. By changing the
267context in which an object is described, we combine and specialize the
268generic displays, ultimately creating different views of our
269objects. LoL uses ContextL extensively. Descriptions are contextl
270layers, and attributes themselves are layered classes. Most of the
271exported functions are layered methods, and the idea of dynamic
272context-sensitivity is used throughout LoL. If you're not familiar
273with contextl, don't worry, LoL mostly stands on its own. Still,
274reading through the material on contextl won't hurt.
275</p>
276<p>
277Descriptions may have different attributes dependant on what
278description contexts (or layers) are currently active. Attributes
279themselves might have different properties.
280</p>
281<p>
282When an object is being described (using WITH-DESCRIBED-OBJECT), it is
283also activated as a layer context. One can also activate/deactivate
284contexts manually, using WITH-ACTIVE-DESCRIPTIONS and
285WITH-INACTIVE-DESCRIPTIONS.
286</p>
287<p>
288Hopefully a little code will make this more clear :
289</p>
290
291
292<pre class="src">(present <span style="color: #bc8f8f;">"Hello World"</span>)
293=&gt;
294Hello World
295Type: (SIMPLE-ARRAY CHARACTER (11))
296Class: #&lt;BUILT-IN-CLASS SB-KERNEL::SIMPLE-CHARACTER-STRING&gt;
297Simple character string
298
299<span style="color: #b22222;">;; </span><span style="color: #b22222;">Now we'll activate a built-in description, INLINE.
300</span>
301(<span style="color: #a020f0;">with-active-descriptions</span> (<span style="color: #a020f0;">inline</span>)
302 (present <span style="color: #bc8f8f;">"Hello World"</span>))
303=&gt;
304Hello World
305</pre>
306
307
308<p>
309You can see that the behavior of PRESENT changed when the INLINE
310context was activated. This is the key innovation that makes LoL so
311useful. In the next chapter we'll create our own descriptions and
312demonstrate this further.
313</p>
314</div>
315</div>
316
317</div>
318
319<div id="outline-container-4" class="outline-2">
320<h2 id="sec-4">4 Defining and Using Descriptions</h2>
321<div id="text-4">
322
323
324
325</div>
326
327<div id="outline-container-4.1" class="outline-3">
328<h3 id="sec-4.1">4.1 Defining a simple description </h3>
329<div id="text-4.1">
330
331<p>The basics of the MAO should now (hopefully) be clear, so lets start
332using it. First, we'll create our very own description.
333</p>
334
335
336<pre class="src">(<span style="color: #a020f0;">define-description</span> hello-world ()
337 ((title <span style="color: #da70d6;">:value</span> <span style="color: #bc8f8f;">"Lisp on Lines Demo"</span>)
338 (identity <span style="color: #da70d6;">:label</span> <span style="color: #bc8f8f;">"Message"</span>)
339 (length <span style="color: #da70d6;">:label</span> <span style="color: #bc8f8f;">"Length"</span> <span style="color: #da70d6;">:function</span> #'length)
340 (active-attributes <span style="color: #da70d6;">:value</span> '(title identity length))))
341</pre>
342
343
344<p>
345Descriptions are defined very much like CLOS classes, and are in fact
346implemented that way, inheritance rules apply. The object returned
347from FIND-DESCRIPTION is best described as a prototype-based
348singleton. In other words, there is only one instance, and it inherits
349attributes and properties from further up its hierarchy unless
350specifically overridden.
351</p>
352<p>
353Attributes can have any number of properties, (see the class
354STANDARD-ATTRIBUTE), but the three most important are accessed via the
355methods ATTRIBUTE-LABEL, ATTRIBUTE-VALUE and ATTRIBUTE-FUNCTION,and
356named (in DEFINE-DESCRIPTION forms and elsewhere)
357by the :label, :value, and :function keywords.
358</p>
359<p>
360ATTRIBUTE-LABEL is simply a textual label that describes the
361attribute. ATTRIBUTE-VALUE is defined to return the result of calling
362ATTRIBUTE-FUNCTION with the object as its argument. If
363ATTRIBUTE-FUNCTION is NIL, the value of the :value property is returned
364directly.
365</p>
366<p>
367In the example above, the IDENTITY and ACTIVE-ATTRIBUTES attributes
368are inherited from T, and we are simply overriding the default
369properties for our description. LENGTH and TITLE are specific to this
370description. A look at src/standard-descriptions/t.lisp may be
371instructive at this point.
372</p>
373<p>
374Now, we can present our object using our new description.
375</p>
376
377
378<pre class="src">(present <span style="color: #bc8f8f;">"Hello World"</span> (find-description 'hello-world))
379=&gt;
380Lisp on Lines Demo
381Message: Hello World
382Length: 11
383
384NIL
385</pre>
386
387
388</div>
389
390</div>
391
392<div id="outline-container-4.2" class="outline-3">
393<h3 id="sec-4.2">4.2 Using descriptions as and with contexts.</h3>
394<div id="text-4.2">
395
396
397<p>
398A we mentioned earlier, when an object is being described, the
399'description context' is also made active. On top of that, one can
400define partial descriptions that are only active when other
401description contexts have been activated.
402</p>
403<p>
404We'll make a ONE-LINE description similar to the INLINE description
405demonstrated earlier.
406</p>
407
408
409<pre class="src">(<span style="color: #a020f0;">define-description</span> one-line ())
410
411(<span style="color: #a020f0;">define-description</span> hello-world ()
412 ((identity <span style="color: #da70d6;">:label</span> nil)
413 (active-attributes <span style="color: #da70d6;">:value</span> '(identity)))
414 (<span style="color: #da70d6;">:in-description</span> one-line))
415
416</pre>
417
418
419<p>
420Here we've defined a new description, ONE-LINE, and a
421context-sensitive extension to our HELLO-WORLD description. This
422partial desription will be active only when in the context of a
423one-line description. One can have attributes that only exist in
424certain description contexts, and attributes can have different
425properties.
426</p>
427
428
429<pre class="src">(<span style="color: #a020f0;">let</span> ((message <span style="color: #bc8f8f;">"Hello World!"</span>)
430 (description (find-description 'hello-world)))
431 (print <span style="color: #da70d6;">:normal</span>)(terpri)
432 (present message description)
433 (print <span style="color: #da70d6;">:one-line</span>)(terpri)
434 (<span style="color: #a020f0;">with-active-descriptions</span> (one-line)
435 (present message description)))
436=&gt;
437<span style="color: #da70d6;">:NORMAL</span>
438Lisp on Lines Demo
439Message: Hello World!
440Length: 12
441
442<span style="color: #da70d6;">:ONE-LINE</span>
443Hello World!
444
445NIL
446</pre>
447
448
449<p>
450By activating the description ONE-LINE, we've changed the context in
451which our object is displayed. We can create any number of
452descriptions and contexts and activate/deactivate them in any order.
453</p>
454<p>
455Descriptions are implemented as ContextL 'layers', so if all
456this seems weird, reading the ContextL papers might help.
457</p>
458</div>
459
460</div>
461
462<div id="outline-container-4.3" class="outline-3">
463<h3 id="sec-4.3">4.3 T : The root of all descriptions.</h3>
464<div id="text-4.3">
465
466
467<p>
468Because all descriptions inherit from T, we can define contexts for T
469and they will apply to every description. The INLINE description can
470be found in standard-descriptions/inline.lisp, where we define
471a desription for T in the context of the INLINE description :
472</p>
473
474
475<pre class="src"><span style="color: #b22222;">;; </span><span style="color: #b22222;">Defined by LoL in inline.lisp :
476</span>(<span style="color: #a020f0;">define-description</span> t ()
477 ((identity <span style="color: #da70d6;">:label</span> nil)
478 (active-attributes <span style="color: #da70d6;">:value</span> '(identity))
479 (attribute-delimiter <span style="color: #da70d6;">:value</span> <span style="color: #bc8f8f;">", "</span>)
480 (label-formatter <span style="color: #da70d6;">:value</span> (curry #'format nil <span style="color: #bc8f8f;">"~A: "</span>))
481 (value-formatter <span style="color: #da70d6;">:value</span> (curry #'format nil <span style="color: #bc8f8f;">"~A"</span>)))
482 (<span style="color: #da70d6;">:in-description</span> inline))}
483
484</pre>
485
486
487<p>
488The does for the LoL DISPLAY mechanism what ONE-LINE did for PRESENT,
489only with more magic. By exetending T in this way, it's easy to create
490contexts the redefine the behavior of LoL while still reusing the basics.
491</p>
492</div>
493
494</div>
495
496<div id="outline-container-4.4" class="outline-3">
497<h3 id="sec-4.4">4.4 DESCRIPTION-OF : Permanently Associate a description with a class.</h3>
498<div id="text-4.4">
499
500
501<p>
502The LAYERED-FUNCTION DESCRIPTION-OF will return the description
503associated with an object.
504</p>
505
506
507<pre class="src">
508(description-of nil)
509=&gt;
510#&lt;DESCRIPTION NULL {AA04F49}&gt;
511
512(description-of t)
513=&gt;
514#&lt;DESCRIPTION SYMBOL {AA04541}&gt;
515
516(description-of '(1 2 3))
517=&gt;
518#&lt;DESCRIPTION CONS {AA04C29}&gt;
519
520<span style="color: #b22222;">;;</span><span style="color: #b22222;">etc
521</span>
522</pre>
523
524
525</div>
526</div>
527
528</div>
529
530<div id="outline-container-5" class="outline-2">
531<h2 id="sec-5">5 The DISPLAY Protocol</h2>
532<div id="text-5">
533
534
535<p>
536Our function, PRESENT, is very basic, though pretty powerful when
537combined with descriptions and contexts. LoL includes a superset of
538such functionality built-in.
539</p>
540<p>
541The main entry point into this protocol is the DISPLAY
542function. The signature for this functions is :
543</p>
544
545
546<pre class="src">(display DISPLAY OBJECT <span style="color: #228b22;">&amp;REST</span> ARGS <span style="color: #228b22;">&amp;KEY</span> DEACTIVATE ACTIVATE <span style="color: #228b22;">&amp;ALLOW-OTHER-KEYS</span>)
547</pre>
548
549
550<p>
551The first argument, DISPLAY, is the place where we will display
552to/on/in/with. It could be a stream, a UCW component, a CLIM gadget,
553or anything else you might want to use.
554</p>
555<p>
556One can specialize on this argument (though it's better to specialize
557DISPLAY-USING-DESCRIPTION&hellip; more on that later) to use generic
558descriptions to display objects in different environments.
559</p>
560<p>
561The second argument is simply the object to be displayed. Here's a
562simple example :
563</p>
564
565
566<pre class="src">(display t t)
567=&gt;
568T
569Type:BOOLEAN
570Class:#&lt;BUILT-IN-CLASS SYMBOL&gt;
571Symbol
572Name:T
573Value:T
574Package:#&lt;PACKAGE <span style="color: #bc8f8f;">"COMMON-LISP"</span>&gt;
575Function:&lt;UNBOUND&gt;
576<span style="color: #b22222;">; </span><span style="color: #b22222;">No value
577</span></pre>
578
579
580<p>
581The two arguments specified in the lambda-list, ACTIVATE and
582DEACTIVATE, are used to activate and deactivate description contexts in
583the scope of the display function.
584</p>
585
586
587<pre class="src">
588(display nil t <span style="color: #da70d6;">:activate</span> '(<span style="color: #a020f0;">inline</span>))
589=&gt;
590<span style="color: #bc8f8f;">"t"</span>
591(<span style="color: #a020f0;">with-active-descriptions</span> (<span style="color: #a020f0;">inline</span>)
592 (display nil t <span style="color: #da70d6;">:deactivate</span> '(<span style="color: #a020f0;">inline</span>)))
593=&gt;
594<span style="color: #bc8f8f;">"T
595Type:BOOLEAN
596Class:#&lt;BUILT-IN-CLASS SYMBOL&gt;
597Symbol
598Name:T
599Value:T
600Package:#&lt;PACKAGE \"COMMON-LISP\"&gt;
601Function:&lt;UNBOUND&gt;"</span>
602
603</pre>
604
605
606<p>
607Any other keyword arguments passed will be used to set the value of an
608attribute with a :keyword property, in the dynamic context of the
609DISPLAY function call. Once such attribute, and a very useful one is
610ACTIVE-ATTRIBUTES with its :attributes keyword :
611</p>
612
613
614<pre class="src">
615(display t t <span style="color: #da70d6;">:attributes</span> '(class package))
616=&gt;
617Class:#&lt;BUILT-IN-CLASS SYMBOL&gt;
618Package:#&lt;PACKAGE <span style="color: #bc8f8f;">"COMMON-LISP"</span>&gt;
619
620</pre>
621
622
623<p>
624The properties of attributes that do not have a :keyword property can
625also be set dynamically. Since :attributes is the :keyword property of
626the ACTIVE-ATTRIBUTES attribute, the following form is equivalent to
627the previous :
628</p>
629
630
631<pre class="src">(display t t <span style="color: #da70d6;">:attributes</span> '((active-attributes
632 <span style="color: #da70d6;">:value</span> (class package))))
633=&gt;
634Class:#&lt;BUILT-IN-CLASS SYMBOL&gt;
635Package:#&lt;PACKAGE <span style="color: #bc8f8f;">"COMMON-LISP"</span>&gt;
636</pre>
637
638
639<p>
640Setting the attributes this way is almost like creating an anonymous
641description context&hellip; you can express just about anything you would
642in a DEFINE-DESCRIPTION. Here's a more involved example :
643</p>
644
645
646<pre class="src">(display t t <span style="color: #da70d6;">:attributes</span> `((identity <span style="color: #da70d6;">:label</span> <span style="color: #bc8f8f;">"The Object"</span>)
647 (class <span style="color: #da70d6;">:label</span> <span style="color: #bc8f8f;">"CLOS Class"</span>)
648 (package <span style="color: #da70d6;">:value</span> <span style="color: #bc8f8f;">"COMMON LISP"</span> <span style="color: #da70d6;">:function</span> nil)
649 (type <span style="color: #da70d6;">:value-formatter</span>
650 ,(<span style="color: #a020f0;">lambda</span> (a)
651 (format nil <span style="color: #bc8f8f;">"Got a value? ~A"</span> a)))))
652=&gt;
653
654The Object:T
655CLOS Class:#&lt;BUILT-IN-CLASS SYMBOL&gt;
656Package:COMMON LISP
657Type:Got a value? BOOLEAN
658
659</pre>
660
661
662<p>
663I hope that serves well to demonstrate the concepts behind LoL, as
664there is no API documentation available at the moment&hellip; use the
665source luke!
666</p>
667
668</div>
669
670</div>
671
672<div id="outline-container-6" class="outline-2">
673<h2 id="sec-6">6 Automatic Descriptions for CLOS classes.</h2>
674<div id="text-6">
675
676
677<p>
678Lisp-on-Lines includes a compose-able metaclass, DESCRIBED-CLASS. It
679can be combined with <u>any</u> other metaclass without affecting the
680behavior of that class. DESCRIBED-CLASS has been used with the
681metaclasses provided by CLSQL, ROFL, Rucksack and UCW simply by
682defining a class that inherits from both metaclasses.
683</p>
684<p>
685DESCRIBED-CLASS creates a base description for the class, named
686DESCRIPTION-FOR-&lt;class&gt;, and another description with the same name
687as the class that has the previous description as a superclass. The
688then defines a method on DESCRIPTION-OF that returns the second
689description.
690</p>
691<p>
692LoL includes DESCRIBED-STANDARD-CLASS, which is subclass of
693STANDARD-CLASS and DESCRIBED-CLASS. We'll use this to create a class
694and its description.
695</p>
696
697
698<pre class="src">
699(<span style="color: #a020f0;">defclass</span> <span style="color: #228b22;">person</span> ()
700 (first-name last-name company-name
701 date-of-birth phone fax email
702 address city province postal-code)
703 (<span style="color: #da70d6;">:metaclass</span> described-standard-class))
704=&gt;
705#&lt;DESCRIBED-STANDARD-CLASS PERSON&gt;
706
707(display t (make-instance 'person))
708=&gt;
709First name:#&lt;UNBOUND&gt;
710Last name:#&lt;UNBOUND&gt;
711Company name:#&lt;UNBOUND&gt;
712Date of birth:#&lt;UNBOUND&gt;
713Phone:#&lt;UNBOUND&gt;
714Fax:#&lt;UNBOUND&gt;
715Email:#&lt;UNBOUND&gt;
716Address:#&lt;UNBOUND&gt;
717City:#&lt;UNBOUND&gt;
718Province:#&lt;UNBOUND&gt;
719Postal code:#&lt;UNBOUND&gt;
720
721</pre>
722
723
724
725</div>
726
727<div id="outline-container-6.1" class="outline-3">
728<h3 id="sec-6.1">6.1 Described CLOS objects an the EDITABLE description</h3>
729<div id="text-6.1">
730
731
732<p>
733The slots of an object are SETF'able places, and LoL takes
734advantage of that to provide EDITABLE descriptions
735automatically. When the EDITABLE description is active, and editor
736will be presented. The REPL based editor is pretty basic, but still
737useful. The HTML based editor will be described later.
738</p>
739
740
741
742<pre class="src">(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">edit-object</span> (object <span style="color: #228b22;">&amp;rest</span> args)
743 (<span style="color: #a020f0;">with-active-descriptions</span> (editable)
744 (apply #'display t object args)))
745
746(<span style="color: #a020f0;">let</span> ((object (make-instance 'person)))
747 (edit-object object)
748 (terpri)
749 (display t object))
750
751<span style="color: #b22222;">;; </span><span style="color: #b22222;">What follows are prompts and the information i entered
752</span>
753First name:Drew
754
755Last name:Crampsie
756
757Company name:The Tech Co-op
758
759Date of birth:1978-07-31
760
761Phone:555-5555
762
763Fax:555-5555
764
765Email:drewc@tech.coop
766
767Address:s/v Kanu, Lower Fraser River
768
769City:Richmond
770
771Province:BC
772
773Postal code:V1V3T6
774
775<span style="color: #b22222;">;; </span><span style="color: #b22222;">And this is what was displayed.
776</span>
777First name:Drew
778Last name:Crampsie
779Company name:The Tech Co-op
780Date of birth:1978-07-31
781Phone:555-5555
782Fax:555-5555
783Email:drewc@tech.coop
784Address:s/v Kanu, Lower Fraser River
785City:Richmond
786Province:BC
787Postal code:V1V3T6
788</pre>
789
790
791</div>
792
793</div>
794
795<div id="outline-container-6.2" class="outline-3">
796<h3 id="sec-6.2">6.2 Extending the generated description</h3>
797<div id="text-6.2">
798
799
800<p>
801We mentioned earlier that DESCRIBED-CLASS creates two descriptions :
802</p>
803
804
805<pre class="src">
806(find-description 'description-for-person)
807=&gt;
808#&lt;DESCRIPTION DESCRIPTION-FOR-PERSON {D296DE1}&gt;
809
810(find-description 'person)
811=&gt;
812#&lt;DESCRIPTION PERSON {ADFEDB1}&gt;
813
814(description-of (make-instance 'person))
815=&gt;
816#&lt;DESCRIPTION PERSON {ADFEDB1}&gt;
817
818</pre>
819
820
821
822<p>
823The reason for this is so we can redefine the description PERSON while
824keeping all the generated information from DESCRIPTION-FOR-PERSON.
825</p>
826<p>
827In this case, we will add an attribute, PERSON-AGE, that calculates
828a persons age based on the data in the date-of-birth slot.
829</p>
830
831
832
833
834
835
836
837
838
839
840
841
842</div>
843</div>
844
845</div>
846
847<div id="outline-container-7" class="outline-2">
848<h2 id="sec-7">7 Using Lisp-on-Lines for the Web.</h2>
849<div id="text-7">
850
851
852<p>
853LoL was developed, and is primarily used, for implementing
854data-driven web applications. As such, it comes with a host of
855features for doing just that.
856</p>
857<p>
858LoL, by default, implements its web portion on top of the wonderful
859UnCommon Web meta-framework. The LISP-ON-LINES-UCW ASDF system
860should be loaded, as it provides the features we're going to
861discuss.
862</p>
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877</div>
878</div>
879<div id="postamble"><p class="author"> Author: Drew Crampsie
880<a href="mailto:Drew Crampsie <drewc@tech.coop>">&lt;Drew Crampsie <drewc@tech.coop>&gt;</a>
881</p>
882<p class="date"> Date: 2009/07/27 01:46:25 PM</p>
883<p>HTML generated by org-mode 6.05 in emacs 22<p>
884</div></body>
885</html>