home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sa104os2.zip / SATHR104.ZIP / SATHER / CONTRIB / LISP / DOC.TXT < prev    next >
Text File  |  1994-10-25  |  16KB  |  477 lines

  1. Sather Lisp
  2.  
  3. Robert Griesemer
  4. International Computer Science Institute, Berkeley
  5. gri@icsi.berkeley.edu
  6.  
  7. August 17, 1994
  8.  
  9.  
  10. 1. Introduction
  11.  
  12. Sather Lisp is a primitive Lisp interpreter completely written in Sather 1.0.
  13. Currently no local function definitions are possible, and therefore no higher
  14. order functions can be defined directly (i.e., local lambda's do not work
  15. correctly). However, arbitrary long integers and rational numbers are fully
  16. supported.
  17.   Sather Lisp serves as an example for a non_trivial but still comprehensible
  18. Sather 1.0 application. Its simplicity lead to a small and straightforward
  19. implementation (less than 1000 lines of code, including comments and empty
  20. lines), but the interpreter is still powerful enough to give valuable insights
  21. into the principles of list processing. It can either be used to learn Sather
  22. by studying a concrete application, or to get a glance of list processing by
  23. studying the implementation details.
  24.   This documentation is only a brief description of the interpreter
  25. functionality (its user interface) and is not intended as a Lisp tutorial. The
  26. reader is referred to the standard literature for a more thourough introduction 
  27. into the topic (e.g., P.H. Winston and B.K.P. Horn (1984), Lisp, 2nd edition,
  28. Addison_Wesley).
  29.  
  30.  
  31. 2. Usage
  32.  
  33. The Sather Lisp implementation consists of the file Lisp.sa and the necessary
  34. Sather library files. After compilation with:
  35.  
  36. cs Lisp.sa -main LISP -o Lisp <CR>
  37.  
  38. (assuming SATHER_COMMANDS set correctly), the Lisp interpreter can be started:
  39.  
  40. Lisp <CR>
  41. Sather Lisp - gri 15 Aug 94
  42. (symbols) returns a list of all defined symbols
  43.  
  44. The '>' prompt signals that the interpreter is ready for input. The
  45. interpreter accepts any sequence of Lisp expressions as input and evaluates
  46. them consecutively. The output is the result of the last evaluated expression
  47. (unless an error occured before). The program can be left by typing in Ctrl_D
  48. (indicating end of file) or by using the predefined function exit:
  49.  
  50. > (exit) <CR>
  51.  
  52.  
  53. 3. Expression syntax
  54.  
  55. The Sather Lisp syntax is described using an Extended Backus_Naur Formalism
  56. (EBNF): brackets [ and ] denote optionality of the enclosed sentential form,
  57. braces { and } denote its repetition (possibly zero times). Alternative forms
  58. are separated by vertical bars |. Syntactic entities (non_terminal symbols) are 
  59. denoted by English words starting with a capital letter (the only one is
  60. Expression). Tokens of the language vocabulary (terminal symbols) are either
  61. denoted by English words starting with a small letter (e.g., number), or are
  62. denoted by strings enclosed in double quotes (e.g., "."). No white space may
  63. appear within tokens. However, arbitrary white space and comments may appear
  64. between tokens. Comments are denoted by the curly braces { and } and may be
  65. nested.
  66.  
  67. Expression  =  "'" Expression |
  68.     "(" {Expression} ["." Expression] ")" |
  69.     symbol | number | string.
  70.  
  71. symbol  =  letter {letter | digit} |
  72.     special {special}.
  73. number  =  ["-"] digit {digit} ["/" digit {digit}].
  74. string  =  """ char """.
  75.  
  76. letter  =  "A" | "B" ... "Z" | "a" | "b" ... "z".
  77. digit  =  "0" | "1" ... "9".
  78. special  =  "!" | "#" | "$" | "%" | "&" | "*" | "+" | "-" | "/" | ":" |
  79.     "<" | "=" | ">" | "?" | "@" | "\\" | "^" | "|" | "~".
  80. char  =  any printable character except "
  81.  
  82. Examples:
  83.  
  84. -1234  (negative) integer
  85. 7/31  (positive) rational number
  86. "This is a string"  string
  87. ()  empty list, nil
  88. myFunc  symbol
  89. <=  (special) symbol
  90. 'a  quoted symbol
  91. (a (b 3/4 c) d)  list consisting of 3 elements
  92. (a . b)  dotted pair
  93. (a b c (u v w) x . d)  list terminated with dotted pair
  94. (a . (b . (c . ()))) = (a b c)  equivalence of dotted pair and list notation
  95.  
  96. Note: The negative sign of a number must be immediately before the first digit 
  97. and must not be preceeded by another special character, otherwise it is
  98. interpreted as (special) symbol. 'x is a shortcut for (quote x) (unless quote
  99. has been redefined).
  100.  
  101.  
  102. 4. Expression evaluation
  103.  
  104. Sather Lisp evaluates a list by first evaluating its first element (which must 
  105. evaluate to a function) and then applying the function to the remaining list.
  106. Whether the arguments are evaluated or not depends on the function; e.g., quote 
  107. (') never evaluates its (single) argument, but setq evaluates only its second
  108. argument, and + evaluates all its arguments, etc. Symbols evaluate to their
  109. bound values, which may be assigned using set or setq. Initially, they evaluate 
  110. to nil. Numbers, strings and functions evaluate to themselves. Truth values are 
  111. denoted by the empty list (i.e., nil) and non_nil values. The empty list (nil)
  112. stands for "false", and any non_nil value stands for "true". Usually the
  113. predefined symbols nil and t (which evaluate to the empty list () and t,
  114. respectively) are used to represent "false" and "true". In order to avoid
  115. confusion, they shouldn't be redefined. If they are, (setq nil ()) and (setq t
  116. 't) re_establishes their default values.
  117.  
  118. Examples:
  119.  
  120. 1234  ^  1234
  121. "hello world"  ^  "hello world"
  122. (+ 1 2 3 4 5 6 7 8 9 10)  ^  55
  123. '(a . b)  ^  (a . b)
  124. car  ^  [car]  ([...] denotes functions)
  125. (cons 'a 'b)  ^  (a . b)
  126. (car (cons 'a 'b))  ^  a
  127. (cdr (cons 'a 'b))  ^  b
  128. (cdr '(a b))  ^  (b)
  129. (setq a 4/6)  ^  2/3
  130. a  ^  2/3
  131. (lambda (x) (+ x 1))  ^  [((+ #0 1))]  (#i denotes argument no. i)
  132. ((lambda (x) (+ x 1)) 1)  ^  2
  133. (setq inc (lambda (x) (+ x 1)))  ^  [inc]
  134. (inc 1)  ^  2
  135.  
  136.  
  137. 5. Predefined functions
  138.  
  139. Several functions are predefined in Sather Lisp. Since predefined functions
  140. are bound to ordinary symbols, (the values of) these symbols may be redefined
  141. if desired (and the old function is lost unless it is bound to another symbol,
  142. too). User defined functions may be added (or redefined, resp.) by binding
  143. lambda expressions to symbols (see Section 6). A list of all symbols known to
  144. the system is obtained using (symbols). The following table gives a brief
  145. definition of all predefined functions.
  146.  
  147. Expression  Result  Constraints
  148.  
  149.  
  150. (+ arg0 arg1 [... argn])  (arg0 + arg1) + ... + argn  (numbers only)
  151. (- arg0 arg1 [... argn])  (arg0 - arg1) - ... - argn  (numbers only)
  152. (* arg0 arg1 [... argn])  (arg0 * arg1) * ... * argn  (numbers only)
  153. (/ arg0 arg1 [... argn])  (arg0 / arg1) / ... / argn  (numbers only)
  154. (% arg0 arg1 [... argn])  (arg0 % arg1) % ... % argn  (numbers only)
  155. (^ arg0 arg1 [... argn])  (arg0 ^ arg1) ^ ... ^ argn  (numbers only)
  156.  
  157. (= arg0 arg1 [... argn])  arg0 = arg1 = ... = argn  (numbers and strings only)
  158. (# arg0 arg1 [... argn])  arg0 # arg1 # ... # argn  (numbers and strings only)
  159. (< arg0 arg1 [... argn])  arg0 < arg1 < ... < argn  (numbers and strings only)
  160. (<= arg0 arg1 [... argn])  arg0 <= arg1 <= ... <= argn  (numbers and strings
  161. only)
  162. (> arg0 arg1 [... argn])  arg0 > arg1 > ... > argn  (numbers and strings only)
  163. (>= arg0 arg1 [... argn])  arg0 >= arg1 >= ... >= argn  (numbers and strings
  164. only)
  165.  
  166. (! arg)  factorial of floor(arg)  (numbers only)
  167. (floor arg)  floor of arg  (numbers only)
  168. (ceiling arg)  ceiling of arg  (numbers only)
  169.  
  170. (car arg)  head of arg  (arg must be a list)
  171. (cdr arg)  tail of arg  (arg must be a list)
  172. (cons arg0 arg1)  (arg0 . arg1)
  173. (atom arg)  t if arg is not a pair, () otherwise
  174. (eq arg0 arg1)  arg0 = arg1  
  175.  
  176. 'arg  shortcut for (quote arg)
  177. (quote arg)  returns arg without evaluation
  178. (eval arg)  evaluates the value of arg
  179.  
  180. (set sym arg)  binds the value of arg to the symbol sym
  181. (setq arg0 arg1)  binds the value of arg1 to the symbol value of arg1
  182.  
  183. (write arg)  writes arg to stdout and returns arg
  184. (writeLn)  starts a new line to stdout and returns ()
  185.  
  186. (lambda ...)  see Section 6
  187. (cond arg0 [arg1 ... argn])  each argument is considered to be a list consisting 
  188. of
  189.   a condition (which evaluates to nil or non_nil) and
  190.   a sequence of expressions. cond evaluates the first
  191.   sequence of expressions for which its condition is
  192.   evaluated to a non_nil value. The result of cond
  193.   is the last expression evaluated (see examples).
  194.  
  195. (readFile arg)  reads and evaluates file arg  (arg must be a string)
  196. (tracer arg)  arg = on: turns tracing output on and returns on
  197.   arg # on: turns tracing output off and returns off
  198. (tracer)  actual tracing mode (on or off)
  199. (symbols)  returns list of all known symbols
  200. (exit)  exits the interpreter
  201.  
  202. Note: Use = for comparison of numbers and strings; eq does only a pointer
  203. comparison, thus (eq 1 1) # t!
  204.  
  205.  
  206. 6. Function definition
  207.  
  208. New functions can be created using the lambda function. lambda expects a
  209. parameter list and a sequence of expressions. Three syntactic variants exist:
  210.  
  211. a) (lambda x expr0 expr1 ... exprm)
  212. b) (lambda (par0 par1 .. parn-1) expr0 expr1 ... exprm)
  213. c) (lambda (par0 par1 .. parn-1 . x) expr0 expr1 ... exprm)
  214.  
  215. a) This corresponds to case c) with n = 0.
  216. b) The function expects n parameters which are hold in par0 to parn-1. The
  217. result of a function invocation is the value of the last expression exprm
  218. evaluted using the parameter values (i.e., the parameters are evaluated before
  219. the expri's are evaluated). Symbols that are not parameters are considered to
  220. be global.
  221. c) The function expects at least n parameters. The values of the first n
  222. parameters are hold in par0 to parn-1 (i.e., these parameters are evaluated
  223. before the expri's are evaluated), the remaining parameter list is hold in x
  224. (i.e., the last parameter is not evaluated prior to evaluation of the expri's).
  225.  
  226. Variant a) and c) can be used to implement functions that accept variable long
  227. argument lists or functions that do only partially evaluate their arguments.
  228. For instance, quote could be defined by (setq quote (lambda x (car x))). The
  229. ReadFiles function definition in the example section below is another
  230. application of this feature. Furthermore, variant a) and c) can also be
  231. (mis_)used to implement functions with one local variable x. If more than one
  232. local variable are required, an auxiliary function must be called that
  233. specifies local variables as additional arguments which are not used (but
  234. initialized) by the call.
  235.  
  236. Note: A function which is used several times should be bound to a symbol (for
  237. efficiency reasons). This is especially important when using recursion.
  238.  
  239. Implementation restriction: Currently, local lambda definitions (lambdas within 
  240. lambdas) do not work correctly. Furthermore, quoting arguments within lambdas
  241. is erroneous. Both these problems are related and due to the simplified
  242. implementation. Solving these problems correctly requires a redesign of the
  243. function evaluation mechanism.
  244.  
  245. Examples:
  246.  
  247. (lambda (x) (add x 1))  defines an increment function
  248. (setq inc (lambda (x) (add x 1)))  the value of inc is the increment function
  249. (inc 1)  inc applied to 1 returns the value 2
  250.  
  251. (setq sum  defines a function sum which recursively
  252.    (lambda (n)  calculates the sum of the first n integers
  253.       (cond
  254.          ((< 0 n) (+ n (sum (- n 1))))  
  255.          (t 0)
  256.       )
  257.    )
  258. )
  259.  
  260. (sum 100)  5050
  261.  
  262. (setq list (lambda x x))  returns its arguments as a list without evaluation
  263. (list a b c)  (a b c)
  264.  
  265. (setq readFiles  extend the readFile function to arbitrary many
  266.    (lambda x  arguments
  267.       (cond
  268.          ((atom x))
  269.          (t (readFile (car x)) (eval (cons 'readFiles (cdr x))))
  270.       )
  271.    )
  272. )
  273.  
  274.  
  275. 7. Error recovery
  276.  
  277. Currently, after a parse_ or run_time, the interpreter only prints out a short 
  278. error message and returns to the read_eval_write loop. If the error hapens
  279. during file input (i.e., during the evaluation of a (readFile arg) expression,
  280. also the file name (arg) is displayed. However, the Lisp tracing facility can
  281. be used to simplify the location of bugs. The function tracer is turned on by
  282. evaluating (tracer on), and turned off by evaluating (tracer off). When on, the 
  283. interpreter prints out the every (predefined and user_defined) function call
  284. together with its arguments and the return value. The following shows the trace 
  285. of the expression (sum 3) (sum is defined in Section 8):
  286.  
  287. > (tracer on)
  288. on
  289. > (sum 3)
  290. [sum] called with (3)
  291.    [cond] called with (((<= #0 0) 0) (t (+ #0 (sum (- #0 1)))))
  292.       [<=] called with (#0 0)
  293.       [<=] returns nil
  294.       [+] called with (#0 (sum (- #0 1)))
  295.          [sum] called with ((- #0 1))
  296.             [-] called with (#0 1)
  297.             [-] returns 2
  298.             [cond] called with (((<= #0 0) 0) (t (+ #0 (sum (- #0 1)))))
  299.                [<=] called with (#0 0)
  300.                [<=] returns nil
  301.                [+] called with (#0 (sum (- #0 1)))
  302.                   [sum] called with ((- #0 1))
  303.                      [-] called with (#0 1)
  304.                      [-] returns 1
  305.                      [cond] called with (((<= #0 0) 0) (t (+ #0 (sum (- #0
  306. 1)))))
  307.                         [<=] called with (#0 0)
  308.                         [<=] returns nil
  309.                         [+] called with (#0 (sum (- #0 1)))
  310.                            [sum] called with ((- #0 1))
  311.                               [-] called with (#0 1)
  312.                               [-] returns 0
  313.                               [cond] called with (((<= #0 0) 0) (t (+ #0 (sum
  314. (- #0 1)))))
  315.                                  [<=] called with (#0 0)
  316.                                  [<=] returns t
  317.                               [cond] returns 0
  318.                            [sum] returns 0
  319.                         [+] returns 1
  320.                      [cond] returns 1
  321.                   [sum] returns 1
  322.                [+] returns 3
  323.             [cond] returns 3
  324.          [sum] returns 3
  325.       [+] returns 6
  326.    [cond] returns 6
  327. [sum] returns 6
  328. 6
  329.  
  330. Function names (i.e., the symbols to which the functions are bound to) are
  331. shown in brackets []. If there is no name for a particular function (i.e., in
  332. case of a anonymous lambda expression), the function definition is printed out
  333. instead. Parameters are denoted by #i, starting with i = 0 for the first
  334. parameter of a lambda expression. If the same function sum is called with a
  335. wrong argument, e.g., a string, the run_time error can be located easily:
  336.  
  337. > (sum "illegal argument")
  338. [sum] called with ("illegal argument")
  339.    [cond] called with (((<= #0 0) 0) (t (+ #0 (sum (- #0 1)))))
  340.       [<=] called with (#0 0)
  341. error in [sum]: 0 is not a string
  342.  
  343. Obviously, the error occured in the user_defined function sum (error messages
  344. refer to user_defined function names only). Within sum, the last function
  345. called was [<=] with the arguments #0 and 0. Since #0 refers to the string
  346. "illegal argument", the expression to be evaluated is (<= "illegal argument" 0) 
  347. which results in a run_time error, since [<=] requires all arguments to be
  348. either numbers or strings.
  349.  
  350.  
  351. 8. A few more examples
  352.  
  353. { Sum of the first n integers }
  354.  
  355. (setq sum
  356.    (lambda (n)
  357.       (cond
  358.          ((<= n 0) 0)
  359.          (t (+ n (sum (- n 1))))
  360.       )
  361.    )
  362. )
  363.  
  364. { Examples }
  365.  
  366. (sum 0)
  367. (sum 10)
  368. (sum 100)
  369. (sum 1000)
  370. (sum 0)
  371.  
  372.  
  373. { Factorial using Peano Axioms }
  374.  
  375. (setq s
  376.    (lambda (x)
  377.       (cons 's (cons x nil))))
  378.       
  379. (setq p
  380.    (lambda (x)
  381.       (car (cdr x))))
  382.       
  383. (setq myAdd
  384.    (lambda (x y)
  385.       (cond
  386.          ((atom x) y)
  387.          (t (s (myAdd (p x) y))))))
  388.          
  389. (setq myMul
  390.    (lambda (x y)
  391.       (cond
  392.          ((atom x) 0)
  393.          (t (myAdd (myMul (p x) y) y)))))
  394.          
  395. (setq gen
  396.    (lambda (n)
  397.       (cond
  398.          ((<= n 0) 0)
  399.          (t (s (gen (- n 1)))))))
  400.          
  401. (setq fact
  402.    (lambda (x)
  403.       (cond
  404.          ((atom x) (s 0))
  405.          (t (myMul x (fact (p x)))))))
  406.  
  407. { Examples (gen is used to create Peano Integers) }
  408.  
  409. (gen 0)
  410. (gen 2)
  411. (gen 10)
  412. (gen 100)
  413.  
  414. (p (gen 3))
  415.  
  416. { Peano addition }
  417.  
  418. (myAdd (gen 3) (gen 4))
  419. (myAdd (gen 0) (gen 2))
  420.  
  421. { Peano multiplication }
  422.  
  423. (myMul (gen 2) (gen 3))
  424.  
  425. { Peano factorial }
  426.  
  427. (fact (gen 0))
  428. (fact (gen 2))
  429. (fact (gen 4))
  430. (fact (gen 5))
  431. (fact (gen 6))
  432.  
  433.  
  434. { Towers of Hanoi }
  435.  
  436. (setq print
  437.    (lambda (x)
  438.       (write x) (writeLn)))
  439.  
  440. (setq move
  441.    (lambda (from to)
  442.       (print (cons from (cons to ())))))
  443.  
  444.  
  445. (setq hanoi
  446.    (lambda (from over to n)
  447.       (cond
  448.          ((> n 0)
  449.             (hanoi from to over (- n 1))
  450.             (move from to)
  451.             (hanoi over from to (- n 1))
  452.          ))))
  453.  
  454. { Example }
  455.  
  456. (hanoi 'a 'b 'c 5)
  457.  
  458.  
  459. { Ackerman function }
  460.  
  461. (setq A
  462.    (lambda (x y)
  463.       (cond
  464.          ((= x 0) (+ y 1))
  465.          ((= y 0) (A (- x 1) 1))
  466.          (t (A (- x 1) (A x (- y 1))))
  467.       )
  468.    )
  469. )
  470.  
  471. { Examples }
  472.  
  473. (A 3 2)
  474. (A 3 3)