home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OL.LZH / IDOL.LZH / IDOL.DOC < prev    next >
Text File  |  1991-07-18  |  54KB  |  1,326 lines

  1.  
  2.  
  3.  
  4.                 Programming in Idol: An Object Primer
  5.  
  6.                           Clinton L. Jeffery
  7.  
  8.             January 25, 1990; Last revised March 4, 1991
  9.  
  10. Idol is an object-oriented extension and environment for the Icon
  11. programming language.  This document describes Idol in two parts.
  12. The first part presents Idol's object-oriented programming concepts
  13. as an integral tool with which a programmer maps a good program
  14. design into a good implementation.  As such, it serves as the
  15. "user's guide" for Idol's extensions to Icon.  Idol's
  16. object-oriented programming facilities are viewed within the
  17. broader framework of structured programming and modular design
  18. in general.  Idol's precise syntax and semantics are detailed
  19. in the second part, "An Icon-Derived Object Language", which
  20. serves as a reference manual.
  21.  
  22.  
  23.  
  24.  
  25.  
  26.              Object-Oriented Programming After a Fashion
  27.  
  28. Object-oriented programming means different things to different people.
  29. In Idol, object-oriented programming centers around encapsulation,
  30. inheritance, and polymorphism.  These key ideas are shared by most
  31. object-oriented languages as well as many languages that are not
  32. considered object-oriented.  This paper introduces these ideas and
  33. illustrates their use in actual code.  Idol is relevant in this
  34. discussion because programming concepts are more than mental
  35. exercises; they are mathematical notations by which programmers share
  36. their knowledge.
  37.  
  38. Object-oriented programming can be done in Smalltalk, C++, or
  39. assembler language for that matter, but this does not mean these
  40. programming notations are equally desirable.  Assembler languages
  41. are not portable.  For most programmers, Smalltalk uses an alien
  42. notation; Smalltalk programs also share the flaw that they do not
  43. work well in environments such as UNIX and DOS that consist of
  44. interacting programs written in many languages.  C++ has neither of
  45. these flaws, but the same low-level machine-oriented character
  46. that makes it efficient also makes C++ less than ideal as an
  47. algorithmic notation usable by nonexperts.
  48.  
  49. Idol owes most of its desirable traits to its foundation, the Icon
  50. programming language, developed at the University of Arizona
  51. [Gris90].  In fact, Idol presents objects simply as a tool
  52. to aid in the writing of Icon programs. Idol integrates a concise,
  53. robust notation for object-oriented programming into a language
  54. considerably more advanced than C or Pascal.  Icon already uses a
  55. powerful notation for expressing a general class of algorithms. The
  56. purpose of Idol is to enhance that notation, not to get in the way.
  57.  
  58.  
  59.                              Key Concepts
  60.  
  61. This section describes the general concepts that Idol supplies
  62. to authors of large Icon programs.  The following section provides
  63. programming examples that employ these tools.  The reader is
  64. encouraged to refer back to this section when clarification in
  65. the examples section is needed.
  66.  
  67. The single overriding reason for object-oriented programming
  68. is the large program.  Simple programs can be easily written in
  69. any notation.  Somewhere between the 1,000-line mark and the
  70. 10,000-line mark most programmers can no longer keep track of their
  71. entire program at once.  By using a very high-level programming language,
  72. less lines of code are required; a programmer can write perhaps ten
  73. times as large a program and still be able to keep track of things.
  74. As programmers are required to write larger and larger programs,
  75. the benefit provided by very-high level languages does not keep up
  76. with program complexity.  This obstacle has been labelled the
  77. "software crisis", and object-oriented programming addresses this
  78. crisis.  In short, the goals of object-oriented programming are to
  79. reduce the amount of coding required to write very large programs and
  80. to allow code to be understood independently of the context of the
  81. surrounding program.  The techniques employed to achieve these goals
  82. are discussed below.
  83.  
  84.  
  85.                             Encapsulation
  86.  
  87. The primary concept advocated by object-oriented programming is the
  88. principle of encapsulation.  Encapsulation is the isolation, in the
  89. source code that a programmer writes, of a data representation and the code
  90. that manipulates the data representation.  In some sense, encapsulation
  91. is an assertion that no other routines in the program have "side-effects"
  92. with respect to the data structure in question.  It is easier to reason
  93. about encapsulated data because all of the source code that could affect
  94. that data is immediately present with its definition.
  95.  
  96. Encapsulation does for data structures what the procedure does for
  97. algorithms: it draws a line of demarcation in the program text, the
  98. outside of which is (or can be, or ought to be) irrelevant to the inside.
  99. We call an encapsulated data structure an object. Just as a set of
  100. named variables called parameters comprise the only interface between a
  101. procedure and the code that uses it, a set of named procedures called
  102. methods comprise the only interface between an object and the code that
  103. uses it.
  104.  
  105. This textual definition of encapsulation as a property of program
  106. source code accounts for the fact that good programmers can write
  107. encapsulated data structures in any language.  The problem is not
  108. capability, but verification.  In order to verify encapsulation some
  109. object-oriented languages, like C++, define an elaborate mechanism by
  110. which a programmer can govern the visibility of each data structure.
  111. Like Smalltalk, Idol instead attempts to simplify verification by
  112. preventing violations of encapsulation entirely.
  113.  
  114.  
  115.                              Inheritance
  116.  
  117. In large programs, the same or nearly the same data structures are
  118. used over and over again for a myriad of different purposes.  Similarly,
  119. variations on the same algorithms are employed by structure after
  120. structure.  In order to minimize redundancy, techniques are needed to
  121. support code sharing for both data structures and algorithms.
  122. Code is shared by related data structures by a programming concept
  123. called inheritance.
  124.  
  125. The basic premise of inheritance is simple: if I need to write code
  126. for a new data structure which is similar to one that's already
  127. written, I can specify the new structure by giving the differences
  128. between it and the old structure, instead of copying and then modifying
  129. the old structure's code.  Obviously there are times when the
  130. inheritance mechanism is not useful: if the two data structures are
  131. more different than they are similar, or if they are simple enough
  132. that inheritance would only confuse things, for example.
  133.  
  134. Inheritance addresses a variety of common programming problems found
  135. at different conceptual levels.  The most obvious software engineering
  136. problem it solves might be termed enhancement.  During the
  137. development of a program, its data structures may require extension
  138. via new state variables or new operations or both; inheritance is
  139. especially useful when both the original structure and the extension
  140. are used by the application.  Inheritance also supports
  141. simplification, or the reduction of a data structure's state variables
  142. or operations.  Simplification is analogous to argument culling after
  143. the fashion of the lambda calculus; it captures a logical relation
  144. between structures rather than a common situation in software
  145. development.  In general, inheritance may be used in source code to
  146. describe any sort of relational hyponymy, or special-casing; in Idol
  147. the collection of all inheritance relations defines a directed (not
  148. necessarily acyclic) graph.
  149.  
  150.  
  151.                              Polymorphism
  152.  
  153. From the perspective of the writer of related data structures,
  154. inheritance provides a convenient method for code sharing, but
  155. what about the code that uses objects?  Since objects are
  156. encapsulated, that code is not dependent upon the internals of
  157. the object at all, and it makes no difference to the client code
  158. whether the object in questions belongs to the original class or the
  159. inheriting class.
  160.  
  161. In fact, we can make a stronger statement.  Due to encapsulation,
  162. two different executions of some code that uses objects to implement
  163. a particular algorithm may operate on different objects that are
  164. not related by inheritance at all.  Such code may effectively
  165. be shared by any objects that happen to implement the operations
  166. that the code invokes.  This facility is called polymorphism, and
  167. such algorithms are called generic.  This feature is found in
  168. non-object oriented languages; in object-oriented languages it is
  169. a natural extension of encapsulation.
  170.  
  171.  
  172.                           Object Programming
  173.  
  174. The concepts introduced above are used in many programming languages
  175. in one form or another.  The following text presents these concepts
  176. in the context of actual Idol code.  This serves a dual purpose:
  177. it should clarify the object model adopted by Idol as well as
  178. provide an initial impression of these concepts' utility in coding.
  179. In order to motivate the constructs provided by Idol, our example
  180. begins by contrasting conventional Icon code with Idol code which
  181. implements the same behavior.  The semantics of the Idol code given
  182. here is defined by the Idol reference manual, included later in this
  183. document in the section entitled, "An Icon-Derived Object Language".
  184.  
  185.                             Before Objects
  186.  
  187. In order to place Idol objects in their proper context, the first
  188. example is taken from from regular Icon.  Suppose I am writing some
  189. text-processing application such as a text editor.  Such applications
  190. need to be able to process Icon structures holding the contents of
  191. various text files.  I might begin with a simple structure like the
  192. following:
  193.  
  194. record buffer(filename,text,index)
  195.  
  196. where filename is a string, text is a list of strings
  197. corresponding to lines in the file, and index is a marker for
  198. the current line at which the buffer is being processed.  Icon record
  199. declarations are global; in principle, if the above declaration needs
  200. to be changed, the entire program must be rechecked.  A devotee of
  201. structured programming would no doubt write Icon procedures to read
  202. the buffer in from a file, write it out to a file, examine, insert
  203. and delete individual lines, etc.  These procedures, along with the
  204. record declaration given above, can be kept in a separate source file
  205. (buffer.icn) and understood independently of the program(s) in
  206. which they are used.  Here is one such procedure:
  207.  
  208.  
  209. # read a buffer in from a file
  210. procedure read_buffer(b)
  211.   f := open(b.filename) | fail
  212.   b.text := [ ]
  213.   b.position := 1
  214.   every put(b.text,!f)
  215.   close(f)
  216.   return b
  217. end
  218.  
  219.  
  220. There is nothing wrong with this example; in fact its similarity to the
  221. object-oriented example that follows demonstrates that a good, modular
  222. design is the primary effect encouraged by object-oriented programming.
  223. Using a separate source file to contain a record type and those
  224. procedures which operate on that type allows an Icon programmer to
  225. maintain a voluntary encapsulation of that type.
  226.  
  227.                             After Objects
  228.  
  229. Here is the same buffer abstraction coded in Idol.  This example
  230. lays the groundwork for some more substantial techniques to follow.
  231.  
  232. class buffer(public filename,text,index)
  233.   # read a buffer in from a file
  234.   method read()
  235.     f := open(self.filename) | fail
  236.     selferase()
  237.     every put(self.text,!f)
  238.     close(f)
  239.     return
  240.   end
  241.   # write a buffer out to a file
  242.   method write()
  243.     f := open(self.filename,"w") | fail
  244.     every write(f,!self.text)
  245.     close(f)
  246.   end
  247.   # insert a line at the current index
  248.   method insert(s)
  249.     if self.index = 1 then {
  250.       push(self.text,s)
  251.     } else if self.index > *self.text then {
  252.       put(self.text,s)
  253.     } else {
  254.       self.text := self.text[1:self.index] ||| [s] |||
  255.                      self.text[self.index:0]
  256.     }
  257.     self.index +:= 1
  258.     return
  259.   end
  260.   # delete a line at the current index
  261.   method delete()
  262.     if self.index > *self.text then fail
  263.     rv := self.text[self.index]
  264.     if self.index=1 then pull(self.text)
  265.     else if self.index = *self.text then pop(self.text)
  266.     else self.text := self.text[1:self.index]|||self.text[self.index+1:0]
  267.     return rv
  268.   end
  269.   # move the current index to an arbitrary line
  270.   method goto(l)
  271.     if (0 <= l) & (l <= self.index+1) then return self.index := l
  272.   end
  273.   # return the current line and advance the current index
  274.   method forward()
  275.     if self.index > *self.text then fail
  276.     rv := self.text[self.index]
  277.     self.index +:= 1
  278.     return rv
  279.   end
  280.   method erase()
  281.     self.text     := [ ]
  282.     self.index    := 1
  283.   end
  284. initially
  285.   if   (self.filename) then {
  286.     if not selfread() then selferase()
  287.   } else {
  288.     self.filename := "*scratch*"
  289.     selferase()
  290.   }
  291. end
  292.  
  293.  
  294. This first example is not complex enough to illustrate the full
  295. object-oriented style, but its a start.  Pertaining to the
  296. general concepts introduced above, we can make the following
  297. initial observations:
  298.  
  299. Polymorphism. A separate name space for each class's methods
  300. makes for shorter names.  The same method name can be used in each
  301. class that implements a given operation.  This notation is more
  302. concise than is possible with standard Icon procedures.  More
  303. importantly it allows algorithms to operate correctly upon objects of
  304. any class which implements the operations required by the algorithm.
  305. Constructors.  A section of code is executed automatically when
  306. the constructor is called, allowing initialization of fields to values
  307. other than &null.  Of course, this could be simulated in Icon
  308. by writing a procedure that had the same effect; the value of the
  309. constructor is that it is automatic; the programmer is freed from the
  310. responsibility of remembering to call this code everywhere objects are
  311. created in the client program(s).  This tighter coupling of memory
  312. allocation and its corresponding initialization removes one more
  313. source of program errors, especially on multiprogrammer projects.
  314.  
  315.  
  316. These two observations share a common theme: the net effect is that
  317. each piece of data is made responsible for its own behavior in the
  318. system. Although this first example dealt with simple line-oriented
  319. text files, the same methodology applies to more abstract entities
  320. such as the components of a compiler's grammar (This example
  321. is taken from the Idol translator itself, which provides another
  322. extended example of polymorphism and inheritance.).
  323.  
  324. Idol's code sharing facilities are illustrated if we extend the above
  325. example.  Suppose the application is more than just a text editor---
  326. it includes word-associative databases such as a dictionary,
  327. bibliography, spell-checker, thesaurus, etc.  These various databases
  328. can be represented internally using Icon tables.  The table entries
  329. for the databases vary, but the databases all use string keyword
  330. lookup.  As external data, the databases can be stored in text files,
  331. one entry per line, with the keyword at the beginning.  The format
  332. of the rest of the line varies from database to database.
  333.  
  334. Although all these types of data are different, the code used to
  335. read the data files can be shared, as well as the initial construction
  336. of the tables.  In fact, since we are storing our data one entry per
  337. line in text files, we can use the code already written for buffers
  338. to do the file i/o itself.
  339.  
  340.  
  341. class buftable : buffer()
  342.   method read()
  343.     selfbuffer.read()
  344.     tmp := table()
  345.     every line := !self.text do
  346.       line ? { tmp[tab(many(&letters))] := line | fail }
  347.     self.text := tmp
  348.     return
  349.   end
  350.   method index(s)
  351.     return self.text[s]
  352.   end
  353. end
  354.  
  355.  
  356.  
  357. This concise example shows how little must be written to achieve
  358. data structures with vastly different behavioral characteristics,
  359. by building on code that is already written.  The superclass
  360. read() operation is one important step of the subclass
  361. read() operation; this technique is common enough to have a
  362. name: it is called method combination in the literature. It
  363. allows one to view the subclass as a transformation of the
  364. superclass.  The buftable class is given in its entirety, but
  365. our code sharing example is not complete: what about the data
  366. structures required to support the databases themselves?  They are all
  367. variants of the buftable class, and a set of possible
  368. implementations is given below.  Note that the formats presented are
  369. designed to illustrate code sharing; clearly, an actual application
  370. might make different choices.
  371.  
  372.                             Bibliographies
  373.  
  374. Bibliographies might consist of a keyword followed by an uninterpreted
  375. string of information.  This imposes no additional structure on the
  376. data beyond that imposed by the buftable class.  An example
  377. keyword would be Jeffery90.
  378.  
  379.  
  380. class bibliography : buftable()
  381. end
  382.  
  383.  
  384.  
  385.  
  386.                             Spell-checkers
  387.  
  388. The database for a spell-checker is presumably just a list of words,
  389. one per line; the minimal structure required by the buftable
  390. class given above.  Some classes exist to introduce new terminology
  391. rather than define a new data structure.  In this case we introduce
  392. a lookup operation which may fail, for use in tests.  In addition,
  393. since many spell-checking systems allow user definable dictionaries
  394. in addition to their central database, we allow spellChecker
  395. objects to chain together for the purpose of looking up words.
  396.  
  397.  
  398. class spellChecker : buftable(parentSpellChecker)
  399.   method spell(s)
  400.     return   (self.text[s]) | (  (self.parentSpellChecker))spell(s)
  401.   end
  402. end
  403.  
  404.  
  405.  
  406.  
  407.                              Dictionaries
  408.  
  409. Dictionaries are slightly more involved.  Each entry might consist of a
  410. part of speech, an etymology, and an arbitrary string of uninterpreted
  411. text comprising a definition for that entry, separated by semicolons.
  412. Since each such entry is itself a structure, a sensible decomposition
  413. of the dictionary structure consists of two classes: one that manages
  414. the table and external file i/o, and one that handles the manipulation
  415. of dictionary entries, including their decoding and encoding as
  416. strings.
  417.  
  418.  
  419. class dictionaryentry(word,pos,etymology,definition)
  420.   method decode(s) # decode a dictionary entry into its components
  421.     s ? {
  422.       self.word       := tab(upto(';'))
  423.       move(1)
  424.       self.pos        := tab(upto(';'))
  425.       move(1)
  426.       self.etymology  := tab(upto(';'))
  427.       move(1)
  428.       self.definition := tab(0)
  429.     }
  430.   end
  431.   method encode()  # encode a dictionary entry into a string
  432.     return self.word || ";" || self.pos || ";" ||
  433.              self.etymology || ";" || self.definition
  434.   end
  435. initially
  436.   if /self.pos then {
  437.     # constructor was called with a single string argument
  438.     selfdecode(self.word)
  439.   }
  440. end
  441.  
  442. class dictionary : buftable()
  443.   method read()
  444.     selfbuffer.read()
  445.     tmp := table()
  446.     every line := !self.text do
  447.       line ? { tmp[tab(many(&letters))] := dictionaryentry(line) | fail }
  448.     self.text := tmp
  449.   end
  450.   method write()
  451.     f := open(b.filename,"w") | fail
  452.     every write(f,(!self.text)encode())
  453.     close(f)
  454.   end
  455. end
  456.  
  457.  
  458.  
  459.                                Thesauri
  460.  
  461. Although an oversimplification, one might conceive of a thesauri as a
  462. list of entries, each of which consists of a comma-separated list of
  463. synonyms followed by a comma-separated list of antonyms, with a
  464. semicolon separating the two lists.  Since the code for such a
  465. structure is nearly identical to that given for dictionaries above,
  466. we omit it here (but one might reasonably capture a generalization
  467. regarding entries organized as fields separated by semicolons).
  468.  
  469.  
  470.                Objects and Icon Programming Techniques
  471.  
  472. In examining any addition to a language as large as Icon, a
  473. significant question is how that addition relates to the rest of the
  474. language. In particular, how does object-oriented programming fit into
  475. the suite of advanced techniques used regularly by Icon programmers?
  476. Previous sections of this document expound objects as an
  477. organizational tool, analogous but more effective than the use of
  478. separate compilation to achieve program modularity.  Object-oriented
  479. programming goes considerably beyond that viewpoint.
  480.  
  481. Whether viewed dynamically or statically, the primary effect achieved
  482. by object-oriented programming is the subdivision of program data in
  483. parallel with the code.  Icon already provides a variety of tools that
  484. achieve related effects:
  485.  
  486. Local and Static Variables in Icon procedures are the simplest
  487. imaginable parallel association of data and code.  We do not discuss
  488. them further, although they are by no means insignificant.
  489. Records allow a simple form of user-defined types. They provide
  490. a useful abstraction, but keeping records associated with the right
  491. pieces of code is still the job of the programmer.
  492. String Scanning creates scanning environments.  These are very
  493. useful, but not very general: not all problems can be cast as
  494. string operations.
  495. Co-expressions save a program state for later evaluation.  This
  496. powerful facility has a sweeping range of uses, but unfortunately it
  497. is a relatively expensive mechanism that is frequently misused to
  498. achieve a simple effect.
  499.  
  500.  
  501. Objects and classes, if they are successful, allow a significant
  502. generalization of the techniques developed around the above
  503. language mechanisms.  Objects do not replace these language
  504. mechanisms, but in many cases presented below they provide an
  505. attractive alternative means of achieving similar effects.
  506.  
  507.                          Objects and Records
  508.  
  509. Objects are simply records whose field accesses are voluntarily
  510. limited to a certain set of procedures.
  511.  
  512.                   Objects and Scanning Environments
  513.  
  514. String scanning in Icon is another example of associating a piece of
  515. data with the code that operates on it.  In an Icon scanning
  516. expression of the form e1 ? e2, the result of evaluating
  517. e1 is used implicitly in e2 via a variety of scanning
  518. functions.  In effect, the scanning operation defines a scope in which
  519. state variables &subject and &pos are redefined.
  520. [Walk86] proposes an extension to Icon allowing
  521. programmer-defined scanning environments. The extension involves a new
  522. record data type augmented by sections of code to be executed upon
  523. entry, resumption, and exit of the scanning environment.  The Icon
  524. scanning operator was modified to take advantage of the new facility
  525. when its first argument was of the new environment data type.
  526.  
  527. While objects cannot emulate Icon string scanning syntactically, they
  528. generalize the concept of the programmer-defined scanning environment.
  529. Classes in the Idol standard library include a wide variety of
  530. scanning environments in addition to conventional strings.  The
  531. variation is not limited to the type of data scanned; it also includes
  532. the form and function of the scanning operations.  The form of
  533. scanning operations available are defined by the state variables they
  534. access; in the case of Icon's built-in string scanning, a single
  535. string and a single integer index into that string.
  536.  
  537. There is no reason that a scanning environment cannot maintain a more
  538. complex state, such as an input string, an output string, and a pair
  539. of indices and directions for each string.  Rather than illustrate
  540. the use of objects to construct scanning environments with such an
  541. abstract model, a concrete example is presented below.
  542.  
  543.                             List Scanning
  544.  
  545. List scanning is a straightforward adaptation of string scanning to
  546. the list data type.  It consists of a library class named
  547. ListScan that implements the basic scanning operations, and
  548. various user classes that include the scanning expressions.  This
  549. format is required due to Idol's inability to redefine the semantics
  550. of the ? operator or to emulate its syntax in any reasonable
  551. way.  The state maintained during a list scan consists of
  552. Subject and Pos,  analogous to &subject and
  553. &pos, respectively.
  554.  
  555. ListScan defines analogies to the basic scanning functions of
  556. Icon, e.g. tab, upto, many, any, etc.  These
  557. functions are used in methods  of a ListScan client class, which
  558. in turn defines itself as a subclass of ListScan.  A client such as:
  559.  
  560. class PreNum : ListScan()
  561.   method scan()
  562.     mypos := self.Pos
  563.     suspend selftab(selfupto(numeric))
  564.     self.Pos := mypos
  565.   end
  566. end
  567.  
  568.  
  569. may be used in an expression such as
  570.  
  571. (PreNum(["Tucson", "Pima", 15.0, [ ], "3"]))scan()
  572.  
  573. producing the result ["Tucson", "Pima"].  The conventional Icon
  574. string scanning analogy would be: "abc123" ? tab(upto(&digits)),
  575. which produces the result "abc".  Note that ListScan
  576. methods frequently take list-element predicates as arguments where
  577. their string scanning counterparts take csets.  In the above example,
  578. the predicate numeric supplied to upto is an Icon
  579. function, but predicates may also be arbitrary user-defined procedures.
  580.  
  581. The part of the Idol library ListScan class required to
  582. understand the previous example is presented below.  This code is
  583. representative of user-defined scanning classes allowing pattern
  584. matching over arbitrary data structures in Idol.  Although
  585. user-defined scanning is more general than Icon's built-in scanning
  586. facilities, the scanning methods given below are always
  587. activated in the context of a specific environment.  Icon string
  588. scanning functions can be supplied an explicit environment using
  589. additional arguments to the function.
  590.  
  591.  
  592. class ListScan(Subject,Pos)
  593.   method tab(i)
  594.     if i<0 then i := *self.Subject+1-i
  595.     if i<0 | i>*self.Subject+1 then fail
  596.     origPos := self.Pos
  597.     self.Pos := i
  598.     suspend self.Subject[origPos:i]
  599.     self.Pos := origPos
  600.   end
  601.   method upto(predicate)
  602.     origPos := self.Pos
  603.     every i := self.Pos to *(self.Subject) do {
  604.       if predicate(self.Subject[i]) then suspend i
  605.     }
  606.     self.Pos := origPos
  607.   end
  608. initially
  609.   /(self.Subject) := [ ]
  610.   /(self.Pos) := 1
  611. end
  612.  
  613.  
  614.  
  615.  
  616.                       Objects and Co-expressions
  617.  
  618. Objects cannot come close to providing the power of co-expressions,
  619. but they do provide a more efficient means of achieving well-known
  620. computations such as parallel expression evaluation that have been
  621. promoted as uses for co-expressions.  In particular, a co-expression
  622. is able to capture implicitly the state of a generator for later
  623. evaluation; the programmer is saved the trouble of explicitly coding
  624. what can be internally and automatically performed by Icon's
  625. expression mechanism.  While objects cannot capture a generator state
  626. implicitly, the use of library objects mitigates the cost of
  627. explicitly encoding the computation to be performed, as an
  628. alternative to the use of co-expressions.  The use of objects also is
  629. a significant alternative for implementations of Icon in which
  630. co-expressions are not available or memory is limited.
  631.  
  632.                          Parallel Evaluation
  633.  
  634. In [Gris87], co-expressions are used to obtain the results
  635. from several generators in parallel:
  636.  
  637. decimal   := create(0 to 255)
  638. hex       := create(!"0123456789ABCDEF" || !"0123456789ABCDEF")
  639. octal     := create((0 to 3) || (0 to 7) || (0 to 7))
  640. character := create(image(!&cset))
  641. while write(right(@decimal,3)," ",@hex," ",@octal," ",@character)
  642.  
  643.  
  644.  
  645. For the Idol programmer, one alternative to using co-expressions would
  646. be to link in the following code from the Idol standard library:
  647.  
  648. procedure sequence(bounds[ ])
  649.   return Sequence(bounds)
  650. end
  651.  
  652. class Sequence(bounds,indices)
  653.   method max(i)
  654.     elem := self.bounds[i]
  655.     return (type(elem)== "integer",elem) | *elem-1
  656.   end
  657.   method elem(i)
  658.     elem := self.bounds[i]
  659.     return (type(elem)== "integer",self.indices[i]) |
  660.              elem[self.indices[i]+1]
  661.   end
  662.   method activate()
  663.     top := *(self.indices)
  664.     if self.indices[1] > selfmax(1) then fail
  665.     s := ""
  666.     every i := 1 to top do {
  667.       s ||:= selfelem(i)
  668.     }
  669.     repeat {
  670.        self.indices[top] +:= 1
  671.        if top=1 | (self.indices[top] <= selfmax(top)) then break
  672.        self.indices[top] := 0
  673.        top -:= 1
  674.     }
  675.     return s
  676.   end
  677. initially
  678.   / (self.indices) := list(*self.bounds,0)
  679. end
  680.  
  681.  
  682.  
  683. On the one hand, the above library code is neither terse nor general
  684. compared with co-expressions. This class does, however, allow the
  685. parallel evaluation problem described previously to be coded as:
  686.  
  687. dec       := sequence(255)
  688. hex       := sequence("0123456789ABCDEF","0123456789ABCDEF")
  689. octal     := sequence(3,7,7)
  690. character := sequence(string(&cset))
  691. while write(right(@dec,3)," ",@hex," ",@octal," ",image(@character))
  692.  
  693.  
  694.  
  695. $@ is the unary Idol meta-operator that invokes the
  696. activate() operation. Since the sequence class is already
  697. written and available, its use is an attractive alternative to
  698. co-expressions in many settings.  For example, a general class of
  699. label generators (another use of co-expressions cited in
  700. [Gris87]) is defined by the following library class:
  701.  
  702. class labelgen : Sequence(prefix,postfix)
  703.   method activate()
  704.     return self.prefix||selfSequence.activate()||self.postfix
  705.   end
  706. initially
  707.   /(self.prefix) := ""
  708.   /(self.postfix) := ""
  709.   /(self.bounds)  := [50000]
  710. end
  711.  
  712.  
  713. After creation of a label generator object (e.g.
  714. label := labelgen("L",":")), each resulting label is obtained
  715. via $@label. The sequence defined by this example is
  716.  
  717.         L0:
  718.         L1:
  719.         ...
  720.         L50000:
  721.  
  722.  
  723.  
  724.                               Conclusion
  725.  
  726. Idol presents object programming as a collection of tools to reduce
  727. the complexity of large Icon programs.  These tools are encapsulation,
  728. inheritance, and polymorphism.  Since a primary goal of Idol is to
  729. promote code sharing and reuse, a variety of specific programming
  730. problems have elegant solutions available in the Idol class library.
  731.  
  732.  
  733.                    An Icon-Derived Object Language
  734.  
  735. This section serves as the language reference manual for Idol.  Idol
  736. is a preprocessor for Icon which implements a means of associating a
  737. piece of data with the procedures which manipulate it.  The primary
  738. benefits to the programmer are thus organizational.  The Icon
  739. programmer may view Idol as providing an augmented record type in
  740. which field accesses are made not directly on the records' fields, but
  741. rather through a set of procedures associated with the type.
  742.  
  743.  
  744.                                Classes
  745.  
  746. Since Idol implements ideas found commonly in object-oriented
  747. programming languages, its terminology is taken from that domain.  The
  748. augmented record type is called a "class".  The syntax of a class is:
  749.  
  750.  
  751. class foo(field1,field2,field3,...)
  752.    # procedures to access
  753.    # class foo objects
  754.  
  755. [code to initialize class foo objects]
  756. end
  757.  
  758.  
  759.  
  760. In order to emphasize the difference between ordinary Icon procedures
  761. and the procedures which manipulate class objects, these procedures
  762. are called "methods" (the term is again borrowed from the
  763. object-oriented community).  Nevertheless, the syntax of a method is
  764. that of a procedure:
  765.  
  766.  
  767. method bar(param1,param2,param3,...)
  768.  
  769.    # Icon code which may access
  770.    # fields of a class foo object
  771. end
  772.  
  773.  
  774.  
  775. Since execution of a class method is always associated with a given
  776. object of that class, the method has access to an implicit variable
  777. called self which is a record containing fields whose names are
  778. those given in the class declaration.  References to the self variable
  779. look just like normal record references; they use the dot (.)
  780. operator.  In addition to methods, classes may also contain regular
  781. Icon procedure, global, and record declarations; such declarations
  782. have the standard semantics and exist in the global Icon name space.
  783.  
  784.  
  785.                                Objects
  786.  
  787. Like records, instances of a class type are created with a constructor
  788. function whose name is that of the class.  Instances of a class are
  789. called objects, and their fields may be initialized explicitly in the
  790. constructor in exactly the same way as for records.  For example,
  791. after defining a class foo(x,y) one may write:
  792.  
  793.  
  794. procedure main()
  795.  
  796.   f := foo(1,2)
  797. end
  798.  
  799.  
  800.  
  801. The fields of an object need not be initialized by the class
  802. constructor.  For many objects it is more logical to initialize their
  803. fields to some standard value.  In this case, the class declaration
  804. may include an "initially" section after its methods are defined and
  805. before its end.
  806.  
  807. This section begins with a line containing the word "initially" and
  808. then contains lines which are executed whenever an object of that
  809. class is constructed.  These lines may reference and assign to the
  810. class fields as if they were normal record fields for the object being
  811. constructed.  The "record" being constructed is named self;
  812. more on self later.
  813.  
  814. For example, suppose one wished to implement an enhanced table type
  815. which permitted sequential access to elements in the order they were
  816. inserted into the table.  This can be implemented by a combination of
  817. a list and a table, both of which would initialized to the appropriate
  818. empty structure:
  819.  
  820.  
  821. class taque(l,t) # pronouned `taco'
  822.  
  823.   # methods to manipulate taques,
  824.   # e.g. insert, index, foreach...
  825.  
  826. initially
  827.   self.l := [ ]
  828.   self.t := table()
  829. end
  830.  
  831.  
  832.  
  833. And in such a case one can create objects without including arguments
  834. to the class constructor:
  835.  
  836.  
  837. procedure main()
  838.  
  839.   mytaque := taque()
  840. end
  841.  
  842.  
  843.  
  844. In the absence of an initially section, missing arguments to a
  845. constructor default to the null value.  Together with an initially
  846. section, the class declaration looks rather like a procedure that
  847. constructs objects of that class.  Note that one may write classes
  848. with some fields that are initialized explicitly by the constructor
  849. and other fields are initialized automatically in the initially
  850. section.  In this case one must either declare the automatically
  851. initialized fields after those that are initialized in the
  852. constructor, or insert &null in the positions of the
  853. automatically initialized fields in the constructor.
  854.  
  855.  
  856.  
  857.                           Object Invocation
  858.  
  859. Once one has created an object with a class constructor, one
  860. manipulates the object by invoking methods defined by its class.
  861. Since objects are both procedures and data, object invocation is
  862. similar to both a procedure call and a record access.  The dollar
  863. ($) operator invokes one of an object's methods.  The syntax is
  864. object $ method name ( arguments )
  865.  where the parenthesis may be omitted if the argument list
  866. is empty.  $ is used similarly to the dot (.) operator used to
  867. access record fields.  Using the taque example:
  868.  
  869.  
  870. procedure main()
  871.   mytaque := taque()
  872.   mytaqueinsert("greetings","hello")
  873.   mytaqueinsert(123)
  874.   every write(mytaqueforeach())
  875.   if \(mytaqueindex("hello"))
  876.     then write(", world")
  877. end
  878.  
  879.  
  880.  
  881. Note that direct access to an object's fields using the usual dot (.)
  882. operator is not possible outside of a method of the appropriate class.
  883. Attempts to reference mystack.l in procedure main() would result in
  884. a runtime error (invalid field name).  Within a class method, the
  885. implicit variable self allows access to the object's fields in
  886. the usual manner.  The taque insert method is thus:
  887.  
  888.  
  889.   method insert(x,key)
  890.     /key := x
  891.     put(self.l,x)
  892.     self.t[key] := x
  893.   end
  894.  
  895.  
  896.  
  897. The self variable is both a record and an object.  It allows field
  898. access just like a record, as well as method invocation like any other
  899. object.  Thus class methods can use self to invoke other class methods
  900. without any special syntax.
  901.  
  902.  
  903.  
  904.                              Inheritance
  905.  
  906. In many cases, two classes of objects are very similar.  In
  907. particular, many classes can be thought of simply as enhancements of
  908. some class that has already been defined.  Enhancements might take the
  909. form of added fields, added methods, or both.  In other cases a class
  910. is just a special case of another class.  For example, if one had
  911. defined a class fraction(numerator, denominator), one might want to
  912. define a class inverses(denominator) whose behavior was identical to
  913. that of a fraction, but whose numerator was always 1.
  914.  
  915. Idol supports both of these ideas with the concept of inheritance.
  916. When the definition of a class is best expressed in terms of the
  917. definition of another class or classes, we call that class a subclass
  918. of the other classes.  This corresponds to the logical relation of
  919. hyponymy. It means an object of the subclass can be manipulated just
  920. as if it were an object of one of its defining classes.  In practical
  921. terms it means that similar objects can share the code that
  922. manipulates their fields. The syntax of a subclass is
  923.  
  924.  
  925. class foo : superclasses (fields...)
  926.  
  927. # methods
  928. [optional initially section]
  929. end
  930.  
  931.  
  932.  
  933.  
  934.                          Multiple Inheritance
  935.  
  936. There are times when a new class might best be described as a
  937. combination of two or more classes.  Idol classes may have more than
  938. one superclass, separated by colons in the class declaration.  This is
  939. called multiple inheritance.
  940.  
  941. Subclasses define a record type consisting of all the fieldnames found
  942. in the class itself and in all its superclasses.  The subclass has
  943. associated methods consisting of those in its own body, those in the
  944. first superclass which were not defined in the subclass, those in the
  945. second superclass not defined in the subclass or the first superclass,
  946. and so on.  Fields are initialized either by the constructor or by the
  947. initially section of the first class of the class:superclass list in
  948. which the field is defined.  For example, to define a class of
  949. inverses in terms of a class fraction(numerator,denominator) one
  950. would write:
  951.  
  952.  
  953. class inverse : fraction (denominator)
  954. initially
  955.   self.numerator := 1
  956. end
  957.  
  958.  
  959.  
  960. Objects of class inverse can be manipulated using all the methods
  961. defined in class fraction; the code is actually shared by both classes
  962. at runtime.
  963.  
  964. Viewing inheritance as the addition of fieldnames and methods of
  965. superclasses not already defined in the subclass is the opposite of
  966. the more traditional object-oriented view that a subclass starts with
  967. an instance of the superclass and augments or overrides portions of
  968. the definition with code in the subclass body.  Idol's viewpoint adds
  969. quite a bit of leverage, such as the ability to define classes which
  970. are subclasses of each other.  This feature is described further below.
  971.  
  972.  
  973.                     Invoking Superclass Operations
  974.  
  975. When a subclass defines a method of the same name as a method defined
  976. in the superclass, invocations on subclass objects always result in
  977. the subclass' version of the method.  This can be overridden by
  978. explicitly including the superclass name in the invocation:
  979.  
  980. objectsuperclass.method(parameters)
  981.  
  982. This facility allows the subclass method to do any additional work
  983. required for added fields before or after calling an appropriate
  984. superclass method to achieve inherited behavior.  The result is
  985. frequently a chain of inherited method invocations.
  986.  
  987.  
  988.  
  989.                             Public Fields
  990.  
  991. As noted above, there is a strong correspondence between records and
  992. classes.  Both define new types that extend Icon's built-in
  993. repertoire.  For simple jobs, records are slightly faster as well as
  994. more convenient: the user can directly read and write a record's
  995. fields by name.
  996.  
  997. Classes, on the other hand, promote the re-use of code and reduce the
  998. complexity required to understand or maintain large, involved
  999. structures.  They should be used especially when manipulating
  1000. composite structures ontaining mixes of structures as elements, e.g.
  1001. lists containing tables, sets, and lists in various positions.
  1002.  
  1003. Sometimes it is useful to access fields in an object
  1004. directly, as with records.  An example from the Idol program itself is
  1005. the name field associated with methods and classes---it is a
  1006. string which is intended to be read outside the object.  One can
  1007. always implement a method which returns (or assigns, for that matter)
  1008. a field value, but this gets tedious.  Idol currently supports
  1009. read-only access to fields via the public keyword.  If
  1010. public precedes a fieldname in a class declaration, Idol
  1011. automatically generates a method of the same name which dereferences
  1012. and returns the field.  For example, the declaration
  1013.  
  1014. class sinner(pharisee,public publican)
  1015.  
  1016. generates code equivalent to the following class method in addition
  1017. to any explicitly defined methods:
  1018.  
  1019.   method publican()
  1020.     return .(self.publican)
  1021.   end
  1022.  
  1023.  
  1024.  
  1025. This feature, despite its utility and the best of intentions, makes it
  1026. possible to subvert object encapsulation: it should not be
  1027. used with fields whose values are structures, since the structure
  1028. could then be modified from the outside.  When invoked with the
  1029. -strict option, Idol generates code for public methods which
  1030. checks for a scalar type at runtime before returning the field.
  1031.  
  1032.  
  1033.  
  1034.                 Superclass Cycles and Type Equivalence
  1035.  
  1036. In many situations, there are several ways to represent the same
  1037. abstract type.  Two-dimensional points might be represented by
  1038. Cartesian coordinates x and y, or equivalently by radial coordinates
  1039. expressed as degree d and radian r.  If one were implementing classes
  1040. corresponding to these types there is no reason why one of them should
  1041. be considered a subclass of the other.  The types are truly
  1042. interchangeable and equivalent.
  1043.  
  1044. In Idol, expressing this equivalence is simple and direct.  In defining
  1045. classes Cartesian and Radian we may declare them to be superclasses of
  1046. each other:
  1047.  
  1048. class Cartesian : Radian (x,y)
  1049. # code which manipulates objects using cartesian coordinates
  1050. end
  1051.  
  1052. class Radian : Cartesian (d,r)
  1053. # code which manipulates objects using radian coordinates
  1054. end
  1055.  
  1056.  
  1057. These superclass declarations make the two types equivalent names for
  1058. the same type of object; after inheritance, instances of both classes
  1059. will have fields x, y, d, and r, and support
  1060. the same set of operations.
  1061.  
  1062. Equivalent types each have their own constructor given by their class
  1063. name; although they export the same set of operations, the actual
  1064. procedures invoked by the different instances may be different.  For
  1065. example, if both classes define an implementation of a method
  1066. print, the method invoked by a given instance depends on
  1067. which constructor was used when the object was created.
  1068.  
  1069. If a class inherits any methods from one of its equivalent
  1070. classes, it is responsible for initializing the state of all
  1071. the fields used by those methods in its own constructor, and
  1072. maintaining the state of the inherited fields when its methods make
  1073. state changes to its own fields.  In the geometric example given
  1074. above, in order for class Radian to use any methods inherited
  1075. from class Cartesian, it must at least initialize x and
  1076. y explicity
  1077. in its constructor from calculations on its d and r parameters.
  1078. In general, this added responsibility is minimized in those classes
  1079. which treat an object's state as a value rather than a structure.
  1080.  
  1081. The utility of equivalent types expressed by superclass cycles remains
  1082. to be seen.  At the least, they provide a convenient way to write
  1083. several alternative constructors for the same class of objects.
  1084. Perhaps more importantly, their presence in Idol causes us to question
  1085. the almost religious dogmatism that the superclass graph must always
  1086. be acyclic.
  1087.  
  1088.  
  1089.  
  1090.                               Miscellany
  1091.  
  1092.                          Unary Meta-operators
  1093.  
  1094. Idol supports some shorthand for convenient object invocation.  In
  1095. particular, if a class defines methods named size, foreach, random,
  1096. or activate, these methods can be invoked by a modified version of
  1097. the usual Icon operator:
  1098.  
  1099.  
  1100. $*x is equivalent to xsize()
  1101. $?x is equivalent to xrandom()
  1102. $!x is equivalent to xforeach()
  1103. $@x is equivalent to xactivate()
  1104.  
  1105.  
  1106. Other operators may be added to this list.  If x is an identifier
  1107. it may be used directly.  If x is a more complex expression such as a
  1108. function call, it should be parenthesized, e.g.
  1109. $*(complex_expression()).
  1110. Parentheses are also required in the case of invoking an object
  1111. returned from an invocation, e.g.
  1112.  
  1113.   (classesindex("theClass"))name()
  1114.  
  1115. These requirements are artifacts of the first implementation and are
  1116. subject to change.
  1117.  
  1118.                        Nonunary Meta-operators
  1119.  
  1120. In addition to the unary meta-operators described above, Idol supports
  1121. certain operators with more exotic capabilities.  The expression
  1122. x $$ y(arguments) denotes a list invocation of method
  1123. y for object x and is analogous to Icon's list invocation operator
  1124. (binary !).  Arguments is some list which will be
  1125. applied to the method as its actual parameter list.  List invocation
  1126. is particularly useful in handling methods which take a variable
  1127. number of arguments and allows such methods to call each other.
  1128. Idol list invocation is a direct application of Icon list invocation
  1129. to object methods that could not be done otherwise without knowledge
  1130. of Idol internals.
  1131.  
  1132. Another binary meta-operator is the object index operator given by
  1133. $[, as in the expression x $[ e ].  This expression
  1134. is an equivalent shorthand for x$index(e).  Note that only
  1135. the left brace is preceded by a dollar sign.  The expression in the
  1136. braces is in actuality simply a comma separated list of arguments
  1137. to the index method.
  1138.  
  1139.  
  1140.                               Constants
  1141.  
  1142. As a convenience to the programmer, Idol supports constant
  1143. declarations for the builtin Icon types that are applicative---
  1144. strings, integers, reals, and csets.  Constant declarations are
  1145. similar to global variable declarations with a predefined value:
  1146.  
  1147.   const E_Tick := ".", E_Line := "_", E_Mask := '._'
  1148.  
  1149. Constant declarations are defined from their point of declaration
  1150. to the end of the source file if they are defined globally, or to
  1151. the end of the class definition if they are located within a class.
  1152. Constants may not be declared within a procedure.  Constants are
  1153. equivalent to the textual replacement of the name by the value.
  1154.  
  1155.  
  1156.                             Include Files
  1157.  
  1158. Idol supports an \#include directive as a convenience to the programmer.
  1159. The include directive consists of a line beginning with the string
  1160. "\#include" followed by a filename that is optionally enclosed
  1161. in quotation marks.  When the include directive is encountered, Idol
  1162. reads the contents of the named file as if it were part of the
  1163. current file.  Include files may be nested, but not recursive.
  1164.  
  1165. Since Idol and Icon do not have a compile-time type system, their need
  1166. for sharing via file inclusion is significantly less than in
  1167. conventional programming languages.  Nevertheless, this is one of the
  1168. more frequently requested features missing in Icon.  Include files are
  1169. primarily intended for the sharing of constants and global variable
  1170. identifiers in separately translated modules.
  1171.  
  1172.  
  1173.                      Implementation Restrictions
  1174.  
  1175. The Idol preprocessor is written in Idol and does not actually parse
  1176. the language it purports to implement.  In particular, the
  1177. preprocessor is line-oriented and the initially keyword, and the class
  1178. and method end keyword need to be on a line by themselves.  Similarly,
  1179. both the object being invoked and its method name must be on the
  1180. same line for invocations.  If an object invocation includes an
  1181. argument list, it must begin on the line of the invocation, since
  1182. Idol inserts parentheses for invocations where they are omitted.  This
  1183. is comparable to Icon's semi-colon insertion; it is a convenience that
  1184. may prove dangerous to the novice.  Likewise, the $[ index
  1185. operator, its arguments, and its corresponding close brace must all
  1186. be on the same line with the invoking object.
  1187.  
  1188. Class and method declarations are less restricted: the field/parameter
  1189. list may be written over multiple lines if required, but the keyword is
  1190. recognized only if it begins a line (only whitespace may precede it),
  1191. and that line must include the class/method name, any superclasses,
  1192. and the left parenthesis that opens the field/parameter list.
  1193.  
  1194. The Idol preprocessor reserves certain names for internal use.  In
  1195. particular, __state and __methods are not legal class
  1196. field names.  Similarly, the name idol_object is reserved in the
  1197. global name space, and may not be used as a global variable, procedure,
  1198. or record name. Finally, for each class foo amongst the user's
  1199. code, the names foo, foo__state, foo__methods,
  1200. foo__oprec are reserved, as are the names foo_bar
  1201. corresponding to each method bar in class foo. These
  1202. details are artifacts of the current implementation and are subject
  1203. to change.
  1204.  
  1205.                                Caveats
  1206.  
  1207. Subclass constructors can be confusing, especially when multiple
  1208. inheritance brings in various fields from different superclasses.
  1209. One significant problem for users of the subclass is that the
  1210. parameters expected in the constructor may not be obvious if they
  1211. are inherited from a superclass.  On the other side of the spectrum,
  1212. superclasses which automatically initialize their fields can be
  1213. less than useful if the subclass might need to override the
  1214. default initialization value--the subclass must then explicitly
  1215. name the field in order to make its initially section have
  1216. precedence over the superclass.
  1217.  
  1218. The first of the two problems given above can be solved by naming
  1219. fields explicitly in a subclass when initialization by constructor.
  1220. This achieves clarity at the expense of changing the inheritance
  1221. behavior, since the subclass no longer inherits the superclass
  1222. automatic initialization for that field if there is one.  The latter
  1223. of the two problems can generally be solved by using the / operator
  1224. in automatic field initializations unless the initialization should
  1225. never be overridden.
  1226.  
  1227. While it is occasionally convenient to redeclare an inherited field
  1228. in a subclass, accidentally doing so and then using that field to store an
  1229. unrelated value would be disastrous.  Although Idol offers no proper
  1230. solution to this problem, the -strict option causes the generation
  1231. of warning messages for each redefined field name noting the relevant
  1232. sub- and superclasses.
  1233.  
  1234.  
  1235.  
  1236.                              Running Idol
  1237.  
  1238. Idol requires Version 8 of Icon.  It runs best on UNIX
  1239. systems.  It has been ported to most but not all the various systems
  1240. on which Icon runs.  In particular, if your version of Icon does not
  1241. support the system() function, or your machine does not have
  1242. adequate memory available, Idol will not be able to invoke icont
  1243. to complete its translation and linking.  Since Idol is untested on
  1244. some systems, you may have to make small changes to the source code
  1245. in order to port it to a new system.
  1246.  
  1247. Since its initial inception, Idol has gone through several major
  1248. revisions.  This document describes Idol Version 8.  Contact the
  1249. author for current version information.
  1250.  
  1251.  
  1252.                             Getting a Copy
  1253.  
  1254. Idol is in the public domain.  It is available on the Icon RBBS and by
  1255. anonymous ftp from cs.arizona.edu.  Idol is also distributed with
  1256. the program library for Version 8 of Icon and is available by U.S.
  1257. mail in this way.  Interested parties may contact the author
  1258. (cjeffery@cs.arizona.edu):
  1259.  
  1260.          Clinton Jeffery
  1261.          Department of Computer Science
  1262.          University of Arizona
  1263.          Tucson, AZ 85721
  1264.  
  1265.  
  1266.                      Creating an Idol Executable
  1267.  
  1268. Idol is typically distributed in both Idol and Icon source forms.
  1269. Creating an Idol executable requires a running version of Icon and a
  1270. copy of idolboot.icn, the Icon source for Idol.  A second Icon
  1271. source file contains the operating-system dependent portion of Idol;
  1272. for example, unix.icn (see the Idol README file for the name of
  1273. your system file if you are not on a UNIX system; you may have to
  1274. write your own, but it is not difficult).  Using icont, compile
  1275. idolboot.icn and unix.icn into an executable file (named
  1276. idolboot, or  idolboot.icx). As a final step, rename this
  1277. executable to idol (or idol.icx).
  1278.  
  1279.  
  1280.                       Translating Idol Programs
  1281.  
  1282. The syntax for invoking idol is normally
  1283.  
  1284. idol file1[.iol] [files...]
  1285.  
  1286. (on some systems you may have to say "iconx idol" where it
  1287. says "idol" above).  The Idol translator creates a separate
  1288. Icon file for each class in the Idol source files you give it.  On
  1289. most systems it calls icont automatically to create ucode for these
  1290. files.  If the first file on the command line has any normal Icon code
  1291. in it (in addition to any class definitions it may contain), Idol
  1292. attempts to link it to any classes it may need and create an executable.
  1293.  
  1294. The file extension defaults to .iol.  Idol also accepts
  1295. extensions .icn, .u1, and .cl.  The first two refer
  1296. to Icon source or already translated code for which Idol generates
  1297. link statements in the main (initial) Idol source file.  Idol treats
  1298. arguments with the extension .cl as class names and generates
  1299. link statements for that class and its superclasses.  Class names are
  1300. case-sensitive; Deque.cl is not the same class as deque.cl.
  1301.  
  1302.                               References
  1303.  
  1304.  
  1305.  
  1306. [Gris87]
  1307. Griswold, R.E.
  1308. Programming in Icon; Part I---Programming with
  1309.   Co-Expressions.
  1310. Technical Report 87-6, Department of Computer Science, University of
  1311.   Arizona, June 1987.
  1312.  
  1313. [Gris90]
  1314. Griswold, R.E. and Griswold, M.T.
  1315. The Icon Programming Language, second edition.
  1316. Prentice-Hall, Englewood Cliffs, New Jersey, 1990.
  1317.  
  1318. [Walk86]
  1319. Walker, K.
  1320. Dynamic Environments---A Generalization of Icon String
  1321.   Scanning.
  1322. Technical Report 86-7, Department of Computer Science, University of
  1323.   Arizona, March 1986.
  1324.  
  1325.  
  1326.