misc-utils is a general purpose function library containing functions for destructive and non-destructive list modification, alternate mapping methods, and various other stuff. Copyright (c) 2016, 2017, 2022 Tim Chadburn. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the file "fdl.txt" which is part of this package. Once misc-utils.ss is properly installed in your Scheme implementation's library directory, you can access this library by adding (hamster misc-utils) to your import list. Due to the differences between R5RS and R6RS it has been impossible to avoid making some changes to the API since version 0.1. See the ChangeLog for details. Contents -------- 1. Destructive list modification: insert!, delete-item!, delf! , insert-at-end!, replace-pos! and replace!. 2. Non-destructive list modification: muremove, remove-some, remove-list, remove-pos, occur, list-head, and chop 3. Mapping: filter-map, first-true, first-true-pos, apply-for-each, append-map, all-true and count. 4. Procedure modification: specify and modify-return. 5. Miscellaneous: improper, proper, optarg, nonlist-apply, ilist, iota1, possible-orders, num-connects, list-pos, repeat, all-connects and cons-if-true. 1. Destructive list modification -------------------------------- (insert! ls obj) This adds obj to the beginning of ls; ls must be a non-empty list. (delete-item! tail) This removes the first item from tail. tail must be a non-empty list. If tail is only one item long, the item is replaced with the empty list rather than being removed. (delf! proc ls) This applies proc to each element of ls; if it returns true, that element is removed from the list. If ls is only one item long and that item would be deleted, delf! cannot delete that element but will instead replace it with (placeholder). (replace! proc ls new) This applies proc to each element of ls; if it returns true, that element is replaced with new. (insert-at-end! ls obj) This adds obj to the end of ls; ls must be a non-empty list. (replace-pos! ls pos new) This replaces the element at position pos in ls with new. 2. Non-destructive list modification ------------------------------------ (muremove ls obj proc) This calls (proc obj element) for each element of ls and returns a version of ls in which all elements for which the application of proc to obj and the element returns true are removed. (remove-some ls obj proc num) This functions as muremove except that only the first num elements for which the application of proc to obj and the element returns true are removed. (remove-list from remove find) from and remove must be lists; find must be a procedure which will be called to see whether elements of from exist in the remove list. remove-list returns from with any elements which are present in remove removed from it. For each element of from, find is called with that element as its first argument and remove as its second argument. If find returns true the element will not be present in the returned version of from. (remove-pos ls pos) remove-pos returns ls without the element present at position pos, starting from 0. (occur ls1 ls2) occur returns a list containing all elements which are present both in ls1 and ls2. For an element to be present in both an element in ls1 must be equal? to one in ls2. (list-head ls size) list-head returns a list containing the first size elements of ls. (chop ls size) chop returns a list of lists. These lists represent ls cut up into pieces of size size. For example (chop '(1 2 3 4 5) 2) returns ((1 2) (3 4) (5)). 3. Mapping ---------- (filter-map proc ls ...) filter-map is similar to map, except that only true values may be included in the list which is returned. For example, (filter-map number? '(a 1 b)) would return (#t). (first-true proc ls ...) first-true is also similar to map, except that the only value returned is the result of the first application of proc to elements of the lists which returns true. E.g. (first-true (lambda (x) (and (number? x) x)) '(a b 3 4 d)) returns 3. Once such a true value has been returned the rest of the lists are not evaluated. (count proc ls) This applies proc to each element of ls and returns the number of times this application has returned a true value. (first-true-pos proc ls ...) This is similar to map except that the value returned is a number representing the position in the lists of the first application of proc which returns true. (apply-for-each proc ls) This applies proc to each element of ls using the apply procedure (as in (apply proc element). It does not return anything. (append-map proc ls ...) This is similar to map except that the values returned by proc must be lists, they will be concatenated together into one list using append and this value will be returned. (all-true proc ls ...) all-true applies proc to the elements of the lists ls ... in the same way as map and returns #t if all the applications return true, otherwise #f. 4. Procedure modification ------------------------- (specify keep proc constant ...) specify is a way to create a version of proc with less arguments by specifying constant values for some of its arguments. For example, the 2-argument smatch is created from the 3-argument mmatch by (specify #f mmatch stdmp #f #f). For each argument of proc, a value must be provided; if that value is eq? to keep, the new procedure retains that argument; if it is not, the new procedure will not have that argument, and will pass this value to proc itself. Thus ((specify #f mmatch stdmp #f #f) 1 1) is equivalent to (mmatch stdmp 1 1). (modify-return modifier proc) This creates a new procedure by using modifier to modify the return value of proc. modifier is a procedure of one argument: the return value of proc. For example: ((modify-return (lambda (x) (+ x 1)) +) 1 2) returns 4. Or perhaps more usefully: ((modify-return proper smatch) '(_ ...) '(a b c)) returns (a b c). (note that using smatch requires mmatch.ss to be loaded). 5. Miscellaneous ---------------- (improper ls) Takes a proper list and returns an improper equivalent. (proper ls) Takes an improper list and returns a proper equivalent. (ilist arg ...) Returns an improper list of all its arguments. (iota1 max) This returns a list consisting of a sequence of numbers starting from 1 and ending in max. Each whole number in between the two exists in the sequence. Thus (iota1 5) returns (1 2 3 4 5). This is similar to Guile's iota function except that the list starts with 1 not 0. (optarg pos args) (optarg pos args alt) optarg is an attempt to make it easier to access optional arguments for procedures which use the dotted/improper list type for their list of arguments. optarg's function is to extract optional arguments from the list of arguments after the dot. optarg's arguments are as follows: pos is the position in the optional arguments list where the argument we wish to retrieve will be if it has been given (note that the first position is 0); args is the optional arguments list itself, the final argument which comes after the dot; alt is a default value which is returned if the optional value we want has not been given. If alt is not given, #f is used instead. Examples: (optarg 2 '(a b c)) returns c; (optarg 1 '(a) 'default) returns default; (optarg 1 '(a)) returns #f. (nonlist-apply proc args) If args is a list, proc is applied to it; otherwise, proc is called with args as its only argument. (possible-orders ls) This returns a list of lists representing all the possible orders the elements of ls could be arranged in. This function becomes exponentially slower with longer lists; on an interpreted system lists longer than about 7 elements long start to take a very long time. (num-connects x) This returns the xth triangular number. In other words, if there are x objects and there is a "connection" between each object and each other object, this function returns the number of connections. (list-pos ls obj) This returns the position of the first instance of obj in ls. This is found by using equal? to compare obj to elements of ls. (repeat obj times) This returns a list consisting of obj repeated times times. (all-connects ls) This returns a list of pairs, each one of which represents a "connection" between two different elements of ls. There is a connection between each element and each other element and all of those connections are included in the resulting list. (cons-if-true x y) If y is true, return (cons x y), else return x. No, I can't remember what the point of this is. numbers A simple list of numbers to practise list-manipulations on.