home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / language / quinta.cpt / Quinta / Quinta.doc.txt < prev    next >
Text File  |  1990-04-04  |  16KB  |  379 lines

  1. Quinta
  2.  
  3. ⌐ 1990  Eric W. Sink
  4.  
  5. Introduction
  6.  
  7. This document describes the language Quinta, an object 
  8. oriented, stack based programming language.  Quinta has been 
  9. implemented on the Macintosh.
  10.  
  11. Basic Definitions
  12.  
  13. The relevant terms in Quinta are object, class, message, and 
  14. response.  These terms will be explained below with examples 
  15. given later.
  16.  
  17. Objects represent data.  Each object is an instance of a class.  
  18. Different forms of data are represented by different classes.  An 
  19. object my be pushed on the stack.  An object may also be stored 
  20. into a variable.  An object may be destroyed.
  21.  
  22. Messages manipulate data.  A message is sent to the object(s) on 
  23. top of the stack.  The actual manipulations which take place 
  24. depend entirely on the response of the receiving object(s) to the 
  25. message which was sent.  It is possible that the object(s) will not 
  26. respond at all.
  27.  
  28. For a given message and object on top of the stack, the response 
  29. of the object to the given message is determined by the class of 
  30. the object.  If the class of the object is defined to respond to the 
  31. message, then the object will respond in the defined manner.
  32.  
  33. Classes have a relationship to one another which allows them to 
  34. share responses.  A class may have one or more subclasses.  A 
  35. subclass inherits all of the responses of its parent.  Any object of 
  36. the subclass may respond to any message to which objects of its 
  37. parent class may respond as well.  Subclasses may have 
  38. subclasses themselves.  Any inherited response has an original 
  39. definition class.  This class, the class in which the response is 
  40. defined and not inherited, is referred to as the home of the 
  41. response.
  42.  
  43. Generally, the definition of a response to a given message for a 
  44. given class is another stream of messages to be sent.  In other 
  45. words, an object responds to a message by sending more 
  46. messages.
  47.  
  48. A response to a message for a given class may be public or 
  49. private.  A private message may not be sent from outside of the 
  50. class in which it is defined.  In other words, a response may only 
  51. send private messages successfully to objects of the same class as 
  52. its home.  A public response may be sent by the response of any 
  53. object.  If a private message is sent to an object by an entity 
  54. outside of the class of that object, the object will not respond.
  55.  
  56. Lexical Conventions
  57.  
  58. Quinta source code is stored in text files.  The code consists of 
  59. tokens, delimited by white space.  Delimiter characters are 
  60. defined so that a token may contain white space.  Quinta source 
  61. code is a stream of tokens.  A token can be either a message (a 
  62. command) or the textual representation of an object (a data 
  63. constant).  A token is passed to the interpreter for processing by 
  64. typing it in the Worksheet window and pressing ENTER.  
  65. Quinta messages will appear in this text underlined.  
  66. Capitalization is important -- the Quinta interpreter is case 
  67. sensitive.  Also, TOS is the abbreviation for Top Of Stack.
  68.  
  69. Quinta Constructs
  70.  
  71. The most important data structure of Quinta is the main stack, 
  72. simply referred to as the stack.  The stack is global and can hold 
  73. objects, and only objects.  The fundamental mechanism in 
  74. execution of a Quinta program is the passing of messages to the 
  75. stack.  The object(s) on the stack respond appropriately to the 
  76. messages, perhaps generating more messages and modifying the 
  77. stack further.
  78.  
  79. The stack is used as the intermediate storage for all calculations 
  80. and manipulations of data.  Therefore, all operations are 
  81. postfix.  This "Reverse-Polish" system gives Quinta the flavor 
  82. of Forth, or an RPN calculator.  Any token received by the 
  83. interpreter which is not a message will be processed as the 
  84. textual representation of an object.  If the token does not match 
  85. any standard pattern for conversion to an object, it is an error.  
  86. If the token is converted to an object, it is pushed onto the stack.  
  87. For example, by typing
  88.  
  89.     487.9962
  90.  
  91. into the Quinta interpreter, a floating point object would be 
  92. pushed onto the stack.  Then by typing
  93.  
  94.     sqrt
  95.  
  96. the floating point object on TOS would change to 
  97. 22.0906360252.  sqrt is a message.  "487.9962" is the textual 
  98. representation of an object.  The class of this object is float.  
  99. Objects of class float have a response defined for the message 
  100. sqrt.   The effect of this response is to push a new object 
  101. containing the square root of the value of the receiver.
  102.  
  103. The interpreter continually obtains tokens from the user and 
  104. processes them.  Any token is assumed to be a message and is 
  105. passed to the object on top of the stack.  If the class of that object 
  106. or any of its super classes have a response defined for the 
  107. message specified by the token, that response is interpreted.  
  108. Otherwise, the interpreter attempts to convert the token to an 
  109. object and push it onto the stack. 
  110.  
  111. Messages are always passed to the object or set of objects on 
  112. TOS.  The number of receivers of the message is determined by 
  113. the order of the message.  A message of order n requires n 
  114. receivers.  For example, sqrt is a message of order 1.  Exactly 1 
  115. object is needed to respond to this message.  An example of such 
  116. an object is a float, which must be the object on TOS.
  117.  
  118. However, swap is a message of order 2.  For this message to be 
  119. interpreted, there must be a response defined for the 2 objects in 
  120. level 1 and 2 of the stack.  This particular message is a trivial 
  121. example, because swap is defined for ANY two objects on TOS.  
  122. swap has a response defined for the set of classes 
  123. "generic:generic".  All object classes are subclasses of generic, 
  124. so any two objects can be swapped.  The effect of swap is to 
  125. exchange the objects in level 1 and 2 of the stack.  Note that swap 
  126. is not defined for a single object; i.e. the depth of the stack must 
  127. be at least 2.
  128.  
  129. A more complicated example is the message *.  This message is 
  130. obviously used for multiplication.  There are many different 
  131. responses possible for this message.  For example, there is a 
  132. response to * defined for the classes "integer:float".  In other 
  133. words, if the object in level 1 of the stack is an integer and the 
  134. object in level 2 is a float, then that response will be executed.  
  135. The effect of this message is to multiply the two numbers a push 
  136. the result onto the stack.  (Incidentally, in Quinta, multiplication 
  137. of an integer and a float produces a float.)  There is also a 
  138. separate response defined for the classes "float:integer".  
  139. Clearly, * is a message of order 2.
  140.  
  141. This mechanism, known in some other object oriented languages 
  142. as a multimethod, is quite flexible.  For example, there is a 
  143. response to * defined for "matrix:integer" which implements 
  144. the multiplication of a matrix by an integer constant, pushing the 
  145. resulting matrix.  However, there is no response to + defined for 
  146. "matrix:integer".  The addition of a matrix and an integer does 
  147. not produce a defined result.
  148.  
  149. Consider the following line of Quinta source:
  150.  
  151.     45 98 + dup print drop
  152.  
  153. 45 is an Integer, it is pushed onto the stack.  98 is handled the 
  154. same way.
  155.  
  156. The next token is +.  This is a message.  The message is passed to 
  157. the top of the stack.  + is a message of order 2.  Both of the top 
  158. two items on the stack are of class integer.  The classes 
  159. integer:integer have a response defined for message +.  The 
  160. effect of this response is to add the two integers and return the 
  161. result to the top of the stack.
  162.  
  163. dup is a message.  At this time, the object on top of the stack is an 
  164. integer (the sum of 45 and 98).  The message dup has no 
  165. response defined in class Integer.  However, the class integer is 
  166. indirectly a subclass of the class generic.  Class generic has a 
  167. response defined which duplicates the object on top of the stack.  
  168. Because integer is a subclass of generic, it inherits all of the 
  169. responses defined for generic.  Consequently, objects of class 
  170. integer may respond to dup, even though a special response to 
  171. this message is not defined for that class.  Notice, that since all 
  172. classes are subclasses of generic, any object may be duplicated.
  173.  
  174. print and drop are messages which output an object's textual 
  175. representation and drop an object from the top of the stack, 
  176. respectively.
  177.  
  178. Note that Quinta messages are untyped.  In other words, a given 
  179. message does not always modify the stack in an identical known 
  180. manner for all its responses.  Multiplication of two integers 
  181. yields an integer.  Multiplication of two floats yields a float.  
  182. The interpreter places no restrictions on user defined responses, 
  183. except that all responses to a given message must be of the same 
  184. order.  However, a user is free to define a response to * for 
  185. classes generic:string which exits the interpreter.  It is good 
  186. practice to keep the essential effect and meaning consistent in all 
  187. responses to a given message.  For example, drop should always 
  188. drop the object from the top of stack.  Quinta will happily allow 
  189. you to define a response to drop which duplicates the receiver, 
  190. but to do so would be poor practice.
  191.  
  192.  
  193.  
  194. Response definitions
  195.  
  196. The essence of Quinta programming is in defining new classes 
  197. of objects and in defining new responses for the various classes.
  198.  
  199. To define a response to a message, the following four items are 
  200. needed on the stack, in order (the last item is the top of the 
  201. stack):
  202. 4:    A Block of tokens which will become the response
  203. 3:    A String containing the name of the message
  204. 2:    A Logical which should be TRUE if the response is to be 
  205. Private.
  206. 1:    A List object, containing the set of classes for which the 
  207. message is to be defined.  The number of elements in this list is 
  208. the order of the message.
  209.  
  210. If an attempt is made to define a response to a nonexistent 
  211. message, the message is newly created.
  212.  
  213.  
  214. For convenience, the messages priv and pub have been 
  215. predefined as true and false, respectively.
  216.  
  217. An example response definition:  Suppose we wished to define a 
  218. public message to drop two objects from the stack and multiply 
  219. the third by 4.  We will call this message TRYME.
  220.  
  221.     [ drop drop 4 * ] "TRYME" pub generic 1 >list
  222.  
  223. This set of four tokens prepares the stack to create the new 
  224. response.  To actually perform the operation, we must send the 
  225. message respond.  This will be received by the class object on 
  226. top of the stack, and the response will be created.
  227.  
  228. Therefore, consider the following fragment of source:
  229.  
  230.     [ drop drop 4 * ] "TRYME" pub generic 1 >list respond
  231.     7 4 9 TRYME print
  232.  
  233. The output of this fragment is
  234.     28
  235.  
  236. Class Definitions
  237.  
  238. To define a new class, the following objects are needed on top of 
  239. the stack, in order:
  240.  
  241. 4:    A List of strings giving the names of the Public data 
  242. members of the class
  243. 3:    A List of strings giving the names of the Private data 
  244. members of the class
  245. 2:    A String containing the name of the new class
  246. 1:    A class object which will be the parent class.
  247.  
  248. The message which must be sent to perform the actual operation 
  249. is subclass.
  250.  
  251. For example, let us say we want to define a class to represent a 
  252. window, such as is found in a Window, Icon, Mouse and Pointer 
  253. operating system interface.  The attributes of the window will be 
  254. the location of the cursor, the size of the window, and whether 
  255. or not it needs to be redrawn.  These will correspond to 4 
  256. integers and a logical.  The cursor coordinates will be public and 
  257. the other data members will be private.
  258.  
  259.     "Height" "Width" "Dirty" 3 >list
  260.     "X_cursor" "Y_cursor" 2 >list
  261.     "Window" generic subclass
  262.  
  263. There is now a class Window which has 5 member variables.  In 
  264. most cases, member variables may be treated exactly as 
  265. "regular" variables which are described in the next section.
  266.  
  267. Variables
  268.  
  269. A variable is a place to store an object.  To store an object into a 
  270. variable, push the object, then push the variable and send the 
  271. message sto.  To recall the value stored, push the variable and 
  272. send the message rcl.  Once a value has been stored in a variable, 
  273. simply sending the variable name as a message results in a rcl as 
  274. well.
  275.  
  276. A variable object may be removed by placing it (not its value) 
  277. on the stack and sending the message purge.
  278.  
  279. To clarify, a variable's contents may be pushed onto the stack by 
  280. sending the name of the variable as a message.  You may think of 
  281. this as a message to CONTROL telling it to push the contents of 
  282. a variable onto the stack.  To place the variable itself on the 
  283. stack, it must be surrounded by single quotes.
  284.  
  285. For example,
  286.  
  287.     48 'simple' sto
  288.  
  289. this creates a variable called simple.  After this, the message
  290.  
  291.     simple
  292.  
  293. will push 48 onto the stack.  However the message
  294.  
  295. 'simple' will push the variable itself onto the stack.  Then, 
  296. sending the message
  297.  
  298.     rcl
  299.  
  300. will push 48 onto the stack.
  301.  
  302. The fragment
  303.  
  304.     33 'plok' sto plok 21 'plok' sto plok * 'plok' purge
  305.  
  306. will leave the value 693 on the stack.  Also, after this fragment is 
  307. executed, the variable 'plok' will not exist.
  308.  
  309. A user defined class in Quinta may have a number of member 
  310. variables.  Member variables operate as other variables, 
  311. generally.  For a given member variable within an object, to 
  312. retrieve its contents or push it onto the stack, the object in which 
  313. it resides must be on top of the stack.  After a sto into a member 
  314. variable, the newly modified object is left on the stack.  For 
  315. example, consider the class Window described above and 
  316. presuppose that an object of class Window is in variable 
  317. 'pocket'.  By sending the message:
  318. pocket
  319. a copy of the window object in 'pocket' will be pushed onto the 
  320. stack.  Then, by sending the message
  321.  
  322.     'x_cursor'
  323.  
  324. the x_cursor member variable of the window object will be 
  325. pushed onto the stack (the actual window object will not be on 
  326. the stack).  Now send the message
  327.  
  328.     78 sto
  329.  
  330. After this operation, the window object will again be on the 
  331. stack, including its new value for x_cursor.  The reason for this, 
  332. is that the contents of 'pocket' have not changed!  Remember, 
  333. whenever a variable contents are recalled to the stack, only a 
  334. copy of the contents are ever obtained.  To complete this 
  335. sequence, and store the resulting changes back into pocket, we 
  336. must do just that:
  337.  
  338.     'pocket' sto
  339.  
  340. Finally, observe that Quinta variables are untyped.
  341.  
  342. Local variables
  343.  
  344. A local variable is one which exists only for the lifetime of its 
  345. enclosing and defining response.  The variable may be 
  346. initialized at any time during a response definition, and is 
  347. destroyed upon exiting that response.  Statically allocated local 
  348. variables are not allowed.
  349.  
  350. The message local is of order 2.  In level one, a string containing 
  351. the name of the local variable.  And, in level two, the initial 
  352. contents of the local variable, which may be any object.
  353.  
  354.     [ "x" local x x * ] "sq" pub integer 1 >list respond
  355.  
  356. The above fragment of code is one way of implementing a 
  357. message to square the receiver.
  358.  
  359. Another way of doing the same thing would be:
  360.  
  361.     [ dup * ] "sq" pub integer 1 >list respond
  362.  
  363. The second example uses no local variables, and is probably 
  364. faster.  In general, local variables make Quinta code easier to 
  365. read, and less efficient.  Local variables may be created at any 
  366. time in a block of code but they always expect there to be at least 
  367. one object on the stack to initialize the variable.
  368.  
  369. Recursion is allowed, and local variables with the same name as 
  370. other local or global variables (or messages !) previously in 
  371. existence do not destroy the previous definition for that name.  
  372. Try examining the response to fact for class integer.  This is a 
  373. factorial function, actually defined in Quinta, and is recursive.  
  374. To do this,
  375.  
  376.     _fact_ responses print
  377.  
  378.  
  379.