|
|
1.1 root 1:
2:
3:
4:
5:
6:
7:
8: CHAPTER 1
9:
10:
11: FRANZ LISP
12:
13:
14:
15:
16:
17:
18: 1.1. FRANZ LISP[|-] was created as a tool to further
19: research in symbolic and algebraic manipulation,
20: artificial intelligence, and programming languages at
21: the University of California at Berkeley. Its roots
22: are in a PDP-11 Lisp system which originally came from
23: Harvard. As it grew it adopted features of Maclisp
24: and Lisp Machine Lisp. Substantial compatibility with
25: other Lisp dialects (Interlisp, UCILisp, CMULisp) is
26: achieved by means of support packages and compiler
27: switches. The heart of FRANZ LISP is written almost
28: entirely in the programming language C. Of course, it
29: has been greatly extended by additions written in
30: Lisp. A small part is written in the assembly
31: language for the current host machines, VAXen and a
32: couple of flavors of 68000. Because FRANZ LISP is
33: written in C, it is relatively portable and easy to
34: comprehend.
35:
36: FRANZ LISP is capable of running large lisp pro-
37: grams in a timesharing environment, has facilities for
38: arrays and user defined structures, has a user con-
39: trolled reader with character and word macro capabil-
40: ities, and can interact directly with compiled Lisp,
41: C, Fortran, and Pascal code.
42:
43: This document is a reference manual for the FRANZ
44: LISP system. It is not a Lisp primer or introduction
45: to the language. Some parts will be of interest pri-
46: marily to those maintaining FRANZ LISP at their com-
47: puter site. There is an additional document entitled
48: _T_h_e _F_r_a_n_z _L_i_s_p _S_y_s_t_e_m, _b_y _J_o_h_n _F_o_d_e_r_a_r_o, _w_h_i_c_h _p_a_r_-
49: _t_i_a_l_l_y _d_e_s_c_r_i_b_e_s _t_h_e _s_y_s_t_e_m _i_m_p_l_e_m_e_n_t_a_t_i_o_n. _F_R_A_N_Z
50: _L_I_S_P, _a_s _d_e_l_i_v_e_r_e_d _b_y _B_e_r_k_e_l_e_y, _i_n_c_l_u_d_e_s _a_l_l _s_o_u_r_c_e
51: _c_o_d_e _a_n_d _m_a_c_h_i_n_e _r_e_a_d_a_b_l_e _v_e_r_s_i_o_n _o_f _t_h_i_s _m_a_n_u_a_l _a_n_d
52: _s_y_s_t_e_m _d_o_c_u_m_e_n_t. _T_h_e _s_y_s_t_e_m _d_o_c_u_m_e_n_t _i_s _i_n _a _s_i_n_g_l_e
53: _f_i_l_e _n_a_m_e_d "_f_r_a_n_z._n" _i_n _t_h_e "_d_o_c" _s_u_b_d_i_r_e_c_t_o_r_y.
54: ____________________
55: 9 [|-]It is rumored that this name has something to do with
56: Franz Liszt [F_rants List] (1811-1886) a Hungarian composer
57: and keyboard virtuoso. These allegations have never been
58: proven.
59:
60:
61:
62: 9FRANZ LISP 1-1
63:
64:
65:
66:
67:
68:
69:
70: FRANZ LISP 1-2
71:
72:
73: This document is divided into four Movements. In
74: the first one we will attempt to describe the language
75: of FRANZ LISP precisely and completely as it now
76: stands (Opus 38.69, June 1983). In the second Move-
77: ment we will look at the reader, function types,
78: arrays and exception handling. In the third Movement
79: we will look at several large support packages written
80: to help the FRANZ LISP user, namely the trace package,
81: compiler, fixit and stepping package. Finally the
82: fourth movement contains an index into the other
83: movements. In the rest of this chapter we shall exam-
84: ine the data types of FRANZ LISP. The conventions
85: used in the description of the FRANZ LISP functions
86: will be given in 1.3 -- it is very important that
87: these conventions are understood.
88:
89:
90:
91: 1.2. Data Types FRANZ LISP has fourteen data types.
92: In this section we shall look in detail at each type
93: and if a type is divisible we shall look inside it.
94: There is a Lisp function _t_y_p_e which will return the
95: type name of a lisp object. This is the official
96: FRANZ LISP name for that type and we will use this
97: name and this name only in the manual to avoid confus-
98: ing the reader. The types are listed in terms of
99: importance rather than alphabetically.
100:
101:
102:
103: 1.2.0. lispval This is the name we use to describe
104: any Lisp object. The function _t_y_p_e will never
105: return `lispval'.
106:
107:
108:
109: 1.2.1. symbol This object corresponds to a variable
110: in most other programming languages. It may have a
111: value or may be `unbound'. A symbol may be _l_a_m_b_d_a
112: _b_o_u_n_d meaning that its current value is stored away
113: somewhere and the symbol is given a new value for
114: the duration of a certain context. When the Lisp
115: processor leaves that context, the symbol's
116: current value is thrown away and its old value is
117: restored.
118: 9 A symbol may also have a _f_u_n_c_t_i_o_n _b_i_n_d_i_n_g. This
119: function binding is static; it cannot be lambda
120: bound. Whenever the symbol is used in the func-
121: tional position of a Lisp expression the function
122: binding of the symbol is examined (see Chapter 4
123: for more details on evaluation).
124: 9 A symbol may also have a _p_r_o_p_e_r_t_y _l_i_s_t, another
125:
126:
127: Printed: January 31, 1984
128:
129:
130:
131:
132:
133:
134:
135: FRANZ LISP 1-3
136:
137:
138: static data structure. The property list consists
139: of a list of an even number of elements, considered
140: to be grouped as pairs. The first element of the
141: pair is the _i_n_d_i_c_a_t_o_r the second the _v_a_l_u_e of that
142: indicator.
143: 9 Each symbol has a print name (_p_n_a_m_e) which is how
144: this symbol is accessed from input and referred to
145: on (printed) output.
146: 9 A symbol also has a hashlink used to link symbols
147: together in the oblist -- this field is inaccessi-
148: ble to the lisp user.
149: 9 Symbols are created by the reader and by the func-
150: tions _c_o_n_c_a_t, _m_a_k_n_a_m and their derivatives. Most
151: symbols live on FRANZ LISP's sole _o_b_l_i_s_t, and
152: therefore two symbols with the same print name are
153: usually the exact same object (they are _e_q). Sym-
154: bols which are not on the oblist are said to be
155: _u_n_i_n_t_e_r_n_e_d. The function _m_a_k_n_a_m creates uninterned
156: symbols while _c_o_n_c_a_t creates _i_n_t_e_r_n_e_d ones.
157:
158:
159: 8 ____________________________________________________________
160: Subpart name Get value Set value Type
161:
162: 8 ________________________________________________________________________________________________________________________
163: value eval set lispval
164: setq
165: 8 ____________________________________________________________
166: property plist setplist list or nil
167: list get putprop
168: defprop
169: 8 ____________________________________________________________
170: function getd putd array, binary, list
171: binding def or nil
172: 8 ____________________________________________________________
173: print name get_pname string
174: 8 ____________________________________________________________
175: hash link
176: 8 ____________________________________________________________
177: 7 |7|7|7|7|7|7|7|7|7|7|7|7|7|
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190: |7|7|7|7|7|7|7|7|7|7|7|7|7|
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203: |7|7|7|7|7|7|7|7|7|7|7|7|7|
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216: |7|7|7|7|7|7|7|7|7|7|7|7|7|
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229: |7|7|7|7|7|7|7|7|7|7|7|7|7|
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247: 1.2.2. list A list cell has two parts, called the
248: car and cdr. List cells are created by the func-
249: tion _c_o_n_s.
250:
251:
252: 8 ________________________________________________
253: Subpart name Get value Set value Type
254:
255: 8 ________________________________________________________________________________________________
256: car car rplaca lispval
257: 8 ________________________________________________
258: cdr cdr rplacd lispval
259:
260:
261:
262: 9 Printed: January 31, 1984
263:
264:
265:
266:
267:
268:
269:
270: FRANZ LISP 1-4
271:
272:
273: 8 ________________________________________________
274: 799 |99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
275: 7777777777777777777777777777777777777777777777799 |99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
276: 7777777777777777777777777777777777777777777777799 |99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
277: 7777777777777777777777777777777777777777777777799 |99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
278: 7777777777777777777777777777777777777777777777799 |99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
279: 777777777777777777777777777777777777777777777
280:
281:
282: 1.2.3. binary This type acts as a function header
283: for machine coded functions. It has two parts, a
284: pointer to the start of the function and a symbol
285: whose print name describes the argument _d_i_s_c_i_p_l_i_n_e.
286: The discipline (if _l_a_m_b_d_a, _m_a_c_r_o or _n_l_a_m_b_d_a) deter-
287: mines whether the arguments to this function will
288: be evaluated by the caller before this function is
289: called. If the discipline is a string (specifi-
290: cally "_s_u_b_r_o_u_t_i_n_e", "_f_u_n_c_t_i_o_n", "_i_n_t_e_g_e_r-_f_u_n_c_t_i_o_n",
291: "_r_e_a_l-_f_u_n_c_t_i_o_n", "_c-_f_u_n_c_t_i_o_n", "_d_o_u_b_l_e-_c-_f_u_n_c_t_i_o_n",
292: or "_v_e_c_t_o_r-_c-_f_u_n_c_t_i_o_n" ) then this function is a
293: foreign subroutine or function (see 8.5 for more
294: details on this). Although the type of the _e_n_t_r_y
295: field of a binary type object is usually string or
296: other, the object pointed to is actually a sequence
297: of machine instructions.
298: Objects of type binary are created by _m_f_u_n_c_t_i_o_n,
299: _c_f_a_s_l, and _g_e_t_a_d_d_r_e_s_s.
300:
301:
302: 8 _________________________________________________________
303: Subpart name Get value Set value Type
304:
305: 8 __________________________________________________________________________________________________________________
306: entry getentry string or fixnum
307: 8 _________________________________________________________
308: discipline getdisc putdisc symbol or fixnum
309: 8 _________________________________________________________
310: 7 |8|7|7|7|7|
311:
312:
313:
314: 9 |8|7|7|7|7|
315:
316:
317:
318: 9 |8|7|7|7|7|
319:
320:
321:
322: 9 |8|7|7|7|7|
323:
324:
325:
326: 9 |8|7|7|7|7|
327:
328:
329:
330:
331:
332: 9
333:
334:
335: 1.2.4. fixnum A fixnum is an integer constant in
336: the range -2[31] to 2[31]-1. Small fixnums (-1024
337: to 1023) are stored in a special table so they
338: needn't be allocated each time one is needed. In
339: principle, the range for fixnums is machine depen-
340: dent, although all current implementations for
341: franz have this range.
342:
343:
344:
345: 1.2.5. flonum A flonum is a double precision real
346: number. On the VAX, the range is +_2.9x10[-37] to
347: +_1.7x10[38]. There are approximately sixteen
348: decimal digits of precision. Other machines may
349: have other ranges.
350:
351:
352:
353:
354:
355: 9 Printed: January 31, 1984
356:
357:
358:
359:
360:
361:
362:
363: FRANZ LISP 1-5
364:
365:
366: 1.2.6. bignum A bignum is an integer of potentially
367: unbounded size. When integer arithmetic exceeds
368: the limits of fixnums mentioned above, the calcula-
369: tion is automatically done with bignums. Should
370: calculation with bignums give a result which can be
371: represented as a fixnum, then the fixnum represen-
372: tation will be used[|-]. This contraction is known
373: as _i_n_t_e_g_e_r _n_o_r_m_a_l_i_z_a_t_i_o_n. Many Lisp functions
374: assume that integers are normalized. Bignums are
375: composed of a sequence of list cells and a cell
376: known as an sdot. The user should consider a big-
377: num structure indivisible and use functions such as
378: _h_a_i_p_a_r_t, and _b_i_g_n_u_m-_l_e_f_t_s_h_i_f_t to extract parts of
379: it.
380:
381:
382:
383: 1.2.7. string A string is a null terminated
384: sequence of characters. Most functions of symbols
385: which operate on the symbol's print name will also
386: work on strings. The default reader syntax is set
387: so that a sequence of characters surrounded by dou-
388: ble quotes is a string.
389:
390:
391:
392: 1.2.8. port A port is a structure which the system
393: I/O routines can reference to transfer data between
394: the Lisp system and external media. Unlike other
395: Lisp objects there are a very limited number of
396: ports (20). Ports are allocated by _i_n_f_i_l_e and _o_u_t_-
397: _f_i_l_e and deallocated by _c_l_o_s_e and _r_e_s_e_t_i_o. The
398: _p_r_i_n_t function prints a port as a percent sign fol-
399: lowed by the name of the file it is connected to
400: (if the port was opened by _f_i_l_e_o_p_e_n, _i_n_f_i_l_e, _o_r
401: _o_u_t_f_i_l_e). During initialization, FRANZ LISP binds
402: the symbol piport to a port attached to the stan-
403: dard input stream. This port prints as %$stdin.
404: There are ports connected to the standard output
405: and error streams, which print as %$stdout and
406: %$stderr. This is discussed in more detail at the
407: beginning of Chapter 5.
408:
409:
410:
411:
412: ____________________
413: 9 [|-]The current algorithms for integer arithmetic opera-
414: tions will return (in certain cases) a result between +_2[30]
415: and 2[31] as a bignum although this could be represented as
416: a fixnum.
417:
418:
419:
420: 9 Printed: January 31, 1984
421:
422:
423:
424:
425:
426:
427:
428: FRANZ LISP 1-6
429:
430:
431: 1.2.9. vector Vectors are indexed sequences of
432: data. They can be used to implement a notion of
433: user-defined types via their associated property
434: list. They make hunks (see below) logically
435: unnecessary, although hunks are very efficiently
436: garbage collected. There is a second kind of vec-
437: tor, called an immediate-vector, which stores
438: binary data. The name that the function _t_y_p_e
439: returns for immediate-vectors is vectori.
440: Immediate-vectors could be used to implement
441: strings and block-flonum arrays, for example. Vec-
442: tors are discussed in chapter 9. The functions
443: _n_e_w-_v_e_c_t_o_r, and _v_e_c_t_o_r, can be used to create vec-
444: tors.
445:
446:
447: 8 ________________________________________________
448: Subpart name Get value Set value Type
449:
450: 8 ________________________________________________________________________________________________
451: datum[_i] vref vset lispval
452: 8 ________________________________________________
453: property vprop vsetprop lispval
454: vputprop
455: 8 ________________________________________________
456: size vsize - fixnum
457: 8 ________________________________________________
458: 7 |7|7|7|7|7|7|7|
459:
460:
461:
462:
463:
464:
465: |7|7|7|7|7|7|7|
466:
467:
468:
469:
470:
471:
472: |7|7|7|7|7|7|7|
473:
474:
475:
476:
477:
478:
479: |7|7|7|7|7|7|7|
480:
481:
482:
483:
484:
485:
486: |7|7|7|7|7|7|7|
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498: 1.2.10. array Arrays are rather complicated types
499: and are fully described in Chapter 9. An array
500: consists of a block of contiguous data, a function
501: to access that data, and auxiliary fields for use
502: by the accessing function. Since an array's
503: accessing function is created by the user, an array
504: can have any form the user chooses (e.g. n-
505: dimensional, triangular, or hash table).
506: Arrays are created by the function _m_a_r_r_a_y.
507:
508:
509: 8 _______________________________________________________________
510: Subpart name Get value Set value Type
511:
512: 8 ______________________________________________________________________________________________________________________________
513: access function getaccess putaccess binary, list
514: or symbol
515: 8 _______________________________________________________________
516: auxiliary getaux putaux lispval
517: 8 _______________________________________________________________
518: data arrayref replace block of contiguous
519: set lispval
520: 8 _______________________________________________________________
521: length getlength putlength fixnum
522: 8 _______________________________________________________________
523: delta getdelta putdelta fixnum
524:
525:
526:
527: 9 Printed: January 31, 1984
528:
529:
530:
531:
532:
533:
534:
535: FRANZ LISP 1-7
536:
537:
538: 8 _______________________________________________________________
539: 799 |9|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
540: 7777777777777777777777777777777777777777899 |9|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
541: 7777777777777777777777777777777777777777899 |9|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
542: 7777777777777777777777777777777777777777899 |9|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
543: 7777777777777777777777777777777777777777899 |9|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|99|
544: 777777777777777777777777777777777777778
545:
546:
547: 1.2.11. value A value cell contains a pointer to a
548: lispval. This type is used mainly by arrays of
549: general lisp objects. Value cells are created with
550: the _p_t_r function. A value cell containing a
551: pointer to the symbol `foo' is printed as
552: `(ptr to)foo'
553:
554:
555:
556: 1.2.12. hunk A hunk is a vector of from 1 to 128
557: lispvals. Once a hunk is created (by _h_u_n_k or
558: _m_a_k_h_u_n_k) it cannot grow or shrink. The access time
559: for an element of a hunk is slower than a list cell
560: element but faster than an array. Hunks are really
561: only allocated in sizes which are powers of two,
562: but can appear to the user to be any size in the 1
563: to 128 range. Users of hunks must realize that
564: (_n_o_t (_a_t_o_m '_l_i_s_p_v_a_l)) will return true if _l_i_s_p_v_a_l
565: is a hunk. Most lisp systems do not have a direct
566: test for a list cell and instead use the above test
567: and assume that a true result means _l_i_s_p_v_a_l is a
568: list cell. In FRANZ LISP you can use _d_t_p_r to check
569: for a list cell. Although hunks are not list
570: cells, you can still access the first two hunk ele-
571: ments with _c_d_r and _c_a_r and you can access any hunk
572: element with _c_x_r[|-]. You can set the value of the
573: first two elements of a hunk with _r_p_l_a_c_d and _r_p_l_a_c_a
574: and you can set the value of any element of the
575: hunk with _r_p_l_a_c_x. A hunk is printed by printing
576: its contents surrounded by { and }. However a hunk
577: cannot be read in in this way in the standard lisp
578: system. It is easy to write a reader macro to do
579: this if desired.
580:
581:
582:
583: 1.2.13. other Occasionally, you can obtain a
584: pointer to storage not allocated by the lisp sys-
585: tem. One example of this is the entry field of
586: those FRANZ LISP functions written in C. Such
587: objects are classified as of type other. Foreign
588: functions which call malloc to allocate their own
589: space, may also inadvertantly create such objects.
590: The garbage collector is supposed to ignore such
591: ____________________
592: 9 [|-]In a hunk, the function _c_d_r references the first ele-
593: ment and _c_a_r the second.
594:
595:
596:
597: Printed: January 31, 1984
598:
599:
600:
601:
602:
603:
604:
605: FRANZ LISP 1-8
606:
607:
608: objects.
609:
610:
611:
612: 1.3. Documentation The conventions used in the follow-
613: ing chapters were designed to give a great deal of
614: information in a brief space. The first line of a
615: function description contains the function name in
616: bold face and then lists the arguments, if any. The
617: arguments all have names which begin with a letter or
618: letters and an underscore. The letter(s) gives the
619: allowable type(s) for that argument according to this
620: table.
621:
622:
623: 8 _______________________________________________________
624: Letter Allowable type(s)
625:
626: 8 ______________________________________________________________________________________________________________
627: g any type
628: 8 _______________________________________________________
629: s symbol (although nil may not be allowed)
630: 8 _______________________________________________________
631: t string
632: 8 _______________________________________________________
633: l list (although nil may be allowed)
634: 8 _______________________________________________________
635: n number (fixnum, flonum, bignum)
636: 8 _______________________________________________________
637: i integer (fixnum, bignum)
638: 8 _______________________________________________________
639: x fixnum
640: 8 _______________________________________________________
641: b bignum
642: 8 _______________________________________________________
643: f flonum
644: 8 _______________________________________________________
645: u function type (either binary or lambda body)
646: 8 _______________________________________________________
647: y binary
648: 8 _______________________________________________________
649: v vector
650: 8 _______________________________________________________
651: V vectori
652: 8 _______________________________________________________
653: a array
654: 8 _______________________________________________________
655: e value
656: 8 _______________________________________________________
657: p port (or nil)
658: 8 _______________________________________________________
659: h hunk
660: 8 _______________________________________________________
661: 7 |7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|
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: |7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|
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: |7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|
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: In the first line of a function description, those
746: arguments preceded by a quote mark are evaluated (usu-
747: ally before the function is called). The quoting con-
748: vention is used so that we can give a name to the
749: result of evaluating the argument and we can describe
750: the allowable types. If an argument is not quoted it
751: does not mean that that argument will not be
752:
753:
754: 9 Printed: January 31, 1984
755:
756:
757:
758:
759:
760:
761:
762: FRANZ LISP 1-9
763:
764:
765: evaluated, but rather that if it is evaluated, the
766: time at which it is evaluated will be specifically
767: mentioned in the function description. Optional argu-
768: ments are surrounded by square brackets. An ellipsis
769: (...) means zero or more occurrences of an argument of
770: the directly preceding type.
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: 9
818:
819: 9 Printed: January 31, 1984
820:
821:
822:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.