List and text utilities Isis software documentation

List and text utilities

This document explains the various list manipulation utilities available in Isis. Since strings are represented as lists of characters in Isis, all of these routines may be used on strings and text in an analogous way.


Creating and retrieving items from lists

To create a new list, use the Isis list formation construct (simply place the expressions inside of square brackets [ ]):
[ exp exp ... ]
To retrieve a particular item from a list, use the Isis list reference construct:
( list index )
Read the Isis primer for more information. Here are a few examples:
-> (set r [ 1 2 3 ]) [ 1 2 3 ] -> (r 0) 1 -> (r 3) * Index 3 out of range. Null -> (set s [['x' 7] ['q' 100] [42.0 "obsequious"]] ) [ [ 'x' 7 ] [ 'q' 100 ] [ 42.0 "obsequious" ] ] -> ((s 2) 1) "obsequious"


Basic operators

(length list) # number of items in list (head list) # first item in list, equivalent to (list 0) (tail list) # last item in list, equivalent to (list (- (length list) 1)) If the given list is empty, head and tail will return Null.
-> (set alist [ 3 4 5 6 ]) [ 3 4 5 6 ] -> (length alist) 4 -> (head alist) 3 -> (tail alist) 6 -> (set blist "Corporal Clegg") "Corporal Clegg" -> (length blist) 14 -> (tail blist) 'g'


Inserting and appending

(insert-before k val list) # insert val before item k in list (insert-after k val list) # insert val after item k in list (head-insert val list) # insert val at beginning of list (tail-insert val list) # insert val at end of list (append list1 list2 ...) # append lists together into one big list In these routines, k should be an integer list index, indicating where to insert the new item in the list. If k is negative, the value will be inserted at the beginning of the list, and if k is greater than the length of the list, the item will be inserted at the end of the list.
-> (set x [0 1 2 3]) [ 0 1 2 3 ] -> (insert-before 1 42 x) [ 0 42 1 2 3 ] -> (insert-after 2 42 x) [ 0 1 2 42 3 ] -> (head-insert 42 x) [ 42 0 1 2 3 ] -> (tail-insert 42 x) [ 0 1 2 3 42 ]
append accepts any number of lists and concatenates them together to form one big list.
-> (append [1 2 3] [4 5 6] [7 8 9]) [ 1 2 3 4 5 6 7 8 9 ] -> (append "gold" "finger") "goldfinger"


Sublist operators

(sublist n m list) # return section of list between index m and n, inclusive (first k list) # return the first k items in list (last k list) # return the last k items in the list (allbutfirst k list) # return all but the first k items in the list (allbutlast k list) # return all but the last k items in the list In these routines, n, m, and k should be integer list indices, which will be clamped between 0 and the size of the list before the operation is performed.
-> (set x [0 1 2 3 4 5 6 7 8 9]) [ 0 1 2 3 4 5 6 7 8 9 ] -> (sublist 3 8 x) [ 3 4 5 6 7 8 ] -> (first 3 x) [ 0 1 2 ] -> (last 4 x) [ 6 7 8 9 ] -> (allbutfirst 1 x) [ 1 2 3 4 5 6 7 8 9 ] -> (allbutlast 1 x) [ 0 1 2 3 4 5 6 7 8 ]


Changing and removing items

(change-item index val list) # change specified index to val in list (remove-item index list) # remove specified index from list (change-items indexlist vallist list) # change specified indices in list (remove-items indexlist list) # remove specified indices in list In these routines, index should be an integer list index, and indexlist should be a list of indices. change-items changes the specified indices in indexlist to the corresponding values in vallist. If any indices are out of range, an error message is printed, and the list is not affected.
-> (set x [ 5 4 3 2 1 ]) [ 5 4 3 2 1 ] -> (set x (change-item 3 42 x)) [ 5 4 3 42 1 ] -> (set x (change-item 5 1000 x)) [ 5 4 3 42 1 1000 ] -> (set x (remove-item 4 x)) [ 5 4 3 42 1000 ] -> (change-item 5 '!' "horse.") "horse!" -> (remove-item 1 "bleach!") "beach!" -> (change-items [0 3 6] "Wda" "Vile Message") "Wild Massage"


Lists and procedures

(apply procedure arglist) # apply procedure to a list of arguments (map procedure arg1list arg2list ...) # apply procedure to corresponding elements in lists apply applies a procedure to the arguments given in a list.
-> (+ 1 2 3) 6 -> (apply + [1 2 3]) 6
map is a powerful operator that applies a procedure to corresponding items in any number of argument lists, and returns a list of the results. The number of arguments the procedure accepts must match the number of argument lists passed.
-> (map (proc (x) (+ 3 x)) [ 1 2 3 4 5 ]) [ 4 5 6 7 8 ] -> (map pow [ 2 3 4 5 6 ] [ 6 5 4 3 2 ]) [ 64.0 243.0 256.0 125.0 36.0 ]


Sorting and reordering

(sort sortproc list) # sort list using sortproc as the predicate (foremost sortproc list) # find foremost item in list using sortproc as the predicate (hindmost sortproc list) # find hindmost item in list using sortproc as the predicate (reorder indexlist list) # reorder list in the order specified in indexlist sort sorts a list using the given procedure to determine how it's ordered. foremost and hindmost are similar to sort, but instead of sorting the entire list, they just return the index of the item that would be first or last if the list was sorted. reorder rearrages the items in a list in the order specified by the given list of indices, which does not have to be the same length as the list.
-> (set alist [9 3 5 1 2 8 6 7 0 4]) [ 9 3 5 1 2 8 6 7 0 4 ] -> (sort > alist) [ 9 8 7 6 5 4 3 2 1 0 ] -> (sort < alist) [ 0 1 2 3 4 5 6 7 8 9 ] -> (foremost < alist) 8 -> (hindmost < alist) 0 -> (reorder [3 1 2 7 0] alist) [ 1 3 5 7 9 ]


Other basic utilities

(reverse list) # reverse the order of the items in a list (make-list len val) # make a new list filled with val (make-series start len increment) # make a new list with a mathematical series (assoc key list) # search a list of lists for a particular head item reverse reverses the order of a list, and make-list forms a new list of a certain length filled with a single value.
-> (reverse [1 2 3 4 5]) [ 5 4 3 2 1 ] -> (reverse "redrum") "murder" -> (make-list 10 42) [ 42 42 42 42 42 42 42 42 42 42 ] -> (make-list 5 Null) [ Null Null Null Null Null ] -> (make-list 42 'a') "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
make-series creates a list that starts with start, contains len number of items, where each sucessive item is increment greater than the last.
-> (make-series 0 10 1) [ 0 1 2 3 4 5 6 7 8 9 ] -> (make-series 1 5 10) [ 1 11 21 31 41 ] -> (make-series 0 10 -3) [ 0 -3 -6 -9 -12 -15 -18 -21 -24 -27 ] -> (make-series 'A' 26 1) "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
assoc searches a list of lists for a particular item. If the given key matches the first item of one of the lists, the entire matching list is returned. Otherwise, Null is returned. As such, assoc can be useful in searching a database that takes the form of a list of lists.
-> (set database [ ["stefan" "E15-348"] ["jacky" "E15-351"] ["wad" "E15-355"] ]) [ [ "stefan" "E15-348" ] [ "jacky" "E15-351" ] [ "wad" "E15-355" ] ] -> (assoc "stefan" database) [ "stefan" "E15-348" ] -> (assoc "wad" database) [ "wad" "E15-355" ] -> (assoc "prince" database) Null


Character case conversion

(toupper charval) # case convert characters (tolower charval) (upcase anyval) # case convert any value (downcase anyval) toupper and tolower will convert characters to upper or lower case. upcase and downcase will convert characters, strings, or characters contained anywhere in a list to upper or lower case. Anything other than characters is left unchanged.
-> (toupper 'a') 'A' -> (tolower 'M') 'm' -> (toupper 'R') 'R' -> (toupper 45) 45 -> (upcase "louder") "LOUDER" -> (downcase "SOFTER") "softer" -> (upcase [ "brazil" "uganda" "chile" ]) [ "BRAZIL" "UGANDA" "CHILE" ] -> (upcase [ 3 2 1 "ignition" ]) [ 3 2 1 "IGNITION" ]


Character constants

alert # '\a' backspace # '\b' formfeed # '\f' newline # '\n' return # '\r' tab # '\t' vtab # '\v' squote # '\'' dquote # '\"' backslash # '\\' These pre-defined character constants are often more intuitive than using the backslash escape-character form of the character.
-> (print "Stefan" tab tab "E15-348" tab tab dquote "agent 42" dquote newline) Stefan E15-348 "agent 42"


Search, remove, and replace

(search val list) # search list for val, return index or Null (remove val list) # remove first occurrence val (replace oldval newval list) # replace first occurrence oldval with newval (search-all val list) # return list of indices (remove-all val list) # remove all occurrences of val (replace-all oldval newval list) # replace all occurrences of oldval with newval (search-list l1 l2) # search for l1 embedded in l2, return index or Null (search-string s1 s2) # identical to search-list (remove-list l1 l2) # remove all occurrences of embedded list in l2 (remove-string s1 s2) # identical to remove-list (replace-list oldl newl l2) # replace all occurrences of embedded list in l2 (replace-string olds news s2) # identical to replace-list search looks for the first occurrence of a value in a list and returns the index of the item or Null if not found. remove removes the first occurrence of a value from a list and returns the modified list. replace replaces the first occurrence of a value in a list and returns the modified list.

search-all looks for all occurrences of a value in a list and returns a list of indices. remove-all removes all occurrences of a value from a list and returns the modified list. replace-all replaces all occurrences of a value and returns the modified list.

search-list looks for a list l1 embedded in another list l2 and returns the starting index of the first occurrence or Null if not found. Since strings are just lists of characters, search-string points to the same function as search-list and has the same effect.

remove-list and remove-string also point to the same function, as do replace-list and replace-string. The former function removes all occurrences of a list l1 embedded in another list l2 and return the modified list. The latter replaces all occurrences of an embedded list with a new list and returns the modified list.

-> (search 42 [ 40 75 42 64 42 42 30 ]) 2 -> (remove 42 [ 40 75 42 64 42 42 30 ]) [ 40 75 64 42 42 30 ] -> (remove-all 42 [ 40 75 42 64 42 42 30 ]) [ 40 75 64 30 ] -> (replace-all 42 "zap" [ 40 75 42 64 42 42 30 ]) [ 40 75 "zap" 64 "zap" "zap" 30 ] -> (search 'a' "manual labor") 1 -> (search-all 'a' "manual labor") [ 1 4 8 ] -> (search-all 'e' "manual labor") [] -> (replace-all 'e' 'a' "bed gremmer") "bad grammar" -> (remove-all 'q' "qsqeqcqrqeqtq qmqeqsqsqaqgqeq") "secret message" -> (search-list [42 42] [ 40 75 42 64 42 42 30 ]) 4 -> (search-string "brown" "the big brown bear") 8 -> (search-string "shaft" "the big brown bear") Null -> (replace-string "bear" "beaver" "the big brown bear") "the big brown beaver" -> (remove-string "brown" "the big brown bear") "the big bear"


Miscellaneous utilities

(string-to-word-list str) # convert text into a list of words (string-to-line-list linelen str) # break text into list of lines (fill-text fillcol str) # fill text into lines of a max length

string-to-word-list separates a string to a list of words with no spaces.

-> (string-to-word-list "Bob Jones was very sure of the color.") [ "Bob" "Jones" "was" "very" "sure" "of" "the" "color." ] -> (string-to-word-list "Yes, I am!") [ "Yes," "I" "am!" ]
string-to-line-list separates a string to a list of lines, where each line is of a length less than maxlinelength. The only exception is if there is a word in the string which is itself longer than maxlinelength; in this case the word is given its own line and is not truncated. Any existing newline characters are NOT given special treatment and do not force a line break.
-> (string-to-line-list 20 "Bob, please do not speak out of turn.") [ "Bob, please do not" "speak out of turn." ] -> (string-to-line-list 5 "But I was only trying to be a good boy.") [ "But I" "was" "only" "trying" "to be" "a" "good" "boy." ]
fill-text fills a piece of text, adding newline characters to keep lines at a maximum length. If a word is too long for the line, it is not broken. It leaves any newlines already in the text untouched.
-> (fill-text 20 "this is a test of the emergency broadcast system.") "this is a test of the emergency broadcast system." -> (fill-text 10 "this is a test of the emergency broadcast system.") "this is a test of the emergency broadcast system."


Requirements:
Scripts: (load "list-utilities.isis")


Thanks to Christian Baekkelund and Jon Dakss for their contributions to this library.