gluser.mss 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793
  1. @Make(Manual)
  2. @Define(PE,FaceCode U)
  3. @Begin(TitlePage)
  4. @Begin(TitleBox)
  5. @MajorHeading[GLISP User's Manual]
  6. @BlankSpace(2)
  7. @Center(
  8. Gordon S. Novak Jr.
  9. Computer Science Department
  10. Stanford University
  11. Stanford, California 94305)
  12. @BlankSpace(3)
  13. @BlankSpace(2)
  14. @Center[@B<Revised:> @Value(Date)]
  15. @End(TitleBox)
  16. @Begin(ResearchCredit)
  17. This research was supported in part by NSF grant SED-7912803 in the Joint
  18. National Science Foundation - National Institute of Education Program
  19. of Research on Cognitive Processes and the Structure of Knowledge in
  20. Science and Mathematics, and in part by the Defense Advanced Research
  21. Projects Agency under contract MDA-903-80-c-007.
  22. @End(ResearchCredit)
  23. @End(TitlePage)
  24. @Chapter(Introduction)
  25. @Section(Overview of GLISP)
  26. GLISP is a LISP-based language which provides high-level
  27. language features not found in ordinary LISP. The GLISP language
  28. is implemented by means of a compiler which accepts GLISP as input and
  29. produces ordinary LISP as output; this output can be further compiled
  30. to machine code by the LISP compiler. GLISP is available for several
  31. LISP dialects, including Interlisp, Maclisp, UCI Lisp, ELISP, Franz
  32. Lisp, and Portable Standard Lisp.
  33. The goal of GLISP is to allow structured objects to be referenced
  34. in a convenient, succinct language, and to allow the structures of objects
  35. to be changed without changing the code which references the objects.
  36. GLISP provides both PASCAL-like and English-like syntaxes; much of the power
  37. and brevity of GLISP derive from the compiler features necessary to
  38. support the relatively informal, English-like language constructs.
  39. The following example function illustrates how GLISP permits definite
  40. reference to structured objects.
  41. @Begin(ProgramExample)
  42. (HourlySalaries (GLAMBDA ( (a DEPARTMENT) )
  43. (for each EMPLOYEE who is HOURLY
  44. (PRIN1 NAME) (SPACES 3) (PRINT SALARY) ) ))
  45. @End(ProgramExample)
  46. The features provided by GLISP include the following:
  47. @Begin(Enumerate)
  48. GLISP maintains knowledge of the "context" of the computation as the
  49. program is executed. Features of objects which are in context may be
  50. referenced directly; the compiler will determine how to reference the
  51. objects given the current context, and will add the newly referenced
  52. objects to the context. In the above example, the function's
  53. argument, an object whose class is
  54. DEPARTMENT, establishes an initial context relative to
  55. which EMPLOYEEs can be found. In the context of an EMPLOYEE, NAME
  56. and SALARY can be found.
  57. GLISP supports flexible object definition and reference with a
  58. powerful abstract datatype facility.
  59. Object classes are easily declared to the system. An object
  60. declaration includes a definition of the storage structure of the
  61. object and declarations of properties of the object; these may be
  62. declared in such a way that they compile open, resulting in efficient
  63. object code. GLISP supports object-centered programming, in which
  64. processes are invoked by means of "messages" sent to objects.
  65. Object structures may be LISP structures (for which code is
  66. automatically compiled) or Units in the user's favorite representation
  67. language (for which the user can supply compilation functions).
  68. Loop constructs, such as
  69. @ (FOR EACH <item> WITH <property> DO ...)@ ,
  70. are compiled into loops of the appropriate form.
  71. Compilation of infix expressions is provided for the arithmetic
  72. operators and for additional operators which facilitate list manipulation.
  73. Operators are interpreted appropriately for Lisp datatypes as well as
  74. for numbers; operator overloading for user-defined objects is provided
  75. using the message facility.
  76. The GLISP compiler infers the types of objects when possible, and uses
  77. this knowledge to generate efficient object code. By performing
  78. @I[ compilation relative to a knowledge base ], GLISP is able to perform
  79. certain computations (e.g., inheritance of an attached procedure
  80. from a parent class of an object
  81. in a knowledge base) at compile time rather than at runtime, resulting
  82. in much faster execution.
  83. By separating object definitions from the code which references objects,
  84. GLISP permits radical changes to object structures with no changes to
  85. code.
  86. @End(Enumerate)
  87. @Section(Implementation)
  88. GLISP is implemented by means of a compiler, which produces a
  89. normal Lisp EXPR from the GLISP code; the GLISP code is saved on the
  90. function's property list, and the compiled definition replaces the
  91. GLISP definition. Use of GLISP entails the cost of a single
  92. compilation, but otherwise is about as efficient as normal LISP.
  93. The LISP code produced by GLISP can be further compiled to machine
  94. code by the LISP compiler.
  95. GLISP functions
  96. are indicated by the use of GLAMBDA instead of LAMBDA in the function
  97. definition. When the Lisp interpreter sees the GLAMBDA, it
  98. calls the GLISP compiler
  99. to incrementally compile the GLISP function.
  100. The compiled version replaces the GLISP version (which is saved on the
  101. function name's property list), and is used thereafter.
  102. This automatic compilation feature is currently implemented in Interlisp
  103. and in Franz Lisp. In other dialects, it is necessary for the user to
  104. explicitly invoke compilation of GLISP functions by calling the compiler
  105. function @PE[GLCC] for each one.
  106. To use GLISP, it is first necessary to load the compiler file into
  107. Lisp. Users' files containing structure descriptions and GLISP code
  108. are then loaded. Compilation of a GLISP function is requested by:
  109. @Tabset(1.7 inch)
  110. @Begin(Format)
  111. @PE[(GLCC 'FN)]@\Compile @PE[FN].
  112. @PE[(GLCP 'FN)]@\Compile @PE[FN] and prettyprint the result.
  113. @PE[(GLP 'FN)]@\Print the compiled version of @PE[FN].
  114. @End(Format)
  115. In Interlisp, all the GLISP functions (beginning with GLAMBDA) in a file
  116. can be compiled by invoking @PE[(GLCOMPCOMS@ <file>COMS)], where
  117. @PE[<file>COMS] is the list of file package commands for the file.
  118. Properties of compiled functions are stored on the property list of
  119. the function name:
  120. @Begin(Format)
  121. @PE[GLORIGINALEXPR]@\Original (GLISP) version of the function.@FOOT[The
  122. original definition is saved as EXPR in Interlisp.]
  123. @PE[GLCOMPILED]@\GLISP-compiled version of the function.
  124. @PE[GLRESULTTYPE]@\Type of the result of the function.
  125. @PE[GLARGUMENTTYPES]@\Types of the arguments of the function.
  126. @End(format)
  127. Properties of GLISP functions can be examined with the function
  128. @PE[(GLED '<name>)], which calls the Lisp editor on the property
  129. list of @PE[<name>]. @PE[(GLEDF '<name>)] calls the Lisp editor on the
  130. original (GLISP) definition of @PE[<name>].
  131. @Section(Error Messages)
  132. GLISP provides detailed error messages when compilation errors are
  133. detected; many careless errors such as misspellings will be caught
  134. by the compiler. When the source program contains errors, the
  135. compiled code generates runtime errors upon execution of the
  136. erroneous expressions.
  137. @Section(Interactive Features of GLISP)
  138. Several features of GLISP are available interactively, as well as in
  139. compiled functions:
  140. @Enumerate{
  141. The @PE[A] function, which creates structured objects from a readable
  142. property/value list, is available as an interactive function.
  143. Messages to objects can be executed interactively.
  144. A display editor/inspector, GEV, is available for use with bitmap
  145. graphics terminals.@Foot[GEV is currently implemented only for Xerox
  146. Lisp machines.] GEV interprets objects according to their GLISP
  147. structure descriptions; it allows the user to inspect objects, edit
  148. them, interactively construct programs which operate on them, display
  149. computed properties, send messages to objects, and "push down" to
  150. inspect data values.}
  151. @Chapter(Object Descriptions)
  152. @Section(Declaration of Object Descriptions)
  153. An @I(Object Description) in GLISP is a description of the structure
  154. of an object in terms of named substructures, together with definitions
  155. of ways of referencing the object. The latter may include
  156. @I( properties )
  157. (i.e., data whose values are not stored, but are computed
  158. from the values of stored data), adjectival predicates, and
  159. @I(messages) which the object can receive; the messages can be used to
  160. implement operator overloading and other compilation features.
  161. Object Descriptions are obtained by GLISP in several ways:
  162. @Begin(Enumerate)
  163. The descriptions of basic datatypes (e.g., INTEGER) are automatically
  164. known to the compiler.
  165. Structure descriptions (but not full object descriptions) may be used
  166. directly as @I(types) in function definitions.
  167. The user may declare object descriptions to the system using the
  168. function GLISPOBJECTS; the names of the object types may then be
  169. used as @I[ types ] in function definitions and definitions of other
  170. structures.
  171. Object descriptions may be included as part of a knowledge
  172. representation language, and are then furnished to GLISP by the
  173. interface package written for that representation language.
  174. @End(Enumerate)
  175. LISP data structures are declared using the function GLISPOBJECTS@Foot{
  176. Once declared, object descriptions may be included in INTERLISP program
  177. files by including in the <file>COMS a statement of the form:
  178. @PE[(GLISPOBJECTS@ <object-name@-(1)>@ ...@ <object-name@-(n)>)]},
  179. which takes one or more object
  180. descriptions as arguments (assuming the descriptions to be quoted).
  181. Since GLISP compilation is performed relative to the knowledge base
  182. of object descriptions, the object descriptions must be declared
  183. prior to GLISP compilation of functions using those descriptions.
  184. The format of each description is as follows:
  185. @Begin(ProgramExample)
  186. (<object name> <structure description>
  187. PROP <property descriptions>
  188. ADJ <adjective descriptions>
  189. ISA <predicate descriptions>
  190. MSG <message descriptions>
  191. SUPERS <list of superclasses>
  192. VALUES <list of values> )
  193. @End(ProgramExample)
  194. The <object name> and <structure description> are required; the other
  195. property/value pairs are optional, and may appear in any order.
  196. The following example illustrates some of the
  197. declarations which might be made to describe the object type
  198. @PE(VECTOR).
  199. @Begin(ProgramExample)
  200. (GLISPOBJECTS
  201. (VECTOR (CONS (X NUMBER) (Y NUMBER))
  202. PROP ( (MAGNITUDE ((SQRT X*X + Y*Y))) )
  203. ADJ ( (ZERO (X IS ZERO AND Y IS ZERO))
  204. (NORMALIZED (MAGNITUDE = 1.0)) )
  205. MSG ( (+ VECTORPLUS OPEN T)
  206. (- VECTORDIFFERENCE) )
  207. ))
  208. @End(ProgramExample)
  209. @Subsection(Property Descriptions)
  210. Each @PE[<description>] specified with PROP, ADJ, ISA, or MSG
  211. has the following format:
  212. @Begin(ProgramExample)
  213. (<name> <response> <prop@-[1]> <value@-[1]> ... <prop@-[n]> <value@-[n]>)
  214. @END(ProgramExample)
  215. where @PE[<name>] is the (atomic) name of the property, @PE[<response>]
  216. is a function name or a list of GLISP code to be compiled in place
  217. of the property, and the @PE[<prop>@ <value>] pairs are optional
  218. properties which affect compilation. All four kinds of
  219. properties are compiled in a similar fashion, as
  220. described in the section "Compilation of Messages".
  221. @Subsection(Supers Description)
  222. The SUPERS list specifies a list of @I[ superclasses ], i.e., the names
  223. of other object descriptions from which the object may inherit PROP,
  224. ADJ, ISA, and MSG properties. Inheritance from superclasses can be
  225. recursive, as described under "Compilation of Messages".
  226. @Subsection(Values Description)
  227. The VALUES list is a list of pairs, @PE[ (<name> <value>) ], which is
  228. used to associate symbolic names with constant values for an object
  229. type. If VALUES are defined for the type of the @I[ selector ] of a
  230. CASE statement, the corresponding symbolic names may be used as the
  231. selection values for the clauses of the CASE statement.
  232. @Section(Structure Descriptions)
  233. Much of the power of GLISP is derived from its use of Structure
  234. Descriptions. A Structure Description (abbreviated "<sd>") is a means
  235. of describing a LISP data structure and giving names to parts of the
  236. structure; it is similar in concept to a Record declaration in PASCAL.
  237. Structure descriptions are used by the GLISP compiler to generate code
  238. to retrieve and store parts of structures.
  239. @Subsection(Syntax of Structure Descriptions)
  240. The syntax of structure
  241. descriptions is recursively defined in terms of basic types and
  242. composite types which are built up from basic types. The syntax of
  243. structure descriptions is as follows:
  244. @Foot[The names of the basic types and the structuring operators must
  245. be all upper-case or lower-case, depending on the case which is usual for
  246. the underlying Lisp system. In general, other GLISP keywords and
  247. user program names may be in upper-case, lower-case, or mixed-case,
  248. if mixed cases are permitted by the Lisp system.]
  249. @Begin(Enumerate)
  250. The following basic types are known to the compiler:
  251. @Begin(Format)
  252. @Tabdivide(3)
  253. @B(ATOM)
  254. @B(INTEGER)
  255. @B(REAL)
  256. @B(NUMBER)@\(either INTEGER or REAL)
  257. @B(STRING)
  258. @B(BOOLEAN)@\(either T or NIL)
  259. @B(ANYTHING)@\(an arbitrary structure)
  260. @End(Format)
  261. An object type which is known to the compiler, either from a GLISPOBJECTS
  262. declaration or because it is a Class of units in the user's knowledge
  263. representation language, is a valid type for use in a structure
  264. description. The <name>@ of such an object type may be specified
  265. directly as <name> or, for readability, as @ @B[(A]@ <name>@B[)]@
  266. or @ @B[(AN]@ <name>@B[)].
  267. @Foot[Whenever the form @B<(A ...)> is allowed in GLISP, the form
  268. @B<(AN ...)> is also allowed.]@
  269. Any substructure can be named by enclosing it
  270. in a list prefixed by the name: @ @B[(]<name>@ @ <sd>@B[)]@ .
  271. This allows the same substructure to have multiple names.
  272. "A", "AN", and the names used in forming composite types (given below)
  273. are treated as reserved words, and may not be used as names.
  274. Composite Structures:@
  275. Structured data types composed of other structures are described using
  276. the following structuring operators:
  277. @Begin(Enumerate)
  278. (@B[CONS]@ @ <sd@-[1]>@ @ <sd@-[2]>)
  279. @*
  280. The CONS of two structures whose descriptions
  281. are <sd@-[1]> and <sd@-[2]>.
  282. (@B[LIST]@ @ <sd@-[1]>@ @ <sd@-[2]>@ @ ...@ @ <sd@-[n]>)
  283. @*
  284. A list of exactly the elements
  285. whose descriptions are <sd@-[1]>@ <sd@-[2]>@ ...@ <sd@-[n]>.
  286. (@B[LISTOF]@ @ <sd>)
  287. @*
  288. A list of zero or more elements, each of which has
  289. the description <sd>.
  290. (@B[ALIST]@ @ (<name@-[1]>@ <sd@-[1]>)@ ...@ (<name@-[n]>@ <sd@-[n]>))
  291. @*
  292. An association list
  293. in which the atom <name@-[i]>, if present, is associated with a structure
  294. whose description is <sd@-[i]>.
  295. (@B[PROPLIST]@ @ (<name@-[1]>@ <sd@-[1]>)@ ...@ (<name@-[n]>@ <sd@-[n]>))
  296. @*
  297. An association list in "property-list format" (alternating names and
  298. values)
  299. in which the atom <name@-[i]>, if present, is associated with a structure
  300. whose description is <sd@-[i]>.
  301. (@B[ATOM]@ @ @ (@B[BINDING]@ @ <sd>)
  302. @ @ @ @ (@B[PROPLIST]@ @ (<pname@-[1]>@ <sd@-[1]>)@ ...@ @~
  303. (<pname@-[n]>@ <sd@-[n]>)@ ))
  304. @*
  305. This describes an atom with its binding and/or its property list;
  306. either the BINDING or the PROPLIST group may be omitted.
  307. Each property name <pname@-[i]> is treated as a property list indicator
  308. as well as the name of the substructure. When creation of such a
  309. structure is specified, GLISP will compile code to create a GENSYM atom.
  310. (@B[RECORD]@ @ <recordname>@ @ (<name@-[1]>@ <sd@-[1]>)@ @ ...@ @ (<name@-[n]>@ <sd@-[n]>))
  311. @*
  312. RECORD specifies the use of contiguous records for data storage.
  313. <recordname> is the name of the record type; it is optional,
  314. and is not used in some Lisp dialects.@Foot[RECORDs are
  315. implemented using RECORDs in Interlisp, HUNKs in Maclisp and Franz Lisp,
  316. VECTORs in Portable Standard Lisp, and lists in UCI Lisp and ELISP.
  317. In Interlisp, appropriate RECORD declarations must be made to the system
  318. by the user in addition to the GLISP declarations.]
  319. (@B[TRANSPARENT]@ @ <type>)
  320. @*
  321. An object of type <type> is incorporated into the structure being
  322. defined in @I[transparent mode], which means that all fields and
  323. properties of the object of type <type> can be directly referenced
  324. as if they were properties of the object being defined. A substructure
  325. which is a named @I[ type ] and which is not declared to be TRANSPARENT
  326. is assumed to be opaque, i.e., its internal structure cannot be seen
  327. unless an access path explicitly names the subrecord.@Foot{For example,
  328. a PROFESSOR record might contain some fields which are unique to
  329. professors, plus a pointer to an EMPLOYEE record. If the declaration
  330. in the PROFESSOR record were @PE[(EMPREC@ (TRANSPARENT@ EMPLOYEE))],
  331. then a field of the employee record, say SALARY, could be referenced
  332. directly from a variable P which points to a PROFESSOR record as
  333. @PE[ P:SALARY ]; if the declaration were @PE[(EMPREC@ EMPLOYEE)],
  334. it would be necessary to say @PE[P:EMPREC:SALARY].}
  335. The object
  336. of type <type> may also contain TRANSPARENT objects; the graph of
  337. TRANSPARENT object references must of course be acyclic.
  338. (@B[OBJECT]@ @ (<name@-[1]>@ <sd@-[1]>)@ ...@ (<name@-[n]>@ <sd@-[n]>))
  339. @*(@B[ATOMOBJECT]@ @ (<name@-[1]>@ <sd@-[1]>)@ ...@ (<name@-[n]>@ <sd@-[n]>))
  340. @*(@B[LISTOBJECT]@ @ (<name@-[1]>@ <sd@-[1]>)@ ...@ (<name@-[n]>@ <sd@-[n]>))
  341. @*These declarations describe @I[ Objects ], data structures which can
  342. receive messages at runtime. The three types of objects are implemented
  343. as records, atoms, or lists, respectively. In each case, the system
  344. adds to the object
  345. a @PE[CLASS] datum which points to the name of the type of the
  346. object. An object declaration may only appear as the top-level
  347. declaration of a named object type.
  348. @End(Enumerate)
  349. @End(Enumerate)
  350. @Subsection(Examples of Structure Descriptions)
  351. The following examples illustrate the use of Structure Descriptions.
  352. @Begin(ProgramExample)
  353. (GLISPOBJECTS
  354. (CAT (LIST (NAME ATOM)
  355. (PROPERTIES (LIST (CONS (SEX ATOM)
  356. (WEIGHT INTEGER))
  357. (AGE INTEGER)
  358. (COLOR ATOM)))
  359. (LIKESCATNIP BOOLEAN)))
  360. (PERSON (ATOM
  361. (PROPLIST
  362. (CHILDREN (LISTOF (A PERSON)))
  363. (AGE INTEGER)
  364. (PETS (LIST (CATS (LISTOF CAT))
  365. (DOGS (LISTOF (A DOG))) ))
  366. )))
  367. )
  368. @End(ProgramExample)
  369. The first structure, CAT, is entirely composed of list structure.
  370. An CAT structure might look like:
  371. @Begin(ProgramExample)
  372. (PUFF ((MALE . 10) 5 CALICO) T)
  373. @End(ProgramExample)
  374. Given a CAT object X, we could ask for its WEIGHT [equivalent to
  375. (CDAADR X)] or for a subrecord such as PROPERTIES [equivalent
  376. to (CADR X)]. Having set a variable Y to the PROPERTIES,
  377. we could also ask for the WEIGHT from Y [equivalent to (CDAR Y)].
  378. In general, whenever a subrecord is accessed, the structure description
  379. of the subrecord is associated with it by the compiler,
  380. enabling further accesses to parts of the
  381. subrecord. Thus, the meaning
  382. of a subrecord name depends on the type of record from which the
  383. subrecord is retrieved. The subrecord AGE has two different
  384. meanings when applied to PERSONs and CATs.
  385. The second structure, PERSON, illustrates a description of
  386. an object which is a Lisp atom with properties stored on its property
  387. list. Whereas no structure names appear in an actual CAT structure,
  388. the substructures of a PROPLIST operator must be named, and
  389. the names appear in the actual structures. For example, if X is a
  390. PERSON structure, retrieval of the AGE of X is equivalent to
  391. @PE[(GETPROP@ X@ 'AGE)].
  392. A subrecord of a PROPLIST record can be referenced directly; e.g., one
  393. can ask for the DOGS of a PERSON directly, without cognizance of
  394. the fact that DOGS is part of the PETS property.
  395. @Section(Editing of Object Descriptions)
  396. An object description can be edited by calling @PE[ (GLEDS TYPE) ],
  397. where @PE[ TYPE ] is the name of the object type. This will cause the
  398. Lisp editor to be called on the object description of @PE[ TYPE ].
  399. @Section(Interactive Editing of Objects)
  400. An interactive structure inspector/editor, GEV, is available for the
  401. Xerox 1100-series lisp machines. GEV allows the user to inspect and
  402. edit any structures which are described by GLISP object descriptions,
  403. to "zoom in" on substructures of interest, and to display the values
  404. of computed properties automatically or on demand. GEV is described
  405. in a separate document.
  406. @Section(Global Variables)
  407. The types of free variables can be declared within the functions which
  408. reference them. Alternatively, the types of global variables can be
  409. declared to the compiler using the
  410. form:@Foot[@PE{(GLISPGLOBALS@ <name@-(1)>@ ...@ <name@-(n)>)}
  411. is defined as a file package command for Interlisp.]
  412. @Begin(ProgramExample)
  413. (GLISPGLOBALS (<name> <type>) ... )
  414. @End(ProgramExample)
  415. Following such a declaration, the compiler will assume a free variable
  416. <name> is of the corresponding <type>. A GLOBAL object does not have
  417. to actually exist as a storage structure; for example, one could define
  418. a global object "MOUSE" or "SYSTEM" whose properties are actually
  419. implemented by calls to the operating system.
  420. @Section(Compile-Time Constants and Conditional Compilation)
  421. The values and types of compile-time constants can be declared to the
  422. compiler using the
  423. form:@Foot[@PE{(GLISPCONSTANTS@ <name@-(1)>@ ...@ <name@-(n)>)}
  424. is defined as a file package command for Interlisp.]
  425. @Programexample[
  426. (GLISPCONSTANTS (<name> <value-expression> <type>) ... )
  427. ]
  428. The <name> and <type> fields are assumed to be quoted. The
  429. @PE[ <value-expression> ] field is a GLISP expression which is
  430. parsed and evaluated; this allows constants to be defined by expressions
  431. involving previously defined constants.
  432. The GLISP compiler will perform many kinds of computations on
  433. constants at compile time, reducing the size of the compiled code and
  434. improving execution speed.@Foot[Ordinary Lisp functions are evaluated
  435. on constant arguments if the property @PE(GLEVALWHENCONST) is set to T on
  436. the property list of the function name. This property is set by the
  437. compiler for the basic arithmetic functions.]
  438. In particular, arithmetic, comparison,
  439. logical, conditional, and CASE function calls are optimized, with
  440. elimination of dead code. This permits conditional compilation in
  441. a clean form. Code can be written which tests the values of flags
  442. in the usual way; if the flag values are then declared to be
  443. compile-time constants using GLISPCONSTANTS,
  444. the tests will be performed at compile time, and the unneeded code
  445. will vanish.
  446. @Chapter(Reference To Objects)
  447. @Section(Accessing Objects)
  448. The problem of reference is the problem of determining what object,
  449. or feature of a structured object, is referred to by some part of
  450. a statement in a language. Most programming languages solve the
  451. problem of reference by unique naming: each distinct object in a
  452. program unit has a unique name, and is referenced by that name.
  453. Reference to a part of a structured object is done by giving the name
  454. of the variable denoting that object and a path specification which
  455. tells how to get to the desired part from the whole.
  456. GLISP permits reference by unique naming and path specification,
  457. but in addition permits @I[definite reference relative to context.]
  458. A @I[definite reference] is a reference to an object which has not
  459. been explicitly named before, but which can be understood relative
  460. to the current context of computation. If, for example, an object
  461. of type VECTOR (as defined earlier) is in context, the program
  462. statement
  463. @Begin(ProgramExample)
  464. (IF X IS NEGATIVE ...
  465. @End(ProgramExample)
  466. contains a definite reference to "X", which may be interpreted as the
  467. X substructure of the VECTOR which is in context. The definition of
  468. the computational context and the way in which definite references
  469. are resolved are covered in a later section of this manual.
  470. In the following section, which describes the syntaxes of reference
  471. to objects in GLISP, the following notation is used. "<var>" refers
  472. to a variable name in the usual LISP sense, i.e., a LAMBDA variable,
  473. PROG variable, or GLOBAL variable; the variable is assumed to point
  474. to (be bound to) an object. "<type>" refers to the type of object
  475. pointed to by a variable. "<property>" refers to a property or subrecord of
  476. an object.
  477. Two syntaxes are available for reference to objects: an
  478. English-like syntax, and a PASCAL-like syntax.
  479. The two are equivalent, and may be intermixed freely within a GLISP
  480. function. The allowable forms of references in the two syntaxes are
  481. shown in the table below.
  482. @Begin(Format)
  483. @TabDivide(3)
  484. @U("PASCAL" Syntax)@\@U("English" Syntax)@\@U(Meaning)
  485. <var>@\<var>@\The object denoted
  486. @\@\by <var>
  487. @B[:]<type>@\@B[The] <type>@\The object whose type
  488. @\@\is <type>
  489. @B[:]<property>@\@B[The] <property>@\The <property> of
  490. @I[or] <property>@\@\some object
  491. <var>@B[:]<property>@\@B[The] <property> @B[of] <var>@\The <property> of the
  492. @\@\object denoted by <var>
  493. @End(Format)
  494. These forms can be extended to specify longer paths in the obvious way,
  495. as in "The AGE of the SPOUSE of the HEAD of the DEPARTMENT" or
  496. "DEPARTMENT:HEAD:SPOUSE:AGE". Note that there is no distinction
  497. between reference to substructures and reference to properties as
  498. far as the syntax of the referencing code is concerned; this
  499. facilitates hiding the internal structures of objects.
  500. @Section(Creation of Objects)
  501. GLISP allows the creation of structures to be specified by expressions
  502. of the form:
  503. @BlankSpace(1)
  504. @B[(A] <type> @P[with] <property@-[1]> @P[=] <value@-[1]> @P[,] ... @P[,] @~
  505. <property@-[n]> @P[=] <value@-[n]>@B[)]
  506. @BlankSpace(1)
  507. In this expression, the "@I[with]", "=", and "," are allowed for
  508. readability, but may be omitted if desired@Foot[Some Lisp dialects,
  509. e.g. Maclisp, will interpret commas as "backquote" commands and generate
  510. error messages. In such dialects, the commas must be omitted or be
  511. "slashified".]; if present, they must all
  512. be delimited on both sides by blanks.
  513. In response to such an expression, GLISP will generate code to create
  514. a new instance of
  515. the specified structure. The <property> names may be specified in any
  516. order. Unspecified properties are defaulted according to the
  517. following rules:
  518. @Begin(Enumerate)
  519. Basic types are defaulted to 0 for INTEGER and NUMBER, 0.0 for REAL,
  520. and NIL for other types.
  521. Composite structures are created from the defaults of their
  522. components, except that missing PROPLIST and ALIST items which
  523. would default to NIL are omitted.
  524. @End(Enumerate)
  525. Except for missing PROPLIST and ALIST elements, as noted above, a
  526. newly created LISP structure will contain all of the fields specified
  527. in its structure description.
  528. @Section(Interpretive Creation of Objects)
  529. The "A" function is defined for interpretive use as well as for use
  530. within GLISP functions.
  531. @Section(Predicates on Objects)
  532. Adjectives defined for structures using the @PE[ADJ] and @PE[ISA]
  533. specifications may be used in predicate expressions on objects in
  534. @B[If] and @B[For] statements. The syntax of basic predicate
  535. expressions is:
  536. @Begin(ProgramExample)
  537. <object> @b[is] <adjective>
  538. <object> @B[is a] <isa-adjective>
  539. @End(ProgramExample)
  540. Basic predicate expressions may be combined using AND, OR, NOT or ~, and
  541. grouping parentheses.
  542. The compiler automatically recognizes the LISP adjectives
  543. ATOMIC, NULL, NIL, INTEGER,
  544. REAL, ZERO, NUMERIC, NEGATIVE, MINUS, and BOUND, and the ISA-adjectives
  545. ATOM, LIST, NUMBER, INTEGER, SYMBOL, STRING, ARRAY, and
  546. BIGNUM@Foot[where applicable.]; user definitions have precedence
  547. over these pre-defined adjectives.
  548. @Subsection(Self-Recognition Adjectives)
  549. If the ISA-adjective @PE[ self ] is defined for an object type, the
  550. type name may be used as an ISA-adjective to test whether a given
  551. object is a member of that type. Given a predicate phrase of the
  552. form "@PE[@ X@ is@ a@ Y@ ]", the compiler first looks at the definition
  553. of the object type of @PE[ X ] to see if @PE[ Y ] is defined as an
  554. ISA-adjective for such objects.
  555. If no such ISA-adjective is found, and @PE[ Y ]
  556. is a type name, the compiler looks to see if @PE[ self ]
  557. is defined as an ISA-adjective for @PE[ Y ], and if so, compiles it.
  558. If a @PE[ self ] ISA-adjective predicate is compiled as the test of an
  559. @B[If], @B[While], or @B[For] statement, and the tested object is a
  560. simple variable, the variable will be known to be of that type within
  561. the scope of the test. For example, in the statement
  562. @Begin(ProgramExample)
  563. (If X is a FOO then (_ X Print) ...
  564. @End(ProgramExample)
  565. the compiler will know that X is a FOO if the test succeeds, and will
  566. compile the Print message appropriate for a FOO, even if the type of
  567. X was declared as something other than FOO earlier. This feature is
  568. useful in implementing disjunctive types, as discussed in a later
  569. section.
  570. @Subsection(Testing Object Classes)
  571. For those data types which are defined using one of the OBJECT
  572. structuring operators, the Class name is automatically defined as an
  573. ISA-adjective. The ISA test is implemented by runtime examination of
  574. the CLASS datum of the object.
  575. @Chapter(GLISP Program Syntax)
  576. @Section(Function Syntax)
  577. GLISP function syntax is essentially the same as that of LISP
  578. with the addition of type information and RESULT and GLOBAL declarations.
  579. The basic function syntax is:
  580. @Foot[The PROG is not required. In Lisp dialects other than Interlisp,
  581. LAMBDA may be used instead of GLAMBDA.]
  582. @Begin(ProgramExample)
  583. (<function-name> (@B[GLAMBDA] (<arguments>)
  584. @P[(RESULT] <result-description>@P[)]
  585. @P[(GLOBAL] <global-variable-descriptions>@P[)]
  586. (PROG (<prog-variables>)
  587. <code> )))
  588. @End(ProgramExample)
  589. The RESULT declaration is optional; in many cases, the compiler
  590. will infer the result type automatically. The main use of the RESULT
  591. declaration is to allow the compiler to determine the result type
  592. without compiling the function, which may be useful when compiling
  593. another function which calls it. The <result-description> is a
  594. standard structure description or <type>.
  595. The GLOBAL declaration is used to inform the compiler of the
  596. types of free variables. The function GLISPGLOBALS can be used to
  597. declare the types of global variables, making GLOBAL declarations
  598. within individual functions unnecessary.
  599. The major difference between a GLISP function definition and a
  600. standard LISP definition is the presence of type declarations for
  601. variables, which are in PASCAL-like syntax of the following forms:
  602. @Begin(ProgramExample)
  603. <variable>@B[:]<type>
  604. <variable>@B[:(A] <type>@B[)]
  605. <variable>@B[,]<variable>@B[,]...@B[:]<type>
  606. <variable>@B[,]<variable>@B[,]...@B[:(A] <type>@B[)]
  607. @B[:]<type>
  608. @B[(A] <type>@B[)]
  609. @End(ProgramExample)
  610. In addition to declared <type>s, a Structure Description may be
  611. used directly as a <type> in a variable declaration.
  612. Type declarations are required only for variables whose subrecords or
  613. properties will be referenced. In general, if the value of a variable is
  614. computed in such a way that the type of the value can be inferred, the
  615. variable will receive the appropriate type automatically; in such
  616. cases, no type declaration is necessary. Since GLISP maintains a
  617. @I[context] of the computation, it is often unnecessary to name a
  618. variable which is an argument of a function;
  619. in such cases, it is only necessary to specify the <type> of
  620. the argument, as shown in the latter two syntax forms above.
  621. PROG and GLOBAL declarations must always specify variable
  622. names (with optional types); the ability to directly reference features
  623. of objects reduces the number of PROG variables needed in many cases.
  624. Initial values for PROG variables may be specified, as in Interlisp,
  625. by enclosing the variable and its initial value in a list@Foot[This
  626. feature is available in all Lisp dialects.]:
  627. @ProgramExample{
  628. (PROG (X (N 0) Y) ...)
  629. }
  630. However, the syntax of variable declarations does not permit the type
  631. of a variable and its initial value to both be specified.
  632. @Section(Expressions)
  633. GLISP provides translation of infix expressions of the kind usually
  634. found in programming languages. In addition, it provides additional
  635. operators which facilitate list manipulation and other operations.
  636. Overloading of operators for user-defined types is provided by means
  637. of the @I[message] facility.
  638. Expressions may be written directly in-line within function references,
  639. as in
  640. @PE[ (SQRT X*X + Y*Y) ],
  641. or they may be written within parentheses; parentheses may be used for
  642. grouping in the usual way. Operators may be written with or without
  643. delimiting spaces, @I[except for the "-" operator, which @P(must) be delimited
  644. by spaces].
  645. @Foot[The "-" operator is required to be delimited by spaces since "-" is
  646. often used as a hyphen within variable names. The "-" operator will be
  647. recognized within "atom" names if the flag GLSEPMINUS is set to T.]
  648. Expression parsing is done by an operator precedence parser, using the
  649. same precedence ordering as in FORTRAN.
  650. @Foot[The precedence of compound operators is higher than assignment
  651. but lower than that of all other operators. The operators
  652. @PE[^ _ _+ +_ _- -_] are right-associative; all others are left-associative.]
  653. The operators which are recognized are as follows:@Foot<In Maclisp, the
  654. operator @PE[/] must be written @PE[//].>
  655. @Begin(Format)
  656. @TabDivide(3)
  657. Assignment@\@PE(_) @I[ or ] @PE[:=]
  658. Arithmetic@\@PE[+ - * / ^]
  659. Comparison@\@PE[= @R<~>= <> < <= > >=]
  660. Logical@\@PE[AND OR NOT @R<~>]
  661. Compound@\@PE(_+ _- +_ -_)
  662. @End(Format)
  663. @Subsection(Interpretation of Operators)
  664. In addition to the usual interpretation of operators when used with
  665. numeric arguments, some of the operators are interpreted appropriately
  666. for other Lisp types.
  667. @Paragraph(Operations on Strings)
  668. For operands of type STRING, the operator @PE[ + ] performs
  669. concatenation. All of the comparison operators are defined for STRINGs.
  670. @Paragraph(Operations on Lists)
  671. Several operators are defined in such a way that they perform set
  672. operations on lists of the form @PE[ (LISTOF@ <type>) ], where
  673. @PE[ <type> ] is considered to be the element type. The following
  674. table shows the interpretations of the operators:
  675. @Begin(Format)
  676. @Tabdivide(3)
  677. @PE[<list> + <list>]@\Set Union
  678. @PE[<list> - <list>]@\Set Difference
  679. @PE[<list> * <list>]@\Set Intersection
  680. @PE[<list> + <element>]@\CONS
  681. @PE[<element> + <list>]@\CONS
  682. @PE[<list> - <element>]@\REMOVE
  683. @PE[<element> <= <list>]@\MEMBER or MEMB
  684. @PE[<list> >= <element>]@\MEMBER or MEMB
  685. @End(Format)
  686. @Paragraph(Compound Operators)
  687. Each compound operator performs an operation involving the arguments
  688. of the operator and assigns a value to the left-hand argument;
  689. compound operators are therefore thought of as "destructive change"
  690. operators.
  691. The meaning of a compound operator depends on the type of its
  692. left-hand argument, as shown in the following table:
  693. @Begin(Group)
  694. @Begin(Format)
  695. @TabDivide(5)
  696. @U(Operator)@\@U(Mnemonic)@\@U(NUMBER)@\@U(LISTOF)@\@U(BOOLEAN)
  697. @B[@PE(_+)]@\@I(Accumulate)@\PLUS@\NCONC1@\OR
  698. @B[@PE(_-)]@\@I(Remove)@\DIFFERENCE@\REMOVE@\AND NOT
  699. @B[@PE(+_)]@\@I(Push)@\PLUS@\PUSH@\OR
  700. @B[@PE(-_)]@\@I(Pop)@\@\POP@Foot[For the Pop operator, the arguments are in
  701. the reverse of the usual order, i.e., (TOP@ @PE(-_)@ STACK) will pop the
  702. top element off STACK and assign the element removed to TOP.]
  703. @End(Format)
  704. @End(Group)
  705. As an aid in remembering the list operators, the arrow may be
  706. thought of as representing the list, with the head of the arrow being
  707. the front of the list and the operation (+ or -) appearing where the
  708. operation occurs on the list. Thus, for example, @PE(_+) adds an element
  709. at the end of the list, while @PE(+_) adds an element at the front of the
  710. list.
  711. Each of the compound operators performs an assignment to its left-hand
  712. side; the above table shows an abbreviation of the operation which is
  713. performed prior to the assignment.
  714. The following examples show the effects of the operator "@PE(_+)" on
  715. local variables of different types:
  716. @Begin(Format)
  717. @TabDivide(3)
  718. @U(Type)@\@U(Source Code)@\@U(Compiled Code)
  719. INTEGER@\@PE(I _+ 5)@\@PE[(SETQ I (IPLUS I 5))]
  720. BOOLEAN@\@PE(P _+ Q)@\@PE[(SETQ P (OR P Q))]
  721. LISTOF@\@PE(L _+ ITEM)@\@PE[(SETQ L (NCONC1 L ITEM))]
  722. @END(Format)
  723. When the compound operators are not specifically defined for a type,
  724. they are interpreted as specifying the operation (@PE[+] or @PE[-])
  725. on the two operands, followed by assignment of the result to the
  726. left-hand operand.
  727. @Paragraph(Assignment)
  728. Assignment of a value to the left-hand argument of an assignment
  729. operator is relatively flexible in GLISP. The following kinds of
  730. operands are allowed on the left-hand side of an assignment operator:
  731. @Begin(Enumerate)
  732. Variables.
  733. Stored substructures of a structured type.
  734. PROPerties of a structured type, whenever the interpretation of the PROPerty
  735. would be a legal left-hand side.
  736. Algebraic expressions involving numeric types, @I[ provided ] that
  737. the expression ultimately involves only one occurrence of a variable
  738. or stored value.@Foot{For example, @PE[(X^2 _ 2.0)] is acceptable,
  739. but @PE[(X*X@ _@ 2.0)] is not because the variable @PE[X] occurs twice.}
  740. @End(Enumerate)
  741. For example, consider the following Object Description for a CIRCLE:
  742. @ProgramExample{
  743. (CIRCLE (LIST (START VECTOR) (RADIUS REAL))
  744. PROP ((PI (3.1415926))
  745. (DIAMETER (RADIUS*2))
  746. (CIRCUMFERENCE (PI*DIAMETER))
  747. (AREA (PI*RADIUS^2))) )
  748. }
  749. Given this description, and a CIRCLE @PE[ C ],
  750. the following are legal assignments:
  751. @Programexample{
  752. (C:RADIUS _ 5.0)
  753. (C:AREA _ 100.0)
  754. (C:AREA _ C:AREA*2)
  755. (C:AREA _+ 100.0)
  756. }
  757. @Paragraph(Self-Assignment Operators
  758. @Foot[This section may be skipped by the casual user of GLISP.])
  759. There are some cases where it would be desirable to let an object
  760. perform an assignment of its own value. For example, the user might
  761. want to define @I[PropertyList] as an abstract datatype, with messages
  762. such as GETPROP and PUTPROP, and use PropertyLists as substructures
  763. of other datatypes. However, a message such as PUTPROP may cause the
  764. PropertyList object to modify its own structure, perhaps even changing
  765. its structure from NIL to a non-NIL value. If the function which
  766. implements PUTPROP performs a normal assignment to its "self" variable,
  767. the assignment will affect only the local variable, and will not modify
  768. the PropertyList component of the containing structure. The purpose
  769. of the Self-Assignment Operators is to allow such modification of the
  770. value within the containing structure.
  771. The Self-Assignment Operators are @PE[__], @PE[__+], @PE[_+_], and
  772. @PE[__-], corresponding to the operators @PE[_], @PE[_+], @PE[+_],
  773. and @PE[_-], respectively. The meaning of these operators is that
  774. the assignment is performed to the object on the left-hand side of
  775. the operator, @I[as seen from the structure containing the object].
  776. The use of these operators is highly restricted; any use of a
  777. Self-Assignment Operator must meet all of the following conditions:
  778. @Begin(Enumerate)
  779. A Self-Assignment Operator can only be used within a Message function
  780. which is compiled OPEN.
  781. The left-hand side of the assignment must be a simple variable which
  782. is an argument of the function.
  783. The left-hand-side variable must be given a unique (unusual) name to
  784. prevent accidental aliasing with a user variable name.
  785. @End(Enumerate)
  786. As an example, the PUTPROP message for a PropertyList datatype could
  787. be implemented as follows:
  788. @Begin(ProgramExample)
  789. (PropertyList.PUTPROP (GLAMBDA (PropertyListPUTPROPself prop val)
  790. (PropertyListPUTPROPself __
  791. (LISTPUT PropertyListPUTPROPself prop val)) ))
  792. @End(ProgramExample)
  793. @Section(Control Statements)
  794. GLISP provides several PASCAL-like control statements.
  795. @Subsection(IF Statement)
  796. The syntax of the IF statement is as follows:
  797. @Begin(ProgramExample)
  798. (@B[IF] <condition@-[1]> @P[THEN] <action@-[11]>@ ...@ <action@-[1i]>
  799. @P[ELSEIF] <condition@-[2]> @P[THEN] <action@-[21]>@ ...@ <action@-[2j]>
  800. ...
  801. @P[ELSE] <action@-[m1]>@ ...@ <action@-[mk]>)
  802. @End(ProgramExample)
  803. Such a statement is translated to a COND of the obvious form. The
  804. "THEN" keyword is optional, as are the "ELSEIF" and "ELSE" clauses.
  805. @Subsection(CASE Statement)
  806. The CASE statement selects a set of actions based on an atomic selector
  807. value; its syntax is:
  808. @Begin(ProgramExample)
  809. (@B[CASE] <selector> @B[OF]
  810. (<case@-[1]> <action@-[11]>@ ...@ <action@-[1i]>)
  811. (<case@-[2]> <action@-[21]>@ ...@ <action@-[2j]>)
  812. ...
  813. @P[ELSE] <action@-[m1]>@ ...@ <action@-[mk]>)
  814. @End(ProgramExample)
  815. The @PE[<selector>] is evaluated, and is compared with the given
  816. @PE[<case>] specifications. Each @PE[<case>] specification is either
  817. a single, atomic specification, or a list of atomic specifications.
  818. All @PE[<case>] specifications are assumed to be quoted. The "ELSE"
  819. clause is optional; the "ELSE" actions are executed if @PE[<selector>]
  820. does not match any @PE[<case>].
  821. If the @I[ type ] of the @PE[<selector>] has a VALUES specification,
  822. @PE[<case>] specifications which match the VALUES for that type will
  823. be translated into the corresponding values.
  824. @Subsection(FOR Statement)
  825. The FOR statement generates a loop through a set of elements (typically
  826. a list). Two syntaxes of the FOR statement are provided:
  827. @Begin(ProgramExample)
  828. (@B[FOR EACH] <set> @P[DO] <action@-[1]>@ ...@ <action@-[n]>)
  829. (@B[FOR] <variable> @B[IN] <set> @P[DO] <action@-[1]>@ ...@ <action@-[n]>)
  830. @End(ProgramExample)
  831. The keyword "DO" is optional. In the first form of the FOR statement,
  832. the singular form of the <set> is specified; GLISP will convert the
  833. given set name to the plural form.
  834. @Foot[For names with irregular plurals, the plural form should be put
  835. on the property list of the singular form under the property name
  836. PLURAL, e.g., @PE<(PUTPROP 'MAN 'PLURAL 'MEN)>.]
  837. The <set> may be qualified by an
  838. adjective or predicate phrase in the first form; the allowable syntaxes
  839. for such qualifying phrases are shown below:
  840. @Begin(ProgramExample)
  841. <set> @B[WITH] <predicate>
  842. <set> @B[WHICH IS] <adjective>
  843. <set> @B[WHO IS] <adjective>
  844. <set> @B[THAT IS] <adjective>
  845. @End(ProgramExample)
  846. The <predicate> and <adjective> phrases may be combined with AND, OR, NOT,
  847. and grouping parentheses. These phrases may be followed by a qualifying
  848. phrase of the form:
  849. @Begin(ProgramExample)
  850. @B[WHEN] <expression>
  851. @End(ProgramExample)
  852. The "WHEN" expression is ANDed with the other qualifying expressions to
  853. determine when the loop body will be executed.
  854. Within the FOR loop, the current member of
  855. the <set> which is being examined is automatically put into @I[context]
  856. at the highest level of priority.
  857. For example, suppose that the current context contains a substructure
  858. whose description is:
  859. @Begin(ProgramExample)
  860. (PLUMBERS (LISTOF EMPLOYEE))
  861. @END(ProgramExample)
  862. Assuming that EMPLOYEE contains the appropriate definitions, the
  863. following FOR loop could be written:
  864. @Begin(ProgramExample)
  865. (FOR EACH PLUMBER WHO IS NOT A TRAINEE DO SALARY _+ 1.50)
  866. @End(ProgramExample)
  867. To simplify the collection of features of a group of objects, the
  868. <action>s in the FOR loop may be replaced by the CLISP-like construct:
  869. @Begin(ProgramExample)
  870. ... @B[COLLECT] <form>)
  871. @End(ProgramExample)
  872. @Subsection(WHILE Statement)
  873. The format of the WHILE statement is as follows:
  874. @Begin(ProgramExample)
  875. (@B[WHILE] <condition> @B[DO] <action@-[1]> ... <action@-[n]>)
  876. @End(ProgramExample)
  877. The actions @PE(<action@-[1]>) through @PE(<action@-[n]>) are executed
  878. repeatedly as long as @PE(<condition>) is true. The keyword @B[DO]
  879. may be omitted. The value of the expression is NIL.
  880. @Subsection(REPEAT Statement)
  881. The format of the REPEAT statement is as follows:
  882. @Begin(ProgramExample)
  883. (@B[REPEAT] <action@-[1]> ... <action@-[n]> @B[UNTIL] <condition>)
  884. @End(ProgramExample)
  885. The actions @PE(<action@-[1]>) through @PE(<action@-[n]>) are repeated
  886. (always at least once) until @PE[<condition>] is true. The value of
  887. the expression is NIL. The keyword @B[UNTIL] is required.
  888. @Section(Definite Reference to Particular Objects)
  889. In order to simplify reference to particular member(s) of a group,
  890. definite reference may be used. Such an expression is written using
  891. the word @B[THE] followed by the singular form of the group,
  892. or @B[THOSE] followed by the plural form of the group, and
  893. qualifying phrases (as described for the @B[FOR] statement).
  894. The following examples illustrate these expressions.
  895. @Begin(ProgramExample)
  896. (THE SLOT WITH SLOTNAME = NAME)
  897. (THOSE EMPLOYEES WITH JOBTITLE = 'ELECTRICIAN)
  898. @End(ProgramExample)
  899. The value of @B[THE] is a single object (or NIL if no object satisfies
  900. the specified conditions); @B[THOSE] produces a list of all objects
  901. satisfying the conditions.@Foot[In general, nested loops are optimized
  902. so that intermediate lists are not actually constructed. Therefore,
  903. use of nested THE or THOSE statements is not inefficient.]
  904. @Chapter(Messages)
  905. GLISP supports the @I[Message] metaphor, which has its roots in the
  906. languages SIMULA and SMALLTALK. These languages provide
  907. @I[Object-Centered Programming], in which objects are thought of as
  908. being active entities which communicate by sending each other
  909. @I[Messages]. The internal structures of objects are hidden; a program
  910. which wishes to access "variables" of an object does so by sending
  911. messages to the object requesting the access desired. Each object
  912. contains
  913. @Foot[typically by inheritance from some parent in a Class hierarchy]
  914. a list of @I[Selectors], which identify the messages to which the object
  915. can respond. A @I[Message] specifies the destination object, the
  916. selector, and any arguments associated with the message. When a
  917. message is executed at runtime, the selector is looked up for the
  918. destination object; associated with the selector is a procedure, which
  919. is executed with the destination object and message arguments as its
  920. arguments.
  921. GLISP treats reference to properties, adjectives, and predicates
  922. associated with an object similarly to the way it treats messages.
  923. The compiler is able to perform much of the lookup of @I[selectors]
  924. at compile time, resulting in efficient code while maintaining the
  925. flexibility of the
  926. message metaphor. Messages can be defined in such a way that they
  927. compile open, compile as function calls to the function which is
  928. associated with the selector, or compile as messages to be interpreted
  929. at runtime.
  930. Sending of a @I[message] in GLISP is specified using the following syntax:
  931. @Begin(ProgramExample)
  932. @B[(SEND] <object> <selector> <arg@-[1]>@ ...@ <arg@-[n]>@B[)]
  933. @End(ProgramExample)
  934. The keyword "SEND" may be replaced by "@B[@PE(_)]". The @PE[<selector>]
  935. is assumed to be quoted. Zero or more arguments may be specified;
  936. the arguments other than @PE[<selector>] are evaluated.
  937. @PE[<object>] is evaluated; if @PE[<object>] is a non-atomic expression,
  938. it must be enclosed in at least one set of parantheses, so that the
  939. @PE[<selector>] will always be the third element of the list.
  940. @SECTION(Compilation of Messages)
  941. When GLISP encounters a message statement, it looks up the <selector>
  942. in the MSG definition of the type of the object to which the message
  943. is sent, or in one of the SUPERS of the type.
  944. @Foot[If an appropriate representation language is provided, the
  945. <selector> and its associated <response>
  946. may be inherited from a parent class in the class hierarchy of the
  947. representation language.]
  948. Each <selector> is paired with the appropriate <response> to the message.
  949. Code is compiled depending on the form
  950. of the <response> associated with the <selector>, as follows:
  951. @Foot[If the type of the destination object is unknown, or if the
  952. <selector> cannot be found, GLISP compiles the (SEND@ ...) statement
  953. as if it is a normal function call.]
  954. @Begin(Enumerate)
  955. If the <response> is an atom, that atom is taken as the name of a
  956. function which is to be called in response to the message. The code
  957. which is compiled is a direct call to this function,
  958. @Begin(ProgramExample)
  959. (<response> <object> <arg@-[1]> ... <arg@-[n]>)
  960. @End(ProgramExample)
  961. If the <response> is a list, the contents of the list are recursively
  962. compiled in-line as GLISP code, with the name "@PE[self]" artificially
  963. "bound" to the <object> to which the message was sent. Because the
  964. compilation is recursive, a message may be defined in terms of other
  965. messages, substructures, or properties, which may themselves be defined
  966. as messages.
  967. @Foot[Such recursive definitions must of course be acyclic.]
  968. The outer pair of parentheses of the <response> serves only to bound
  969. its contents; thus, if the <response> is a function call, the function
  970. call must be enclosed in an additional set of parentheses.
  971. @End(Enumerate)
  972. The following examples illustrate the various ways of defining message
  973. responses.
  974. @Begin(ProgramExample)
  975. (EDIT EDITV)
  976. (SUCCESSOR (self + 1))
  977. (MAGNITUDE ((SQRT X*X + Y*Y)))
  978. @End(ProgramExample)
  979. In the first example, a message with <selector> EDIT is
  980. compiled as a direct call to the function EDITV. In the
  981. second example, the SUCCESSOR message is compiled as the sum of
  982. the object receiving the message (represented by "@PE[self]") and the
  983. constant 1; if the object receiving the message is the value of the
  984. variable J and has the type INTEGER, the code generated
  985. for the SUCCESSOR would be @PE[(ADD1 J)]. The third example illustrates
  986. a call to a function, SQRT, with arguments containing definite
  987. references to X and Y (which presumably are defined as part of the
  988. object whose MAGNITUDE is sought). Note that since MAGNITUDE is
  989. defined by a function call, an "extra" pair of parentheses is
  990. required around the function call to distinguish it from in-line code.
  991. The user can determine whether a message is to be compiled open,
  992. compiled as a function call, or compiled as a message which is to
  993. be executed at runtime.
  994. When a GLISP expression is specified as a <response>, the <response>
  995. is always compiled open; open compilation can be requested by using
  996. the OPEN property when the <response> is a function name.
  997. Open compilation operates like
  998. macro expansion; since the "macro" is a GLISP expression, it is easy
  999. to define messages and properties in terms of other messages and
  1000. properties. The combined capabilities of open compilation, message
  1001. inheritance, conditional compilation, and flexible assignment provide
  1002. a great deal of power.
  1003. The ability to use definite reference in GLISP makes
  1004. the definition and use of the "macros" simple and natural.
  1005. @Section(Compilation of Properties and Adjectives)
  1006. Properties, Adjectives, and ISA-adjectives are compiled in the
  1007. same way as Messages. Since the syntax of use of properties and
  1008. adjectives does not permit specification of any arguments, the only
  1009. argument available to code or a function which implements the
  1010. @PE[<response>] for a property or adjective is the @PE[ self ]
  1011. argument, which denotes the object to which the property or adjective
  1012. applies. A @PE[<response>] which is written directly as GLISP code
  1013. may use the name @PE[ self ] directly
  1014. @Foot[The name @PE< self > is "declared" by the compiler, and does
  1015. not have to be specified in the Structure Description.], as in the
  1016. SUCCESSOR example above; a function which is specified as the
  1017. @PE[<response>] will be called with the @PE[self]
  1018. object as its single argument.
  1019. @Section(Declarations for Message Compilation)
  1020. Declarations which affect compilation of Messages, Adjectives, or
  1021. Properties may be specified following the <response> for a given
  1022. message; such declarations are in (Interlisp) property-list format,
  1023. @PE[<prop@-[1]><value@-[1]>@ ...@ <prop@-[n]><value@-[n]>]. The
  1024. following declarations may be specified:
  1025. @Begin(Enumerate)
  1026. @B[RESULT]@PE[ <type>]
  1027. @*
  1028. This declaration specifies the @I[type] of the result of the
  1029. message or other property. Specification of result types helps the
  1030. compiler to perform type inference, thus reducing the number of type
  1031. declarations needed in user programs.
  1032. The RESULT type for simple GLISP expressions will be inferred by the
  1033. compiler; the RESULT declaration should be used if the @PE[<response>]
  1034. is a complex GLISP expression or a function name.
  1035. @Foot[Alternatively, the result of a function may be specified by the
  1036. RESULT declaration within the function itself.]@
  1037. @B[OPEN@ @ T]
  1038. @*
  1039. This declaration specifies that the function which is specified as the
  1040. <response> is to be compiled open at each reference. A <response>
  1041. which is a list of GLISP code is always compiled open; however, such
  1042. a <response> can have only the @PE[self] argument. If it is desired to
  1043. compile open a Message <response> which has arguments besides @PE[self],
  1044. the <response> must be coded as a function (in order to bind the
  1045. arguments) and the OPEN declaration must be used.
  1046. Functions which are compiled open may not be recursive via any chain
  1047. of open-compiled functions.
  1048. @B[MESSAGE@ @ T]
  1049. @*
  1050. This declaration specifies that a runtime message should be generated
  1051. for messages with this <selector> sent to objects of this Class.
  1052. Typically, such a declaration would be used in a higher-level Class
  1053. whose subclasses have different responses to the same message
  1054. <selector>.
  1055. @End(Enumerate)
  1056. @Section(Operator Overloading)
  1057. GLISP provides operator overloading for user-defined objects using
  1058. the Message facility. If an arithmetic operator is defined as the
  1059. @I[selector] of a message for a user datatype, an arithmetic
  1060. subexpression using that operator will be compiled as if it were
  1061. a message call with two arguments. For example, the type VECTOR
  1062. might have the declaration and function definitions below:
  1063. @Begin(ProgramExample)
  1064. (GLISPOBJECTS
  1065. (VECTOR (CONS (X INTEGER) (Y INTEGER))
  1066. MSG ((+ VECTORPLUS OPEN T)
  1067. (_+ VECTORINCR OPEN T)) ) )
  1068. (DEFINEQ
  1069. (VECTORPLUS (GLAMBDA (U,V:VECTOR)
  1070. (A VECTOR WITH X = U:X + V:X , Y = U:Y + V:Y) ))
  1071. (VECTORINCR (GLAMBDA (U,V:VECTOR)
  1072. (U:X _+ V:X)
  1073. (U:Y _+ V:Y) )) )
  1074. @End(ProgramExample)
  1075. With these definitions, an expression involving the operators @PE[+]
  1076. or @PE[_+] will be compiled by open compilation of the respective
  1077. functions.
  1078. The compound operators (@PE[_+ +_ _- -_]) are conventionally thought of as
  1079. "destructive replacement" operators; thus, the expression
  1080. @PE[(U@ _@ U@ +@ V)] will create a new VECTOR structure and assign
  1081. the new structure to U, while the expression @PE[(U@ _+@ V)] will
  1082. smash the existing structure U, given the definitions above.
  1083. The convention of letting the compound operators specify "destructive
  1084. replacement" allows the user to specify both the destructive and
  1085. non-destructive cases. However, if the compound operators are not
  1086. overloaded but the arithmetic operators @PE[+] and @PE[-] are
  1087. overloaded, the compound operators are compiled using the definitions
  1088. of @PE[+] for @PE[_+] and @PE[+_], and @PE[-] for @PE[_-] and @PE[-_].
  1089. Thus, if only the @PE[+] operator were overloaded for VECTOR, the
  1090. expression @PE[(U@ _+@ V)] would be compiled as if it were
  1091. @PE[(U@ _@ U@ +@ V)].
  1092. @Section(Runtime Interpretation of Messages)
  1093. In some cases, the type of the object which will receive a given message
  1094. is not known at compile time; in such cases, the message must be
  1095. executed interpretively, at runtime. Interpretive
  1096. execution is provided for all types of GLISP messages.
  1097. An interpretive message call (i.e., a call to the function @PE[SEND])
  1098. is generated by the GLISP compiler in response to a message call in
  1099. a GLISP program when the specified message selector cannot be found
  1100. for the declared type of the object receiving the message, or when
  1101. the MESSAGE flag is set for that selector. Alternatively, a call to
  1102. SEND may be entered interactively by the user or may be contained in
  1103. a function which has not been compiled by GLISP.
  1104. Messages can be interpreted only for those objects which are represented
  1105. as one of the OBJECT types, since it is necessary that the object
  1106. contain a pointer to its CLASS. The <selector> of the message is
  1107. looked up in the MSG declarations of the CLASS; if it is not found
  1108. there, the SUPERS of the CLASS are examined (depth-first) until the
  1109. selector is found. The <response> associated with the <selector> is
  1110. then examined. If the <response> is a function name, that function is
  1111. simply called with the specified arguments.@Foot{The object to which
  1112. the message is sent is always inserted as the first argument, followed
  1113. by the other arguments specified in the message call.} If the
  1114. <response> is a GLISP expression, the expression is compiled as a
  1115. LAMBDA form and cached for future use.
  1116. Interpretive execution is available for other property types (PROP,
  1117. ADJ, and ISA) using the call:
  1118. @Programexample[
  1119. (SENDPROP <object> <selector> <proptype>)
  1120. ]
  1121. where @PE[<proptype>] is PROP, ADJ, or ISA. @PE[<proptype>] is not
  1122. evaluated.
  1123. @Chapter(Context Rules and Reference)
  1124. The ability to use definite reference to features of objects which
  1125. are in @I[Context] is the key to much of GLISP's power. At the
  1126. same time, definite reference introduces the possibility of ambiguity,
  1127. i.e., there could be more than one object in Context which has
  1128. a feature with a specified name. In this chapter, guidelines are
  1129. presented for use of definite reference to allow the user to avoid
  1130. ambiguity.
  1131. @Section(Organization of Context)
  1132. The Context maintained by the compiler is organized in levels, each
  1133. of which may have multiple entries; the sequence of
  1134. levels is a stack. Searching of the Context
  1135. proceeds from the top (nearest) level of the stack to the bottom
  1136. (farthest) level. The bottom level of the stack is composed of the
  1137. LAMBDA variables of the function being compiled. New levels
  1138. are added to the Context in the following cases:
  1139. @Begin(Enumerate)
  1140. When a PROG is compiled. The PROG variables are added to the new
  1141. level.
  1142. When a @B[For] loop is compiled. The "loop index" variable (which may
  1143. be either a user variable or a compiler variable) is added to the
  1144. new level, so that it is in context during the loop.
  1145. When a @B[While] loop is compiled.
  1146. When a new clause of an @B[If] statement is compiled.
  1147. @End(Enumerate)
  1148. When a Message, Property, or Adjective is compiled, that compilation
  1149. takes place in a @I[ new ] context consisting only of the @PE[ self ]
  1150. argument and other message arguments.
  1151. @Section(Rules for Using Definite Reference)
  1152. The possibility of referential ambiguity is easily controlled in practice.
  1153. First, it should be noted that the traditional methods of unique
  1154. naming and complete path specification ("PASCAL style")
  1155. are available, and should be
  1156. used whenever there is any possibility of ambiguity. Second, there
  1157. are several cases which are guaranteed to be unambiguous:
  1158. @Begin(Enumerate)
  1159. In compiling GLISP code which implements a Message, Property, or
  1160. Adjective, only the @PE[@ self@ ] argument is in context initially;
  1161. definite reference to any substructure or property of the object
  1162. is therefore unambiguous.
  1163. @Foot[Unless there are duplicated names in the object definition.
  1164. However, if the same name is used as both a Property and an Adjective,
  1165. for example, it is not considered a duplicate since Properties and
  1166. Adjectives are specified by different source language constructs.]@
  1167. Within a @B[For] loop, the loop variable is the closest thing in
  1168. context.
  1169. In many cases, a function will only have a single structured argument;
  1170. in such cases, definite reference is unambiguous.
  1171. @End(Enumerate)
  1172. If "PASCAL" syntax (or the equivalent English-like form) is used for
  1173. references other than the above cases, no ambiguities will occur.
  1174. @Section(Type Inference)
  1175. In order to interpret definite references to features of objects,
  1176. the compiler must know the @I[ types ] of the objects. However,
  1177. explicit type specification can be burdensome, and makes it difficult
  1178. to change types without rewriting existing type declarations.
  1179. The GLISP compiler performs type inference in many cases, relieving
  1180. the programmer of the burden of specifying types explicitly. The
  1181. following rules enable the programmer to know when types will be
  1182. inferred by the compiler.
  1183. @Begin(Enumerate)
  1184. Whenever a variable is set to a value whose type is known,
  1185. the type of the variable
  1186. is inferred to be the type of the value to which it was set.
  1187. If a variable whose initial type was NIL (e.g., an untyped PROG variable)
  1188. appears on the left-hand side of the @PE[@ _+@ ] operator, its type
  1189. is inferred to be @PE[(LISTOF@ <type>)], where @PE[@ <type>@ ] is
  1190. the type of the right-hand side of the @PE[@ _+@ ] expression.
  1191. Whenever a substructure of a structured object is retrieved, the type
  1192. of the substructure is retrieved also.
  1193. Types of infix expressions are inferred.
  1194. Types of Properties, Adjectives, and Messages are inferred if:
  1195. @Begin(Enumerate)
  1196. The @PE[ <response> ] is GLISP code whose type can be inferred.
  1197. The @PE[ <response> ] has a RESULT declaration associated with it.
  1198. The @PE[ <response> ] is a function whose definition includes a
  1199. RESULT declaration, or whose property list contains a GLRESULTTYPE
  1200. declaration.
  1201. @End(Enumerate)
  1202. The type of the "loop variable" in a @B[For] loop is inferred and is
  1203. added to a new level of Context by the compiler.
  1204. If an @B[If] statement tests the type of a variable using a @PE[@ self@ ]
  1205. adjective, the variable is inferred to be of that type if the test is
  1206. satisfied. Similar type inference is performed if the test of the type
  1207. of the variable is the condition of a @B[While] statement.
  1208. When possible, GLISP infers the type of the function it is compiling
  1209. and adds the type of the result to the property list of the function
  1210. name under the indicator GLRESULTTYPE.
  1211. The types returned by many standard Lisp functions are known by the
  1212. compiler.
  1213. @End(Enumerate)
  1214. @Chapter(GLISP and Knowledge Representation Languages)
  1215. GLISP provides a convenient @I[Access Language] which allows uniform
  1216. specification of access to objects, without regard to the way in
  1217. which the objects are actually stored; in addition, GLISP provides
  1218. a basic @I[Representation Language], in which the structures and
  1219. properties of objects can be declared. The field of Artificial
  1220. Intelligence has spawned a number of powerful Representation
  1221. Languages, which provide power in describing large numbers of object
  1222. classes by allowing hierarchies of @I[Class] descriptions, in which
  1223. instances of Classes can inherit properties and procedures from
  1224. parent Classes. The @I[Access Languages] provided for these Representation
  1225. Languages, however, have typically been rudimentary, often being no
  1226. more than variations of LISP's GETPROP and PUTPROP. In addition,
  1227. by performing inheritance of procedures and data values at runtime,
  1228. these Representation Languages have often been computationally costly.
  1229. Facilities are provided for interfacing GLISP with representation
  1230. languages of the user's choice. When this is done,
  1231. GLISP provides a convenient and uniform language for
  1232. accessing both objects in the Representation Language and LISP objects.
  1233. In addition, GLISP can greatly improve the efficiency of programs which
  1234. access the representations by performing lookup of procedures and data
  1235. in the Class hierarchy @I[at compile time]. Finally, a LISP structure
  1236. can be specified @I[as the way of implementing] instances of a Class
  1237. in the Representation Language, so that while the objects in such a
  1238. class appear the same as other objects in the Representation Language
  1239. and are accessed in the same way, they are actually implemented as
  1240. LISP objects which are efficient in both time and storage.
  1241. A clean
  1242. @Foot[Cleanliness is in the eye of the beholder and, being next to
  1243. Godliness, difficult to attain. However, it's @I(relatively) clean.]
  1244. interface between GLISP and a Representation Language is provided.
  1245. With such an interface, each @I[Class] in the Representation Language
  1246. is acceptable as a GLISP @I[type]. When the program which is being
  1247. compiled specifies an access to an object which is known to be a
  1248. member of some Class, the interface module for the Representation
  1249. Language is called to generate code to perform the access. The
  1250. interface module can perform inheritance within the Class hierarchy,
  1251. and can call GLISP compiler functions to compile code for
  1252. subexpressions. Properties, Adjectives, and Messages in GLISP format
  1253. can be added to Class definitions, and can be inherited by subclasses
  1254. at compile time. In an Object-Centered representation language or
  1255. other representation language which relies heavily on procedural
  1256. inheritance, substantial improvements in execution speed can be
  1257. achieved by performing the inheritance lookup at compile time and
  1258. compiling direct procedure calls to inherited procedures when the
  1259. procedures are static and the type of the object which inherits the
  1260. procedure is known at compile time.
  1261. Specifications for an interface module for GLISP are contained in a
  1262. separate document@Foot[to be written.]. To date, GLISP has been
  1263. interfaced to our own GIRL representation language, and to LOOPS.
  1264. @Foot[LOOPS, a LISP Object Oriented Programming System, is being
  1265. developed at Xerox Palo Alto Research Center by Dan Bobrow and
  1266. yMark Stefik.]
  1267. @Chapter(Obtaining and Using GLISP)
  1268. GLISP and its documentation are available free of charge over the
  1269. ARPANET. The host computers involved will accept the login
  1270. "ANONYMOUS GUEST" for transferring files with FTP.
  1271. @Section(Documentation)
  1272. This user's manual, in line-printer format, is contained in
  1273. @PE([UTEXAS-20]<CS.NOVAK>GLUSER.LPT) . The SCRIBE source file is
  1274. @PE([SU-SCORE]<CSD.NOVAK>GLUSER.MSS) . Printed copies of this manual
  1275. can be ordered from Publications Coordinator, Computer Science
  1276. Department, Stanford University, Stanford, CA 94305, as technical report
  1277. STAN-CS-82-895 ($3.15 prepaid); the printed version may not be as
  1278. up-to-date as the on-line version.
  1279. @Section(Compiler Files)
  1280. There are two files, GLISP (the compiler itself) and GLTEST (a file
  1281. of examples). The files for the different Lisp dialects are:
  1282. @Tabset(1.4 inch)
  1283. @Begin(Format)
  1284. Interlisp:@\@PE([SU-SCORE]<CSD.NOVAK>GLISP.LSP) and @PE(GLTEST.LSP)
  1285. Maclisp:@\@PE([SU-SCORE]<CSD.NOVAK>GLISP.MAC) and @PE(GLTEST.MAC)
  1286. UCI Lisp:@\@PE([UTEXAS-20]<CS.NOVAK>GLISP.UCI) and @PE(GLTEST.UCI)
  1287. ELISP:@\the UCI version plus @PE([UTEXAS-20]<CS.NOVAK>ELISP.FIX)
  1288. Franz Lisp:@\@PE([SUMEX-AIM]<NOVAK>GLISP.FRANZ) and @PE(GLTEST.FRANZ)
  1289. PSL:@\@PE([SU-SCORE]<CSD.NOVAK>GLISP.PSL) and @PE(GLTEST.PSL)
  1290. @End(Format)
  1291. @Section(Getting Started)
  1292. Useful functions for invoking GLISP are:
  1293. @Begin(Format)
  1294. @PE[(GLCC 'FN)]@\Compile FN.
  1295. @PE[(GLCP 'FN)]@\Compile FN and prettyprint result.
  1296. @PE[(GLP 'FN)]@\Prettyprint GLISP-compiled version of FN.
  1297. @PE[(GLED 'NAME)]@\Edit the property list of NAME.
  1298. @PE[(GLEDF 'FN)]@\Edit the original (GLISP) definition of FN.
  1299. @\(The original definition is saved under the property
  1300. @\"GLORIGINALEXPR" when the function is compiled, and
  1301. @\the compiled version replaces the function
  1302. @\definition.)
  1303. @PE[(GLEDS 'STR)]@\Edit the structure declarations of STR.
  1304. @End(Format)
  1305. The editing functions call the "BBN/Interlisp" structure editor.
  1306. To try out GLISP, load the GLTEST file and use GLCP to compile the
  1307. functions CURRENTDATE, GIVE-RAISE, TESTFN1, TESTFN2, DRAWRECT,
  1308. TP, GROWCIRCLE, and SQUASH. To run compiled functions on test data,
  1309. do:
  1310. @Begin(ProgramExample)
  1311. (GIVE-RAISE 'COMPANY1)
  1312. (TP '(((A (B (C D (E (G H (I J (K))))))))))
  1313. (GROWCIRCLE MYCIRCLE)
  1314. @END(ProgramExample)
  1315. @Section(Reserved Words and Characters)
  1316. GLISP contains ordinary lisp as a sublanguage. However, in order to
  1317. avoid having code which was intended as "ordinary lisp" interpreted
  1318. as GLISP code, it is necessary to follow certain conventions when
  1319. writing "ordinary lisp" code.
  1320. @Subsection(Reserved Characters)
  1321. The colon and the characters which represent the arithmetic operators
  1322. should not be used within atom names, since GLISP splits apart "atoms"
  1323. which contain operators. The set of characters to be avoided within
  1324. atom names is:
  1325. @Programexample{
  1326. + * / ^ _ ~ = < > : ' ,
  1327. }
  1328. The character "minus" (@PE[ - ]) is permitted within atom names unless
  1329. the flag @PE[GLSEPMINUS] is set.
  1330. Some GLISP constructs permit (but do
  1331. not require) use of the character "comma" (@PE[ , ]); since the comma
  1332. is used as a "backquote" character in some Lisp dialects, the user may
  1333. wish to avoid its use. When used in Lisp dialects which use comma as
  1334. a backquote character, all commas must be "escaped" or "slashified";
  1335. this makes porting of GLISP code containing commas more difficult.
  1336. @Subsection(Reserved Function Names)
  1337. Most GLISP function, variable, and property names begin with "@PE[GL]"
  1338. to avoid conflict with user names. Those "function" names which are
  1339. used in GLISP constructs or in interpretive functions should be
  1340. avoided. This set includes the following names:
  1341. @Programexample{
  1342. A AN CASE FOR IF
  1343. REPEAT SEND SENDPROP THE WHILE
  1344. }
  1345. @SUBSECTION(Other Reserved Names)
  1346. Words which are used within GLISP constructs should be avoided as
  1347. variable names. This set of names includes:
  1348. @ProgramExample{
  1349. A AN DO ELSE ELSEIF
  1350. IS OF THE THEN UNTIL
  1351. }
  1352. @SECTION(Lisp Dialect Idiosyncrasies)
  1353. GLISP code passes through the Lisp reader before it is seen by GLISP.
  1354. For this reason, operators in expressions may need to be set off from
  1355. operands by blanks; the operator "@PE[-]" should always be surrounded
  1356. by blanks, and the operator "@PE[+]" should be separated from numbers
  1357. by blanks.
  1358. @Subsection(Interlisp)
  1359. GLISP compilation happens automatically, and usually does not need
  1360. to be invoked explicitly. GLISP declarations are integrated with the
  1361. file package.
  1362. @Subsection(UCI Lisp)
  1363. The following command is needed before loading to make room for GLISP:
  1364. @ProgramExample[(REALLOC 3000 1000 1000 1000 35000)]
  1365. The compiler file modifies the syntax of the character @B[~] to be
  1366. "alphabetic" so it can be used as a GLISP operator.
  1367. The character "@PE[/]" must be "slashified" to "@PE[//]".
  1368. @Subsection(ELISP)
  1369. For ELISP, the UCI Lisp version of the compiler is used, together with
  1370. a small compatibility file. The above comments about UCI lisp do not
  1371. apply to ELISP.
  1372. The characters "@PE[/]" and "@PE[,]" must be "slashified" to "@PE[//]"
  1373. and "@PE[/,]".
  1374. @Subsection(Maclisp)
  1375. The characters "@PE[/]" and "@PE[,]" must be "slashified" to "@PE[//]"
  1376. and "@PE[/,]".
  1377. @Subsection(Franz Lisp)
  1378. Automatic compilation is implemented for Franz Lisp.
  1379. The character "@PE[,]" and the operators "@PE[+_]" and "@PE[-_]"
  1380. must be "slashified" to "@PE[\,]", "@PE[+\_]", and "@PE[-\_]",
  1381. respectively. Before loading GLISP, edit something to cause the
  1382. editor files to be loaded@Foot[Some versions of the "CMU editor"
  1383. contain function definitions which may conflict with those of
  1384. GLISP; if the editor is loaded first, the GLISP versions override.].
  1385. The Franz Lisp version of GLISP has been tested
  1386. on Opus 38 Franz Lisp; users with earlier versions of Franz might
  1387. encounter difficulties.
  1388. @Section(Bug Reports and Mailing List)
  1389. To get on the GLISP mailing list or to report bugs, send mail to
  1390. CSD.NOVAK@@SU-SCORE.
  1391. @Chapter(GLISP Hacks)
  1392. This chapter discusses some ways of doing things in GLISP which might
  1393. not be entirely obvious at first glance.
  1394. @Section(Overloading Basic Types)
  1395. GLISP provides the ability to define properties of structures described
  1396. in the Structure Description language; since the elementary LISP types
  1397. are structures in this language, objects whose storage representation
  1398. is an elementary type can be "overloaded" by specifying properties
  1399. and operators for them. The following examples illustrate how this
  1400. can be done.
  1401. @Begin(ProgramExample)
  1402. (GLDEFSTRQ
  1403. (ArithmeticOperator (self ATOM)
  1404. PROP ((Precedence OperatorPrecedenceFn RESULT INTEGER)
  1405. (PrintForm ((GETPROP self 'PRINTFORM) or self)) )
  1406. MSG ((PRIN1 ((PRIN1 the PrintForm)))) )
  1407. (IntegerMod7 (self INTEGER)
  1408. PROP ((Modulus (7))
  1409. (Inverse ((If self is ZERO then 0
  1410. else (Modulus - self))) ))
  1411. ADJ ((Even ((ZEROP (LOGAND self 1))))
  1412. (Odd (NOT Even)))
  1413. ISA ((Prime PrimeTestFn))
  1414. MSG ((+ IMod7Plus OPEN T RESULT IntegerMod7)
  1415. (_ IMod7Store OPEN T RESULT IntegerMod7)) )
  1416. )
  1417. (DEFINEQ
  1418. (IMod7Store (GLAMBDA (LHS:IntegerMod7 RHS:INTEGER)
  1419. (LHS:self __ (IREMAINDER RHS Modulus)) ))
  1420. (IMod7Plus (GLAMBDA (X,Y:IntegerMod7)
  1421. (IREMAINDER (X:self + Y:self) X:Modulus) ))
  1422. )
  1423. @End(ProgramExample)
  1424. A few subtleties of the function IMod7Store are worth noting.
  1425. First, the left-hand-side expression used in storing the result is
  1426. LHS:self rather than simply LHS. LHS and LHS:self of course refer
  1427. to the same actual structure; however, the @I[type] of LHS is
  1428. IntegerMod7, while the type of LHS:self is INTEGER. If LHS were
  1429. used on the left-hand side, since the @PE[ _ ] operator is
  1430. overloaded for IntegerMod7, the function IMod7Store would be invoked
  1431. again to perform its own function; since the function is compiled
  1432. OPEN, this would be an infinite loop. A second subtlety is that the
  1433. assignment to LHS:self must use the self-assignment operator, @PE[@ __@ ],
  1434. since it is desired to perform assignment as seen "outside" the
  1435. function IMod7Store, i.e., in the environment in which the original
  1436. assignment operation was specified.
  1437. @Section(Disjunctive Types)
  1438. LISP programming often involves objects which may in fact be of
  1439. different types, but which are for some purposes treated alike.
  1440. For example, LISP data structures are typically constructed of
  1441. CONS cells whose fields may point to other CONS cells or to ATOMs.
  1442. The GLISP Structure Description language does not permit the user
  1443. to specify that a certain field of a structure is a CONS cell @P[or]
  1444. an ATOM. However, it is possible to create a GLISP datatype which
  1445. encompasses both. Typically, this is done by declaring the structure
  1446. of the object to be the complex structure, and testing for the
  1447. simpler structure explicitly. This is illustrated for the case of
  1448. the LISP tree below.
  1449. @Begin(ProgramExample)
  1450. (LISPTREE (CONS (CAR LISPTREE) (CDR LISPTREE))
  1451. ADJ ((EMPTY (@R<~>self)))
  1452. PROP ((LEFTSON ((If self is ATOMIC then NIL else CAR)))
  1453. (RIGHTSON ((If self is ATOMIC then NIL else CDR)))))
  1454. @End(ProgramExample)
  1455. @Section(Generators)
  1456. Often, one would like to define such properties of an object as the
  1457. way of enumerating its parts in some order. Such things
  1458. cannot be specified directly as properties of the object because they
  1459. depend on the previous state of the enumeration. However, it is
  1460. possible to define an object, associated with the original datatype,
  1461. which contains the state of the enumeration and responds to Messages.
  1462. This is illustrated below by an object which searches a tree in Preorder.
  1463. @Begin(ProgramExample)
  1464. (PreorderSearchRecord (CONS (Node LISPTREE)
  1465. (PreviousNodes (LISTOF LISPTREE)))
  1466. MSG ((NEXT ((PROG (TMP)
  1467. (If TMP_Node:LEFTSON
  1468. then (If Node:RIGHTSON
  1469. then PreviousNodes+_Node)
  1470. Node_TMP
  1471. else TMP-_PreviousNodes
  1472. Node_TMP:RIGHTSON) ))))
  1473. (TP (GLAMBDA ((A LISPTREE))
  1474. (PROG (PSR)
  1475. (PSR _ (A PreorderSearchRecord
  1476. with Node = (the LISPTREE)))
  1477. (While Node (If Node is ATOMIC (PRINT Node))
  1478. (_ PSR NEXT)) )))
  1479. @End(ProgramExample)
  1480. The object class PreorderSearchRecord serves two purposes: it holds
  1481. the state of the enumeration, and it responds to messages to step
  1482. through the enumeration. With these definitions, it is easy to write
  1483. a program involving enumeration of a LISPTREE, as illustrated by
  1484. the example function TP above. By being open-compiled, messages to
  1485. an object can be as efficient as in-line hand coding; yet, the code
  1486. for the messages only has to be written once, and can easily be
  1487. changed without changing the programs which use the messages.
  1488. @Chapter(Program Examples)
  1489. In this chapter, examples of GLISP object declarations and programs
  1490. are presented. Each example is discussed as a section of this
  1491. chapter; the code for the examples and the code produced by the
  1492. compiler are shown for each example at the end of the chapter.
  1493. @Section(GLTST1 File)
  1494. The GLTST1 file illustrates the use of several types of LISP
  1495. structures, and the use of fairly complex Property definitions
  1496. for objects. SENIORITY of an EMPLOYEE, for example, is defined
  1497. in terms of the YEAR of DATE-HIRED, which is a substructure of
  1498. EMPLOYEE, and the YEAR of the function (CURRENTDATE).
  1499. @Foot[The @I<type> of (CURRENTDATE) must be known to the compiler,
  1500. either by compiling it first, or by including a RESULT declaration
  1501. in the function definition of CURRENTDATE, or by specifying the
  1502. GLRESULTTYPE property for the function name.]
  1503. @Section(GLTST2 File)
  1504. The GLTST2 file illustrates the use of Messages for ordinary LISP
  1505. objects. By defining the arithmetic operators as Message selectors
  1506. for the object VECTOR, use of vectors in arithmetic expressions
  1507. is enabled; OPEN compilation is specified for these messages.
  1508. The definition of GRAPHICSOBJECT uses VECTORs as components.
  1509. While the actual structure of a GRAPHICSOBJECT is simple,
  1510. numerous properties are defined for user convenience.
  1511. The definition of CENTER is easily stated as a VECTOR expression.
  1512. The Messages of GRAPHICSOBJECT illustrate how different responses
  1513. to a message for different types of objects can be achieved, even
  1514. though for GLISP compilation of messages to LISP objects the code
  1515. for a message must be resolved at compile time.
  1516. @Foot[For objects in a Representation Language, messages may be
  1517. compiled directly as LISP code or as messages to be interpreted at
  1518. runtime, depending on how much is known about the object to which the
  1519. message is sent and the compilation declarations in effect.]
  1520. The DRAW and
  1521. ERASE messages get the function to be used from the property list
  1522. of the SHAPE name of the GRAPHICSOBJECT and APPLY it to draw the
  1523. desired object.
  1524. MOVINGGRAPHICSOBJECT contains a GRAPHICSOBJECT as a TRANSPARENT
  1525. component, so that it inherits the properties of a GRAPHICSOBJECT;
  1526. a MOVINGGRAPHICSOBJECT is a GRAPHICSOBJECT which has a VELOCITY,
  1527. and will move itself by the amount of its velocity upon the message
  1528. command STEP.@Foot[This example is adapted from the MovingPoint
  1529. example written by Dan Bobrow for LOOPS.]
  1530. The compilation of the message
  1531. @PE[(_@ MGO@ STEP)] in the function TESTFN1 is of particular
  1532. interest. This message is expanded
  1533. into the sending of the message @PE[(_@ self@ MOVE@ VELOCITY)]
  1534. to the MOVINGGRAPHICSOBJECT. The MOVINGGRAPHICSOBJECT cannot respond
  1535. to such a message; however, since it contains a GRAPHICSOBJECT as a
  1536. TRANSPARENT component, its GRAPHICSOBJECT responds to the message.
  1537. @Foot[TRANSPARENT substructures thus permit procedural inheritance by
  1538. LISP objects.]
  1539. A GRAPHICSOBJECT responds to a MOVE message by
  1540. erasing itself, increasing its START point by the (vector) distance
  1541. to be moved, and
  1542. then redrawing itself. All of the messages are specified as being
  1543. compiled open, so that the short original message actually generates
  1544. a large amount of code.
  1545. A rectangle is drawn by the function DRAWRECT. Note how the use of
  1546. the properties defined for a GRAPHICSOBJECT allows an easy interface
  1547. to the system functions MOVETO and DRAWTO in terms of the properties
  1548. LEFT, RIGHT, TOP, and BOTTOM.