home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / lisp / interpre / apteryx / tutor3.lsp < prev   
Lisp/Scheme  |  1993-12-09  |  8KB  |  236 lines

  1. ; Copyright 1993 Apteryx Lisp Ltd
  2.  
  3. ; Some list processing (use F4 to evaluate example expressions)
  4.  
  5. ; A list is an ordered sequence of elements. In Lisp it is represented 
  6. ; by writing an open bracket "(", the elements of the list in order
  7. ; separated by white space, and then a closing bracket ")".
  8. ; Examples -
  9.  
  10.     (1 2 3 4) ; A list of 4 numbers
  11.  
  12.     (jim fred tom harry trevor) ; A list of 5 names
  13.  
  14.     () ; An empty list (containing 0 members)
  15.  
  16.     ((a b c d e) (f g h) ()) ; A list with 3 members, all of which are
  17.                              ; themselves lists.
  18.  
  19. ; All Lisp programs are lists, but we can also treat lists as data to 
  20. ; be processed. Arguments to a Lisp function are normally evaluated 
  21. ; themselves before being passed to the function. To pass a list directly
  22. ; in without it being evaluated as an expression, we need some way to 
  23. ; prevent this evaluation. We do this by putting a quote character ' 
  24. ; before the list. For example, length is a function that returns the
  25. ; number of members of a list - 
  26.  
  27. (length '(jim tom fred))
  28.  
  29. ; If we leave the quote out, we get an error when the Lisp attempts to
  30. ; evaluate the expression (jim tom fred)
  31.  
  32. (length (jim tom fred))
  33.  
  34. ; The quote ' is actually an abbreviation for the special form "quote".
  35. ; For example '(jim tom fred) = (quote (jim tom fred))
  36. ; Note that the quote character abbreviates both the symbol quote and
  37. ; the brackets that enclose quote and its argument. quote is a special
  38. ; form which takes one argument which is not evaluated and returns that
  39. ; unevaluated argument as it's result. The sole purpose of quote is to
  40. ; prevent the evaluation of data that occurs by default (in particular
  41. ; for lists and non-keyword symbols - other Lisp objects are 
  42. ; self-evaluating, and quote is unnecessary when they are passed as 
  43. ; arguments).
  44.  
  45. (length (quote (jim tom fred)))
  46.  
  47. ; cons is a function that adds an element on to the beginning of a list.
  48.  
  49. (cons 4 '(5 6))
  50.  
  51. ; If we pass a non-list as the second argument we get a dotted pair as
  52. ; a result.
  53.  
  54. (cons 4 5)
  55.  
  56. ; A dotted pair is sometimes called a "cons" or "cons cell". It is stored
  57. ; in the computer as a simple pair of objects (or to be exact as pointers
  58. ; to a pair of objects). A list is in fact constructed using dotted pairs,
  59. ; for example (4 . (5 . (6 . ()))) means the same as (4 5 6). So the 
  60. ; effect of the function cons is to construct a new "cons" made up of
  61. ; pointers to the two arguments to cons. A list is a pair of objects, the
  62. ; first of which is the first element of the list and the second is
  63. ; the list consisting of all elements in the list other than the first
  64. ; element. These two elements are sometimes known as "first" and "rest"
  65. ; and sometimes as "head" and "tail". One exception is the empty list (),
  66. ; which not having a first element, has to be a special object in itself.
  67. ; In Lisp, the empty list is identified with the symbol nil.
  68.  
  69. ; In fact functions called first and rest exist which return the first
  70. ; and second elements respectively of a "cons".
  71.  
  72. (first '(3 4))
  73.  
  74. (rest '(a b c d e))
  75.  
  76. (rest '(3 . 4))
  77.  
  78. ; Alternative names for first and rest are car and cdr.
  79.  
  80. (car '(3 4))
  81.  
  82. (cdr '(a b c d e))
  83.  
  84. ; These are the "traditional" names for these functions (and somewhat
  85. ; obscure). If the name "cons" seems a bit obscure, it is an abbreviation
  86. ; for "constructor", referring to the construction of lists.
  87.  
  88. ; list is a function that makes any number of elements into a list
  89.  
  90. (list (+ 2 3) (+ 4 5))
  91.  
  92. ; append "glues" any number of lists together
  93.  
  94. (append '(a b c) '(d e) '(f g h i) '(j) '(k l m))
  95.  
  96. ; contrast the following -
  97.  
  98. (cons '(a b) '(c d))
  99. (list '(a b) '(c d))
  100. (append '(a b) '(c d))
  101.  
  102. ; member determines if an object belongs to a list.
  103.  
  104. (setq my-family '(dad mum jim tom deborah))
  105.  
  106. (member 'dad my-family)
  107.  
  108. (member 'harry my-family)
  109.  
  110. ; Note that when member returns a positive result it returns that
  111. ; portion of the list argument starting from the member found.
  112. ; Since this is always non-empty, it effectively means true.
  113.  
  114. (if (member 'harry my-family)
  115.   (print "harry is in my family")
  116.   (print "harry is not in my family") )
  117.  
  118. (if (member 'dad my-family)
  119.   (print "dad is in my family")
  120.   (print "dad is not in my family") )
  121.  
  122. ; find the nth element in a list (note that element 0 is the first element)
  123.  
  124. (nth 0 '(a b c d e f))
  125. (nth 1 '(a b c d e f))
  126. (nth 2 '(a b c d e f))
  127.  
  128. ; find the last element in a list 
  129.  
  130. (last '(1 2 3 4 5 6))
  131.  
  132. ; return a copy of a list with specified element removed
  133.  
  134. (remove 'jim '(fred jim tom jim harry jim harry))
  135.  
  136. ; return a copy of a list with elements in reverse order
  137.  
  138. (reverse '(this is my life))
  139.  
  140. ; note that it reverses just the elements of the list, and doesn't 
  141. ; reverse any elements which may be lists
  142.  
  143. (reverse '((this is) (my life)))
  144.  
  145. ; We could write a function that does a "deep" reverse
  146.  
  147. (defun deep-reverse (x)
  148.   (if (consp x)
  149.     (reverse (mapcar #'deep-reverse x))
  150.     x) )
  151.  
  152. (deep-reverse '((this is) (my life) (this is (your life))))
  153.  
  154. ; consp is a function that returns t (= true) for a non-empty list or any
  155. ; other "dotted" pair, and false for anything else. The function definition
  156. ; more or less says - for a non-empty list, first apply deep-reverse
  157. ; to each element, and then return the list of results reversed, for
  158. ; any other object return it unchanged.
  159.  
  160. (deep-reverse '((a . b) (c d)))
  161.  
  162. ; The above function won't produce a very satisfactory result for
  163. ; objects that contain dotted pairs that aren't true lists, because
  164. ; neither mapcar nor reverse like such "improper" lists. To fix this
  165. ; we can use true-listp instead of consp, which only returns t for a 
  166. ; for a "true" list (including the empty list).
  167.  
  168. (defun deep-reverse (x)
  169.   (if (true-listp x)
  170.     (reverse (mapcar #'deep-reverse x))
  171.     x) )
  172.  
  173. (deep-reverse '((a . b) (c d)))
  174.  
  175. ; some pre-defined functions do operate "deeply", i.e. they go into 
  176. ; nested lists.
  177.  
  178. ; For example subst and sublis do substitutions.
  179.  
  180. (subst 'tom 'jim '(jim fred harry (jim (jim tom) (fred jim (jim)))))
  181.  
  182. (sublis '( (tom . tomasina) (fred . frederica) (jim . jane) (harry . harrieta))
  183.   '(jim fred harry (jim (jim tom) (fred jim (jim)))) )
  184.  
  185. ; note that for sublis the first argument is a list of dotted pairs. Such
  186. ; a list is called an association list or assoc list or alist. Each pair
  187. ; is an association of the first element with the second.
  188.  
  189. (setq male-to-female-alist 
  190.   '((tom . tomasina) (fred . frederica) (jim . jane) (harry . harrieta)) )
  191.  
  192. ; assoc the first pair (if any) of an alist whose first element is eql
  193. ; to the first argument.
  194.  
  195. (cdr (assoc 'fred male-to-female-alist))
  196.  
  197. ; You can think of an alist as a simple sort of lookup table.
  198.  
  199. (setq phone-list
  200.   '((tom . 4906589) (jim . 2139087)) )
  201.  
  202. (assoc 'tom phone-list)
  203.  
  204. (assoc 'fred phone-list)    ; This returns nil because no entry is found
  205.  
  206. ; some of the above list functions have "destructive" equivalents, i.e.
  207. ; they are functions that build as much as possible of their result from
  208. ; the input arguments, even if this means altering the input arguments
  209.  
  210. (delete 'jim '(tom jim harry))
  211. (remove 'jim '(tom jim harry))
  212.  
  213. ; the above two seem to give the same result, but lets see what each
  214. ; does to its input argument
  215.  
  216. (let ( (fellas '(tom jim harry)) ) 
  217.   (remove 'jim fellas)              
  218.   fellas)  ; remove leaves its input argument untouched
  219.  
  220. (let ( (fellas '(tom jim harry)) )
  221.   (delete 'jim fellas)
  222.   fellas)  ; delete cuts the element to be deleted out of the input list
  223.  
  224. (let ( (fellas '(jim tom jim harry)) )
  225.   (delete 'jim fellas)
  226.   fellas)  ; note here that the first jim isn't deleted from fellas,
  227.            ; this is because it can be deleted simply by returning the
  228.            ; cdr of the trimmed list
  229.  
  230.  
  231. ; nconc is the destructive equivalent of append - it "destroys" all 
  232. ; input arguments except the last one.
  233.  
  234. (nconc '(tom harry) '(dick))
  235.  
  236.