-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathclojlisp.pamphlet
1179 lines (1039 loc) · 44.7 KB
/
clojlisp.pamphlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass{book}
\usepackage{verbatim}
\usepackage{makeidx}
\usepackage{pstricks}
\usepackage{pst-node}
\usepackage{pst-tree}
\usepackage{hyperref}
\usepackage{graphicx}
% make underscore be an ordinary character
\catcode`\_=12
% we need to have an index
\makeindex
\raggedbottom
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Define tags to make refs and indexes pretty
\newcommand{\defclass}[1]{% e.g. \defclass{classname}
\label{#1}%
\index{#1}%
\index{Class!#1}%
\index{#1!Class}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Define tags to make refs and indexes pretty
\newcommand{\defsubclass}[2]{% e.g. \defsubclass{classname}{subclassname}
\label{#2}%
\index{#1\$#2}%
\index{Class!#2\ in\ \pageref{#1}}%
\index{#2,\ class in\ \pageref{#1}}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Define tags to make refs and indexes pretty
\newcommand{\definterface}[1]{% e.g. \definterface{ifname}
\label{#1}%
\index{#1}%
\index{Interface!#1}%
\index{#1!Interface}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Define tags to make refs and indexes pretty
\newcommand{\defmethod}[2]{% e.g. \defmethod{classname}{methodname}
\label{#2}%
\index{#1.#2}%
\index{#2,\ method\ in\ \pageref{#1}}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Define tags to make refs and indexes pretty
\newcommand{\implements}[2]{% e.g. \implements{class}{interface}
(#2 [\pageref{#2}])%
\index{Implements!#2,\ by\ #1}%
\index{#1!\ implements\ \pageref{#2}}%
\index{#2!\ implemented\ by\ \pageref{#1}}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Define tags to make refs and indexes pretty
\newcommand{\extends}[2]{% e.g. \extends{class}{interface}
(#2 [\pageref{#2}])%
\index{Extends!#2,\ by\ #1}%
\index{#1!\ extends\ \pageref{#2}}%
\index{#2!\ extended\ by\ \pageref{#1}}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Make our own sectioning commands
\newcommand{\defsection}[1]{% e.g. \defsection{sectionname}
\newpage%
\section{#1}%
\label{#1}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Make our own sectioning commands
\newcommand{\defsubsection}[1]{% e.g. \defsubsection{sectionname}
\subsection{{#1}}%
\label{#1}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Make our own references so we can have hyperlinks in pdfs
\newcommand{\refto}[1]{% e.g. \refto{name}
\index{#1}%
[\pageref{#1}] #1}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% a pretty box around some example text for quoting and examples
%%% boxed{boxcolor}{textcolor}{width}{text}
%%% boxed{yellow}{black}{4.6in}{text}
\providecommand\boxed[4]{% \boxed{boxcolor}{textcolor}{width}{text}
\begin{center}
\begin{tabular}{|c|}
\hline
\fcolorbox{#1}{#2}{
\begin{minipage}{#3}
\normalsize
{#4}\hfill
\end{minipage}}\\
\hline
\end{tabular}
\end{center}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% a colored box around quotes
%%% boxed{boxcolor}{textcolor}{width}{text}
%%% boxed{yellow}{black}{4.6in}{text}
\providecommand\quoteme[4]{% \boxed{boxcolor}{textcolor}{width}{text}
\begin{center}
\fcolorbox{#1}{#2}{
\begin{minipage}{#3}
\normalsize
{#4}\hfill
\end{minipage}}\\
\end{center}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% define the text and background colors for REPL boxes
\definecolor{ExampleTextColor}{rgb}{0.5 1.0 1.0}
\definecolor{ExampleBackColor}{rgb}{0.5.0.0 0.0}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% a colored box around quotes
%%% boxed{boxcolor}{textcolor}{width}{text}
%%% boxed{yellow}{black}{4.6in}{text}
\providecommand\forexample[1]{% \boxed{boxcolor}{textcolor}{width}{text}
\begin{center}
\fcolorbox{ExampleBackColor}{ExampleTextColor}{
\begin{minipage}{4.6in}
\normalsize
{#1}\hfill
\end{minipage}}\\
\end{center}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% REPL shows a prompt line and the response
%%% e.g. repl{(+ 2 3)}{5}
\providecommand\repl[2]{% \repl{input}{output}
\forexample{\noindent$>$\ {#1}\\{#2}}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% The literate environments commands %%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% The begin{chunk} environment
\newenvironment{chunk}[1]{% we need the chunkname as an argument
{\ }\newline\noindent% make sure we are in column 1
%{\small $\backslash{}$begin\{chunk\}\{{\bf #1}\}}% alternate begin mark
\hbox{\hskip 2.0cm}{\bf --- #1 ---}% mark the beginning
\verbatim}% say exactly what we see
{\endverbatim% process \end{chunk}
\par{}% we add a newline
\noindent{}% start in column 1
\hbox{\hskip 2.0cm}{\bf ----------}% mark the end
%$\backslash{}$end\{chunk\}% alternate end mark (commented)
\par% and a newline
\normalsize\noindent}% and return to the document
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% the getchunk command
\providecommand{\getchunk}[1]{%
\noindent%
{\small $\backslash{}$begin\{chunk\}\{{\bf #1}\}}% mark the reference
\index{{#1}}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% make the chunk font smaller
\chardef\atcode=\catcode`\@
\catcode`\@=11
\renewcommand{\verbatim@font}{\ttfamily\small}
\catcode`\@=\atcode
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% we need a single column index so write our own
\renewenvironment{theindex}{
{\Huge {\bf {\hskip 1.0in}Index}}%
\thispagestyle{plain}% \parindent\z@%
\begin{itemize}%
\setlength{\itemsep}{1pt}%
\setlength{\parskip}{0pt}%
\setlength{\parsep}{0pt}%
}{\end{itemize}\clearpage}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% we need a packed itemize so write our own
\newenvironment{packeditemize}{%
\begin{itemize}%
\setlength{\itemsep}{1pt}%
\setlength{\parskip}{0pt}%
\setlength{\parsep}{0pt}%
}{\end{itemize}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% leave notes for future work
\newcommand{\tpdhere}[1]{% e.g. \tpdhere{Some note}
{\bf TPDHERE: #1}%
\index{TPDHERE!{#1}}}
\begin{document}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{titlepage}
\center{\includegraphics{clojureIcon.eps}}
\vskip 0.1in
\vskip 0.1in
\center{{\Huge{Clojure in Common Lisp}}}
\vskip 0.1in
\center{\huge{Timothy Daly}}
\vskip 0.1in
\center{\large{\today}}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Make sure everyone gets credit
\begin{center}
\begin{tabular}{lll}
\end{tabular}
\end{center}
\vskip 0.1in
\end{titlepage}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Use roman numeral pages for frontmatter
\pagenumbering{roman}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% because I add lines to the toc, the toc is 4.5pts too wide
%%% so I use this hack to fix it -- TimDaly
\makeatletter
\renewcommand{\@pnumwidth}{2.75em}
\renewcommand{\@tocrmarg}{2.75em}
\makeatother
\tableofcontents
\vfill
\eject
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Make the forward be business block text style
\setlength{\parindent}{0em}
\setlength{\parskip}{1ex}
{\Large{\bf Foreword}}
\vskip .25in
Rich Hickey invented Clojure.
This is a fork of the project to build
Clojure in Common Lisp.
We would like to have these new lisp ideas available in a standard
common lisp environment. There will be some language changes due to
the loss of Java and some enhancements due to Common Lisp. This is
unavoidable but within the spirit of Clojure.
Every effort is made to give credit for any and all contributions.
We are also experimenting with literate
programming as a development and documentation technology.
Clojure is a break with the past traditions of Lisp. This literate
fork is a break with the past traditions of code development. As such
it is intended as an experiment, not a replacement or competition with
the official version of Clojure.
\vskip .25in
%\noindent
Timothy Daly\\
November 10, 2011 ((iHy))
\vfill
\eject
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Start using regular numbers
\pagenumbering{arabic}
\setcounter{chapter}{0} % Chapter 1
%\textunderscore
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% fix the preface in the table of contents
\frontmatter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Preface %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Make this fake chapter show up in the table of contents
\cleardoublepage
\phantomsection
{\bf {\Large Preface: Why Literate Programming}}
\addcontentsline{toc}{chapter}{Preface: Why Literate Programming}
{\vbox {\vskip 0.3in}}
This is a literate program, inspired by Donald Knuth \cite{Knu84}. It is
intended to be read like a novel from cover to cover. The ideas are
expressed clearly but they are grounded in the actual source code.
The code in this documment is the executable source. The chapter
\refto{building} on Building ClojLisp gives the procedure for building
a running system from the enclosed sources.
Most programmers are still locked into the idea of making a program
out of a large pile of tiny files containing pieces of programs.
They do not realize that this organization was forced by the fact
that machines like the PDP 11 only had 8k of memory and a limit
of 4k buffers in the editor. Thus there was a lot of machinery built
up, such as overlay linkers, to try to reconstruct the whole program.
The time has come to move into a more rational means of creating and
maintaining programs. Knuth suggested we write programs like we write
literature, with the idea that we are trying to communicate the ideas
to other people. The fact that the machine can also run the programs
is a useful side-effect but not important.
Very few people have seen a literate program so this is intended
as a complete working example, published in book form. The intent
is that you can sit and read this book like any other novel. At
the end of it you will be familiar with the ideas and how those
ideas are actually expressed in the code.
If programmers can read it and understand it then they can maintain
and modify it. The ideas will have been communicated. The code will
be changed to match changes in the idea. We will all benefit.
I've tried to make it as simple as possible.
Try it once, you might like it.
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Make this fake section show up in the table of contents
{\bf {\large Steps to build ClojLisp}}
\addcontentsline{toc}{section}{Steps to build Clojure}
{\vbox {\vskip 0.1in}}
{\bf Step 1}
We will be using SBCL as the initial development environment so you
need to get an SBCL version running.
You also need the C program \refto{tangle.c} which you can clip
from this file using a text editor and save it as tangle.c. If you
got this file from a git repository the tangle.c program is probably
already available. The tangle program is used to extract the source
files from this document.
{\bf Step 2}
Compile tangle.c to create a function called tangle.
\begin{verbatim}
gcc -o tangle tangle.c
\end{verbatim}
{\bf Step 3}
Run tangle to extract the \refto{Makefile} from this document.
\begin{verbatim}
./tangle clojure.pamphlet Makefile >Makefile
\end{verbatim}
{\bf Step 4}
Running make will create a PDF of the documentation and will
create the clojlisp.lisp file containing the latest source code.
\begin{verbatim}
make
\end{verbatim}
{\bf Step 5}
Start lisp, change to the new package, and start the REPL.
\begin{verbatim}
sbcl
(load "clojlisp.lisp")
(in-package "CLOJLISP")
(clojlisp)
\end{verbatim}
The new REPL knows almost nothing at all. In particular, it has no
functions and no symbols defined yet so you need to qualify everything.
For example,
\begin{verbatim}
(common-lisp::+ 2 3)
\end{verbatim}
To exit the program type:
\begin{verbatim}
(sb-ext:quit)
\end{verbatim}
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Make this fake section show up in the table of contents
{\vbox {\vskip 0.1in}}
{\bf {\large Steps to change Clojure}}
\addcontentsline{toc}{section}{Steps to change Clojure}
{\vbox {\vskip 0.1in}}
Working in literate programming is simple. You need an editor and a
command line. Make changes directly to this document using the editor
and then type
\begin{verbatim}
make
\end{verbatim}
This will destroy the old source and rebuild the clojlisp.lisp file.
If you change the Makefile section in the document you will have to
extract it before the changes take effect:
\begin{verbatim}
./tangle clojlisp.pamphlet Makefile >Makefile
\end{verbatim}
If you are working in Linux it is very effective to use emacs
with a split screen. Start a command line in one buffer and a
shell in the other buffer. If you start xdvi running in the
background you will immediately see the ``printed'' form of the
document every time you switch to the xdvi window.
\begin{verbatim}
xdvi clojlisp.dvi &
\end{verbatim}
The same trick can be used with the PDf file instead. Both xdvi and
xpdf will update automatically when the file is changed on disk.
\begin{verbatim}
xpdf clojlisp.pdf &
\end{verbatim}
Resist the urge to edit the clojlisp.lisp file. It is only there for
the computer. Edit this file directly. Be sure to write words to
communicate your ideas just as you would when writing a book.
The machine code is secondary and intended to make the ideas concrete.
%%% Tim Daly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Make this fake section show up in the table of contents
{\vbox {\vskip 0.1in}}
{\bf {\large Why Bother?}}
\addcontentsline{toc}{section}{Why Bother?}
{\vbox {\vskip 0.1in}}
Why bother with such a difficult method of programming? Because
worthwhile programs should ``live''.
Programs ``live'' because people maintain them. Maintaining and
modifying code correctly requires that you understand why the program
is written as it is, what the key ideas that make the program work,
and why certain, not very obvious, pieces of code exist. Programmers
almost never write this information down anywhere. Great ideas are
invented, the code is written, a man page of documentation is created,
and the job is done.
Well, almost. What does is mean for a program to ``live''? How does a
program survive once the original developers leave the project? There
are many sources of information but almost no source of knowledge.
New programmers don't know what the ``elders'' know. In order to ``live''
and continue to grow there has to be a way to transmit this knowledge.
Literate programming is Knuth's proposed idea for moving from the
world of ideas to the world of information. This is not simply another
documentation format. This is meant to be {\bf Literature}. The ideas
are presented, the implications are explored, the tradeoffs are discussed,
and the code is ``motivated'', like characters in a novel.
You are encouraged to write or rewrite sections of this document to
improve the communication with the readers.
``But I have to learn latex!''. Well, for this document you do.
But \LaTeX is no more than a document markup language like
HTML and it is no harder to learn. It gives you the added advantage
that you have a real language for publishing real documents. Most
books are typeset with this technology and a lot of conferences
and Journals require it. If you can learn Clojure, you can learn
\LaTeX. If you're a programmer you will always need to continue
to learn, at least until you retire into management.
Having used literate programming for years I have collected some key
quotes that might stimulate your interest.
\quoteme{gray}{yellow}{4.6in}
{\vskip 0.1cm
I believe that the time is ripe for significantly better documentation
of programs, and that we can best achieve this by considering programs
to be works of literature. Hence, my title ``Literate Programming''.
Let us change our traditional attitude to the construction of programs.
Instead of imagining that our main task is to instruct a computer what to
do, let us concentrate on explaining to human beings what we want a
computer to do.
{\bf --Donald Knuth ``Literate Programming (1984)''}}
\quoteme{gray}{yellow}{4.6in}
{\vskip 0.1cm
Step away from the machine. Literate programming has nothing to do with
tools or style. It has very little to do with programming. One of the
hard transitions to literate programming is ``literate thinking''.
{\bf --Timothy Daly in Lambda the Ultimate (2010)}}
\quoteme{gray}{yellow}{4.6in}
{\vskip 0.1cm
The effect of this simple shift of emphasis can be so profound as to
change one's whole approach to programming. Under the literate programming
paradigm, the central activity of programming becomes that of conveying
meaning to other intelligent beings rather than merely convincing the
computer to behave in a particular way. It is the difference between
performing and exposing a magic trick.
{\bf --Ross Williams, FunnelWeb Tutorial Manual}}
\quoteme{gray}{yellow}{4.6in}
{\vskip 0.1cm
Another thing I've been enjoying lately is literate programming. Amazingly
it turns out to be faster to write a literate program than an ordinary
program because debugging takes almost no time.
{\bf --Bill Hart, SAGE Mailing list, May 3, 2010}}
\quoteme{gray}{yellow}{4.6in}
{\vskip 0.1cm
The conversation is much more direct if the Design Concept per se, rather
than derivative representatives or partial details, is the focus.
{\bf --Fred Brooks, ``The Design of Design''}}
\quoteme{gray}{yellow}{4.6in}
{\vskip 0.1cm
We are banning the old notion of literate programming that I used when
developing \TeX{}82 because documentation has proven to be too much of
a pain.
{\bf --Donald Knuth TUG 2010}}
\quoteme{gray}{yellow}{4.6in}
{\vskip 0.1cm
Once upon a time I took great care to ensure that \TeX{}82 would be truly
archival so that results obtainable today would produce the same output
50 years from now but that was manifestly foolish. Let's face it, who is
going to care one whit for what I do today after even 5 years have
elapsed, let alone 50. Life is too short to re-read anything anymore
in the internet age. Nothing over 30 months old is trustworthy or
interesting.
{\bf --Donald Knuth TUG 2010}}
\mainmatter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% From ideas to implementation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{From ideas to implementation}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\defsection{}
\chapter{The clojlisp package}
We are defining a lisp-in-lisp so there will be a significant number
of symbol collisions. We have to be very careful to only import symbols
that do not conflict.
\begin{chunk}{defpackage clojlisp}
#+:AKCL (make-package "COMMON-LISP" :use '("LISP"))
#+:AKCL (in-package "USER")
#+:SBCL (declaim (sb-ext:muffle-conditions style-warning))
#+:SBCL (declaim (sb-ext:muffle-conditions warning))
#+:SBCL (declaim (sb-ext:muffle-conditions sb-ext:compiler-note))
(make-package "CLOJLISP")
(in-package "CLOJLISP")
\end{chunk}
\chapter{Imported functions}
We import some functions from other packages which have useful definitions
or which match the semantics of Clojure.
The {\tt bye} function can be used to exit the lisp system.
\begin{chunk}{imported functions}
#+AKCL (lisp::defun bye () (si::bye))
#+SBCL (common-lisp::defun clojlisp::bye () (sb-ext:quit))
\end{chunk}
\chapter{The Reader}
The reader uses the common lisp reader.
\begin{chunk}{defun read}
(common-lisp::defun
clojlisp::read (
common-lisp::&optional input-stream eof-error-p eof-value recursive-p)
(common-lisp::case
(common-lisp::peek-char
common-lisp::nil input-stream eof-error-p eof-value recursive-p)
((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)
(common-lisp::print "number")
(common-lisp::terpri)
(common-lisp::read-char))))
\end{chunk}
\chapter{The Evaluator}
The evaluator uses the common lisp evaluator.
\begin{chunk}{defmacro eval}
(common-lisp::defmacro clojlisp::eval (x) `(common-lisp::eval ,x))
\end{chunk}
\chapter{The Printer}
The printer uses the common lisp printer.
\begin{chunk}{defun print}
(common-lisp::defun clojlisp::print (x) (common-lisp::print x))
\end{chunk}
\chapter{The Clojlisp REPL}
By typing
\begin{verbatim}
(load "clojlisp.lisp")
(in-package "CLOJLISP")
(clojlisp)
\end{verbatim}
you have a read-eval-print loop (REPL). The REPL knows almost nothing
about anything so it can be quite painful. You need to qualify symbols
that come from any other package at the moment. A working example is:
\begin{verbatim}
(common-lisp::+ 2 3)
\end{verbatim}
\begin{chunk}{defun repl}
(common-lisp::defun clojlisp::clojlisp ()
(common-lisp::loop
(clojlisp::print
(clojlisp::eval
(clojlisp::read)))
(common-lisp::terpri)))
\end{chunk}
\chapter{Building ClojLisp}
\label{building}
This is the whole source listing in one file.
If you define a new chunk, add it here.
\defsection{The env global environment}
\label{globalEnv}
We wrap all of the code in a {\tt let} construct which defines a {\tt env}
variable. This variable is accessible from everywhere. It is intended to
contain ``globally scoped information'' such as the current reader setting.
Default values are kept in the {\tt env} variable.
The {\tt env} variable is a stack. Managing the {\tt env} as a stack allows
us to temporarily push information that overrides existing information.
Functions that require temporary bindings can wrap a let around the function
that rebinds {\tt env} with new information cons-ed on the front of the stack.
Leaving the let allows the bindings to pop.
\defsection{The whole thing}
\begin{chunk}{clojlisp}
\getchunk{defpackage clojlisp}
\getchunk{imported functions}
(common-lisp::let (env)
\getchunk{defun read}
\getchunk{defmacro eval}
\getchunk{defun print}
\getchunk{defun repl}
)
\end{chunk}
\defsection{tangle.c}
The tangle program extract pieces of this document and puts them in a file.
Any piece that can be extracted is called a ``chunk''. Each chunk is in a
\LaTeX {\bf chunk} environment. The tangle program expects two arguments,
the name of this file and the chunk to extract as in:
\begin{verbatim}
./tangle clojure.pamphlet clojlisp
\end{verbatim}
It outputs the chunk to standard output. To be useful, redirect the
output to a file as in:
\begin{verbatim}
./tangle clojure.pamphlet clojlisp >clojlisp.lisp
\end{verbatim}
This trivial function walks the document looking for the named chunk.
When it finds it the chunk is printed to standard output. The only
exception is if the chunk contains a {\bf getchunk} markup. This is
used to embed other chunks inline. So tangle will pause the output of
the current chunk, find and print the getchunk reference, and then continue.
Of course, if the getchunk reference contains an embedded getchunk we
recurse into it. This program could be a lot smarter $\ldots$ but why?
\begin{chunk}{tangle.c}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#define DEBUG 0
/* forward reference for the C compiler */
int getchunk(char *chunkname);
/* a memory mapped buffer copy of the file */
char *buffer;
int bufsize;
/* return the length of the next line */
int nextline(int i) {
int j;
if (i >= bufsize) return(-1);
for (j=0; ((i+j < bufsize) && (buffer[i+j] != '\n')); j++);
return(j);
}
/* output the line we need */
int printline(int i, int length) {
int j;
for (j=0; j<length; j++) { putchar(buffer[i+j]); }
printf("\n");
}
/* handle begin{chunk}{chunkname} */
/* is this chunk name we are looking for? */
int foundchunk(int i, char *chunkname) {
if ((strncmp(&buffer[i+14],chunkname,strlen(chunkname)) == 0) &&
(buffer[i+13] == '{') &&
(buffer[i+14+strlen(chunkname)] == '}')) return(1);
return(0);
}
/* handle end{chunk} */
/* is it really an end? */
int foundEnd(int i) {
if ((buffer[i] == '\\') &&
(strncmp(&buffer[i+1],"end{chunk}",10) == 0)) {
return(1);
}
return(0);
}
/* handle getchunk{chunkname} */
/* is this line a getchunk? */
int foundGetchunk(int i, int linelen) {
int len;
if (strncmp(&buffer[i],"\\getchunk{",10) == 0) {
for(len=0; ((len < linelen) && (buffer[i+len] != '}')); len++);
return(len-10);
}
return(0);
}
/* Somebody did a getchunk and we need a copy of the name */
/* malloc string storage for a copy of the getchunk name */
char *getChunkname(int k, int getlen) {
char *result = (char *)malloc(getlen+1);
strncpy(result,&buffer[k+10],getlen);
result[getlen]='\0';
return(result);
}
/* print lines in this chunk, possibly recursing into getchunk */
int printchunk(int i, int chunklinelen, char *chunkname) {
int j;
int k;
int linelen;
char *getname;
int getlen = 0;
for (k=i+chunklinelen+1; ((linelen=nextline(k)) != -1); ) {
if (DEBUG==2) {
printf(">>>>"); printline(k,linelen); printf("<<<<\n");
}
if ((getlen=foundGetchunk(k,linelen)) > 0) {
getname = getChunkname(k,getlen);
getchunk(getname);
free(getname);
k=k+getlen+12l;
} else {
if ((linelen >= 11) && (foundEnd(k) == 1)) {
if (DEBUG) { printf("=================\\end{%s}\n",chunkname); }
return(k+12);
} else {
if (DEBUG==2) {
printf("======== printchunk else %d %d\n",k,linelen);
}
printline(k,linelen);
k=k+linelen+1;
}
}}
if (DEBUG==2) {
printf("=================\\out{%s} %d\n",chunkname,k);
}
return(k);
}
/* find the named chunk and call printchunk on it */
int getchunk(char *chunkname) {
int i;
int j;
int linelen;
int chunklen = strlen(chunkname);
for (i=0; ((linelen=nextline(i)) != -1); ) {
if (DEBUG==2) {
printf("----"); printline(i,linelen); printf("----\n");
}
if ((linelen >= chunklen+15) && (foundchunk(i,chunkname) == 1)) {
if (DEBUG) {
fprintf(stderr,"=================\\getchunk(%s)\n",chunkname);
}
i=printchunk(i,linelen,chunkname);
} else {
i=i+linelen+1;
}
}
if (DEBUG) {
fprintf(stderr,"=================getchunk returned=%d\n",i);
}
return(i);
}
/* memory map the input file into the global buffer and get the chunk */
int main(int argc, char *argv[]) {
int fd;
struct stat filestat;
if ((argc < 2) || (argc > 3)) {
perror("Usage: tangle filename chunkname");
exit(-1);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
perror("Error opening file for reading");
exit(-2);
}
if (fstat(fd,&filestat) < 0) {
perror("Error getting input file size");
exit(-3);
}
bufsize = (int)filestat.st_size;
buffer = mmap(0,filestat.st_size,PROT_READ,MAP_SHARED,fd,0);
if (buffer == MAP_FAILED) {
close(fd);
perror("Error reading the file");
exit(-4);
}
getchunk(argv[2]);
close(fd);
return(0);
}
\end{chunk}
\defsection{Makefile}
This book is actually a literate program\cite{Knu84} and can contain
executable source code. In particular, the Makefile for this book
is part of the source of the book and is included below.
You can extract this chunk with an editor or use the tangle function:
\begin{verbatim}
./tangle clojlisp.pamphlet Makefile >Makefile
\end{verbatim}
\begin{chunk}{Makefile}
PROJECT=clojlisp
TANGLE=tangle
LATEX=/usr/bin/latex
MAKEINDEX=/usr/bin/makeindex
UUDECODE=uudecode
PDF=dvipdf
all:
${TANGLE} ${PROJECT}.pamphlet ${PROJECT} >${PROJECT}.lisp
${TANGLE} ${PROJECT}.pamphlet clojureIcon.eps.uu >clojureIcon.eps.uu
${UUDECODE} clojureIcon.eps.uu
${LATEX} ${PROJECT}.pamphlet
${MAKEINDEX} ${PROJECT}.idx
${LATEX} ${PROJECT}.pamphlet
${PDF} ${PROJECT}.dvi
rm -f ${PROJECT}.aux ${PROJECT}.idx ${PROJECT}.ilg ${PROJECT}.ind
rm -f ${PROJECT}.log ${PROJECT}.out ${PROJECT}.toc ${PROJECT}.aps
rm -f ${PROJECT}.dvi *.eps.uu *~ clojureIcon.eps
\end{chunk}
\defsection{The Clojure Icon}
This document uses the Clojure Icon on the front page.
This is a uuencoded, encapsulated postscript version of the icon.
You can recreate the {\bf clojureIcon.eps} file with:
\begin{verbatim}
./tangle clojlisp.pamphlet clojureIcon.eps.uu >clojureIcon.eps.uu
uudecode clojureIcon.eps.uu
\end{verbatim}
\begin{chunk}{clojureIcon.eps.uu}
begin 644 clojureIcon.eps
M)2%04RU!9&]B92TS+C`@15!31BTS+C`*)25#<F5A=&]R.B!'24U0(%!O<W13
M8W)I<'0@9FEL92!P;'5G:6X@5B`Q+C$W(&)Y(%!E=&5R($MI<F-H9V5S<VYE
M<@HE)51I=&QE.B!C;&]J=7)E+6EC;VXN97!S"B4E0W)E871I;VY$871E.B!-
M;VX@3F]V(#$T(#(Q.C,U.C0S(#(P,3$*)25$;V-U;65N=$1A=&$Z($-L96%N
M-T)I=`HE)4QA;F=U86=E3&5V96PZ(#(*)25086=E<SH@,0HE)4)O=6YD:6YG
M0F]X.B`Q-"`Q-"`Q,34@,3$U"B4E16YD0V]M;65N=',*)25"96=I;E!R;VQO
M9PHE(%5S92!O=VX@9&EC=&EO;F%R>2!T;R!A=F]I9"!C;VYF;&EC=',*,3`@
M9&EC="!B96=I;@HE)45N9%!R;VQO9PHE)5!A9V4Z(#$@,0HE(%1R86YS;&%T
M92!F;W(@;V9F<V5T"C$T+C$W,S(R.#,T-C0U-C8Y-"`Q-"XQ-S,R,C@S-#8T
M-38V.30@=')A;G-L871E"B4@5')A;G-L871E('1O(&)E9VEN(&]F(&9I<G-T
M('-C86YL:6YE"C`@.3DN.3DY.3DY.3DY.3DY.3@V('1R86YS;&%T90HY.2XY
M.3DY.3DY.3DY.3DY.#8@+3DY+CDY.3DY.3DY.3DY.3DX-B!S8V%L90HE($EM
M86=E(&=E;VUE=')Y"C$P,"`Q,#`@.`HE(%1R86YS9F]R;6%T:6]N(&UA=')I
M>`I;(#$P,"`P(#`@,3`P(#`@,"!="B4@4W1R:6YG<R!T;R!H;VQD(%)'0BUS
M86UP;&5S('!E<B!S8V%N;&EN90HO<G-T<B`Q,#`@<W1R:6YG(&1E9@HO9W-T
M<B`Q,#`@<W1R:6YG(&1E9@HO8G-T<B`Q,#`@<W1R:6YG(&1E9@I[8W5R<F5N
M=&9I;&4@+T%30TE).#5$96-O9&4@9FEL=&5R("]2=6Y,96YG=&A$96-O9&4@
M9FEL=&5R(')S='(@<F5A9'-T<FEN9R!P;W!]"GMC=7)R96YT9FEL92`O05-#
M24DX-41E8V]D92!F:6QT97(@+U)U;DQE;F=T:$1E8V]D92!F:6QT97(@9W-T
M<B!R96%D<W1R:6YG('!O<'T*>V-U<G)E;G1F:6QE("]!4T-)23@U1&5C;V1E
M(&9I;'1E<B`O4G5N3&5N9W1H1&5C;V1E(&9I;'1E<B!B<W1R(')E861S=')I
M;F<@<&]P?0IT<G5E(#,*)25"96=I;D1A=&$Z("`@("`@("`@.3DU,R!!4T-)
M22!">71E<PIC;VQO<FEM86=E"E-C/3-^/@I38STS?CX*4V,],WX^"E-C/3-^
M/@I38STS?CX*4V,],WX^"E-C/3-^/@I38STS?CX*4V,],WX^"E-C/3-^/@I3
M8STS?CX*4V,],WX^"E-C/3-^/@I38STS?CX*4V,],WX^"F<F1#9+95H^*FA$
M/D`Y.T0Q7"M596(N5G%*+'X^"F<F1#9-:31U4FI/;FI0,T]E2R)P:3IK<2E*
M+'X^"F<F1#93<"1#;"1H/BQ<+&@[6U9A<"8S4T1*+'X^"F@C0$@A5&TL;2LA
M9$,_76@C1&U^/@IH(T!(+EP]*6`X(6@D4DYH(T1M?CX*:"-`2$EL+S%M7"%O
M3C@V:"-$;7X^"FAU/&,D45A=*5HA2SXT6G,J='X^"FAU/&,Q65]H3&XA3CU:
M+G,J='X^"FAU/&-,:TTC*$XA5&!K,',J='X^"FER.2E16$11;W4A8B\W<FER
M/4Y^/@II<CDI4UYL9%0L(68]7UUI<CU.?CX*:7(Y*5EM*W!842%O(2,[:7(]
M3GX^"FI3;SM(45A<8%`A3$XJ-',J='X^"FI3;SM-65]H+F0A3S(E4G,J='X^
M"FI3;SM8:TTB7T0A52<]/W,J='X^"FLU4$U56$-"9V$A350R2W,J='X^"FLU
M4$U77FMP77`A4"5M9',J='X^"FLU4$U=;2M5*T4A53E21G,J='X^"FM0:U,K
M0&(B45U`7V@Q+$HL?CX*:U!K4SA-.DDN6$TY=$=C2BQ^/@IK4&M34V<]/6=6
M9T`T.RI*+'X^"FPR3&573C9T8"Y+)TU6(THL?CX*;#),95E7-G`N<U4D<3='
M2BQ^/@IL,DQE7VI/*51<:7%H<#Y*+'X^"FQ-9VXN0&%!+5=`82(G.DHL?CX*
M;$UG;CM-.6=?4DTZ:"MN2BQ^/@IL36=N5F<\7$-09T!/5C!*+'X^"FQI+7-9
M8C\K8C)L:3)*?CX*;&DM<W!B0TM9=&QI,DI^/@IL:2UT3&),8V=8;&DR2GX^
M"FU*9#1;3C8L,"9'4#%!)THL?CX*;4ID-%U7-B=3:U)*-BM+2BQ^/@IM2F0T
M8VI.-B14:'4R<T)*+'X^"FUF*CU<1TLS961'3R)6<DHL?CX*;68J/5Y212=J
M6E))0E-$2BQ^/@IM9BH]9&AO1D!-:'1L9$!*+'X^"FXL149=1TLA66)`8S9?
M5$HL?CX*;BQ%1E]21&I>6$T\1D`M2BQ^/@IN+$5&96AO-#1+9T$H+CI*+'X^
M"FY'8$]>1TID36!`8S9B54HL?CX*;D=@3V!21%A25DT\1D,N2BQ^/@IN1V!/
M9FAO(BA)9T$H,3M*+'X^"FYC)EA?1U!K4$-$/F8E9$!A)7!41#XA2"%*+'X^
M"FYC)EAA4DI?53E/;SIS4DTY3$U/3VY<1$=*+'X^"FYC)EAG:'4I*RQH/E$]
M-6<\03%-:#Y1;41*+'X^"FYC)F,Z/4-25S1I.RI"5&DT=%MR8W)>/&UP)28M
M-7X^"FYC)F-<2E9G5EAK4#XL6VM+<$=Q9"(I-&-P6UP_-WX^"FYC)F1-9EPU
M3EAQ(F%P;'$A9$HF9"M!0E9R551U/7X^"F\I06-82R,D<%8A5#D]03TY3BEL
M6$]:."MR<F@Y,5A'9U=//3DK/$YS*G1^/@IO*4%C<54A5S\P(54D76%*2%5H
M+EYU-$11<G)H3D->;S,K44I(,ED^<RIT?CX*;RE!9%-I<&-,/"%6:VI49D5"
M<&AM+DPO3G)R:2QI;2Q:;6!F1'0B)W,J='X^"F]$7&I,96$\03]O<#AC:54C
M/DI`(6]48FAK=5MQ96]$83U^/@IO1%QJ4VDY9T]*<%14-"I<145$7B%P0"A5
M;"4F:4UO1&$]?CX*;T1<:F1P)$UB7W)41&AE;#%J9DLA<C(D.6PN/R(F;T1A
M/7X^"F==)3DS;&DN(B]+)TA'/&5B)FQL?CX*9UTE.3IL:2XB/%4D0#$O:3I2
M)B)^/@IG724Y2VQI+B)7:7`L+G)P)3@Y-WX^"E]:)UEE1#QT0"I$/B%4)4HL
M?CX*7UHG67!/;4E7(D]N7%!+2BQ^/@I?6B=:,&@\8&)P:#Y2)$A*+'X^"E\C
M1D<Z0&12-W15)5-'.7X^"E\C1D=.33TC:6]<1F]L4'X^"E\C1D@E9S]M36UL
M,5`H+'X^"F8I1VU*9W)14F=R2R4O4EA-3EUE<2,Z0E%'3SA+-&5B.2-N?CX*
M9BE';4QK:#TH:G).;%Y`830Y1$UQ(SI"6%))+%`J:3ID,B1^/@IE+%0T0G!!
M63!G:'-+)7)P)4I%.7X^"FQ-9VM.<C=,5T`A,ET]3"%I/4A"<5EP5&A19U)R
M54LH9C1P?CX*;$UG:U=R.5@E5"$U94(X(6Q&(6]Q67!4:EEJ4B9"525<33I^
M/@IL36=K1W(V-&0T;RE!1F$A5T0S3&9$<W$I<RIT?CX*;68J0U5=.$-*)4!F
M5V4L<G)-;EUO.&HD/V%3/E<S(3$S*U4A-5-`+THL?CX*;68J0UYH.%%I(5EL
M3D=,<G)-=2QO/%Q3,&=!.EM'(3-K;4(A-SI+/THL?CX*;68J0TY6+D1M9C$G
M(6$W<S<M*F!R<D0V369$=$8X<RIT?CX*;D=@3S=-64-47%0H1'->:"%P22Q1
M9'1S-"$Q,RY6(2Q?2S%*+'X^"FY'8$]08%8V5CMC3%\F.6MJ8R)<7&`\4&0A
M,VMP0R$P4B152BQ^/@IN1V!/*$%B4G%;2BM%6"]R<5I1;VM/-R4G:#UP<B)^
M/@IO*4%A0TU9.DY;5"DX3FAP<SAA,W)R0D-P3SDI75]Q=3997VUO5%,J<2,^
M:GX^"F\I06%78%8M4#IC35)60W)50F1><G)#-S-::5-!2'%U-EHC;7-T2F-Q
M(SYJ?CX*;RE!83=!8DEK6DHL0C9);U=2;V!S-F9M7W)R1#9.9D1T1CES*G1^
M/@IO1%QF9V]J6W50<74V9F%63DE-.7%U-EUE46=G*#M4)T@T42$N<UU"(2Q?
M3C)*+'X^"F]$7&<^;W,B331Q=39F;VHT<E-F<74V76I<85IS+%XE*2(B(3(X
M;C4A,%(G5DHL?CX*;T1<9DQO94A-3'%U-F940RY$561Q6B0A7W%9<%%4;D-2
M8'-Q(SYJ?CX*<"8^)V--63%(6T0^(6DL(54_)TY/5#QU,')R0RXO3SDH7C5R
M.U%F:D!D;4HB96)4-7%^/@IP)CXG:&!6)$HZ6V5F<24A5FM/36==-G!"<G)#
M9$%::5)@+7([469L33T_)G)I.RI$)WX^"G`F/B=@06)`95HU4")A4"%3<%U1
M-V9>+7-S-F9M8')R3BE0;D-2839Q/EES?CX*<$%9,&1*1FT]3V--6UQ#;$)Q
M23(A.48H6"%6:2--3SDH7C5R.U%C26XU;UM7<3Y9<WX^"G!!63!I7R(];#-K
M4%D^7'!T:V\G(3L_/VHA5R=`<5II4F`M<CM18U1N.CI31'$^67-^/@IP05DP
M83U3*S]+7EQN*C1H+$8R0"$W0UU$;4ID(E\A.S5J-B$Y83%82BQ^/@IP7'0Y
M94I&;3U/4&PQ3UYP;4-O/R%,5UI;<G)"6'5/.2A>/'([46)@;C5O7&!Q674G
M?CX*<%QT.6I?(CUL,V%O*2\^<E-)1"LA5"IE47)R0T8V6FE28#)R.U%C)&XZ
M.E0V<5EU)WX^"G!<=#EB/5,K/TM%<CYQ/&]-8E16(44X6&=S-E1A7G)R1#9/
M9D1T;4AS*G1^/@IP7'0U6&\T)61E<CM18F]P;%!17W([46-E;3YQ0$9Q(S$S
M;F]J6T=N(35323)*+'X^"G!<=#8X;SQ!.V=R.U%C5W!T4&PT<CM18VIM0F-O
M,G%99T5P<%!*16LA-SI40DHL?CX*<%QT-39O+F<]+7([46(S<&19/3AQ=3\D
M7G([469R9T`\97%N1SPP.'X^"G$C.C\K;S0E9"IR.U%C/'`U;T`Y<CM18G5M
M/G$]87([46)U;E$U9$UQ674G?CX*<2,Z/TUO/$$[2G([46-B<#UO6D%R.U%C
M.VU"8VQ$<CM18S1N555</7%9=2=^/@IQ(SH^:F\N9SPV<CM18FQP+B,L,7([
M6BI><CM18V!N7FUJ)G%9=2=^/@IQ/E5+7D0]7S8[<"8T;6IN8B8B151$7%UH
M96$O0'1L35Y?8&]J6T=N<5EU)WX^"G$^54MG6V4D82AQ66=%;W%T.%]%:3M%
M5%1J-E@L46YB<DEG<%!*16MQ674G?CX*<3Y52U<U4"17,6\I.%)G:VLN1D<_
M36IC:')Q=6-S<E,D96]Q674G?CX*<3Y51U!O-"5C;'([46,A;U0Y+BER.U%B
M8&T^<3U,<CM18F!N435E07%U.S!^/@IQ/E5(-F\\03M`<CM18UEO7#E(.W([
M46,M;4)C;#9R.U%C)&Y555QU<74[,'X^"G$^54<K;RYG.W%R.U%B/F],06YM
M<CM:*EYR.U%C6VY>;6HW<74[,'X^"G%9<%%*;FU?6U!R5FQL66\X<R1&<CM1
M8RYM(U8U+7)6;&Q5;E$U9&UQ=3LP?CX*<5EP45YO(28R77)6;&QK;T!S/RAR
M.U%C1&TG2&-:<E9L;%QN555<57%U.S!^/@IQ67!1/FYH3#-H<E9L;$9O,29D
M97([6BI><CM18VQN7FUJ+G%U.S!^/@IQ67!046\T)6-%<CM18RYN<E=Q+G)6
M;&Q1;2-6-%)R.U%B-FYL4&U$<74[,'X^"G%9<%$W;SQ!.RUR.U%C76\E6#8[
M<E9L;%UM)TAC.7([46):;G!P93=Q=3LP?CX*<5EP4"QO+F<[/G([46)5;FI@
M72)R.UHJ7G([46-1;R4S<R5Q=3LP?CX*<74V6E]N;5]:=')6;&QM;E<\9U)R
M.U%B8&TC5C4[<E9L:VMN;%!M)'%U.S!^/@IQ=39::&\A)C)$<E9L;')N7STM
M*W([46,M;2=(8V1R5FQL+6YP<&1T<74[,'X^"G%U-EI8;FA,,RAR5FQL:6Y/
M15,E<CM:*EYR.U%C76\E,W)R<74[,'X^"G%U-EEO;FU?6T9R5FQL2VX\(5\Y
M<E9L;"AM(U8T;7)6;&Q*;E$U96%R.U8Y?CX*<74V6D9O(28R6')6;&QG;D0B
M)#UR5FQL0&TG2&-,<E9L;%5N555=-W([5CE^/@IQ=3995&YH3#-;<E9L;"]N
M-"I+-W)6=3-?<CM18VEN7FUJ/W([5CE^/@IQ=399-6YM7UMM<E9L;"AN/"%>
M7G)6;&Q*;2-6-$MR.UHZ:"$W:"-)2BQ^/@IQ=39:*6\A)C)K<E9L;%QN1"(D
M+G)6;&Q8;2=(8S5R.UH[/"$Y(6542BQ^/@IQ=3987&YH3#0Y<E9L:TMN-"I*
M.W([6BI><CM:/#XA.S8Y:4HL?CX*<CM18TQN;5]:1'([46)A;CPA7CQR5FQL
M9FQ=1"9%(2UE(3DA-F(\/THL?CX*<CM18V!O(28R+'([46-2;D0B)"-R5FQL
M:VQA-E1I(3%%1"\A."XU3$HL?CX*<CM18T!N:$PR/7([46%Q;C0J25=R.UHJ
M7G([46-3;R4S<S9R.U8Y?CX*<CM18R5N;5]:5W)6;&Q?;5I`32-R5FQK;VTC
M5C4M<E9L:TQN;%!M;G([5CE^/@IR.U%C3&\A)C(V<E9L;&UM8D!G-7)6;&PW