Documentation for a Collection of R7RS Libraries

Peter Lane

May 2017 Documentation for R7RS Libraries ii

Contents

1 Introduction 1 1.1 Getting Started...... 1 1.2 Documentation...... 2

2 Abbrev: (import (robin abbrev)) 3 2.1 abbrev...... 3

3 Constants: (import (robin constants)) 4

4 CSV: (import (robin csv)) 5 4.1 make-csv-reader...... 5 4.2 csv-read...... 5 4.3 csv-read-all...... 5 4.4 make-csv-writer...... 6 4.5 csv-write...... 6 4.6 csv-write-all...... 6

5 Directory: (import (robin directory)) 7 5.1 change-directory...... 7 5.2 current-directory...... 7 5.3 delete-directory...... 7 5.4 list-directory...... 7 5.5 list-directory-files...... 8 5.6 list-glob...... 8 5.7 make-directory...... 8 5.8 Example: Count lines of Scheme code...... 9

6 Disjoint Set: (import (robin disjoint-set)) 10 6.1 make-disjoint-set...... 10 6.2 disjoint-set?...... 10 6.3 disjoint-set:make...... 10 6.4 disjoint-set:find...... 10 6.5 disjoint-set:union...... 10 6.6 disjoint-set:size...... 10 6.7 Example: Kruskal’s Algorithm...... 11 Documentation for R7RS Libraries iii

7 Logger: (import (robin logger)) 12 7.1 new-logger...... 12 7.2 logger?...... 12 7.3 log-close...... 12 7.4 log-add...... 13 7.5 log-unknown log-fatal log-error log-warn log-info log-debug...... 13 7.6 log-level...... 13 7.7 log-unknown? log-fatal? log-error? log-warn? log-info? log-debug?...... 13 7.8 Example...... 13

8 Series: (import (robin series)) 15 8.1 Scanners...... 15 8.1.1 series...... 15 8.1.2 series?...... 15 8.1.3 make-series...... 15 8.1.4 scan...... 15 8.1.5 scan-list...... 15 8.1.6 scan-vector...... 16 8.1.7 scan-string...... 16 8.1.8 scan-range...... 16 8.1.9 scan-sublists...... 16 8.1.10 scan-alist...... 16 8.1.11 scan-file...... 16 8.1.12 scan-fn...... 16 8.1.13 scan-fn-inclusive...... 16 8.2 Mapping...... 16 8.2.1 map-fn...... 16 8.3 Truncation...... 16 8.3.1 until...... 16 8.3.2 until-if...... 16 8.4 Other On-Line Transducers...... 17 8.4.1 previous...... 17 8.5 Choosing and Expanding...... 17 8.5.1 choose...... 17 8.5.2 choose-if...... 17 8.5.3 spread...... 17 8.5.4 expand...... 17 8.6 Other Off-Line Transducers...... 17 8.6.1 catenate...... 17 Documentation for R7RS Libraries iv

8.6.2 subseries...... 17 8.6.3 positions...... 17 8.6.4 mask...... 17 8.6.5 mingle...... 17 8.7 Collectors...... 18 8.7.1 collect-last...... 18 8.7.2 collect-first...... 18 8.7.3 collect-nth...... 18 8.7.4 collect...... 18 8.7.5 collect-string...... 18 8.7.6 collect-append...... 18 8.7.7 collect-alist...... 18 8.7.8 collect-file...... 18 8.7.9 collect-length...... 18 8.7.10 collect-sum...... 18 8.7.11 collect-max...... 18 8.7.12 collect-min...... 19 8.7.13 collect-and...... 19 8.7.14 collect-or...... 19 8.7.15 collect-fn...... 19

9 SRFI 64 Utilities: (import (robin srfi64-utils)) 20 9.1 test-all-equal...... 20 9.2 test-approx-same...... 20 9.3 test-compare...... 20 9.4 test-no-error...... 21

10 Statistics: (import (robin statistics)) 22 10.1 arithmetic-mean...... 22 10.2 arithmetic-geometric-mean...... 22 10.3 coefficient-of-variation...... 22 10.4 combinations...... 22 10.5 geometric-mean...... 23 10.6 harmonic-mean...... 23 10.7 jaccard-distance...... 23 10.8 jaccard-index...... 23 10.9 mean...... 24 10.10median...... 24 10.11mode...... 24 Documentation for R7RS Libraries v

10.12percentile...... 24 10.13perlin-noise...... 24 10.14permutations...... 25 10.15population-standard-deviation...... 25 10.16population-variance...... 25 10.17random-normal...... 25 10.18random-pick...... 26 10.19random-sample...... 26 10.20random-weighted-sample...... 26 10.21sign...... 26 10.22sorenson-dice-index...... 27 10.23standard-deviation...... 27 10.24standard-error-of-the-mean...... 27 10.25variance...... 27

11 Text: (import (robin text)) 28 11.1 daitch-mokotoff-soundex...... 28 11.2 hamming-distance...... 28 11.3 levenshtein-distance...... 29 11.4 metaphone...... 29 11.5 optimal-string-alignment-distance...... 29 11.6 porter-stem...... 30 11.7 russell-soundex...... 30 11.8 sorenson-dice-similarity...... 30 11.9 soundex...... 30 11.10string→n-grams...... 30 11.11words→with-commas...... 31 11.12word-wrap...... 31

12 PS/Tk: Tk Graphical User Interface Toolkit 32 12.1 Simple Example...... 33 12.2 Working with Widgets...... 34 12.3 Tk Functions...... 35 12.3.1 tk/after ...... 35 12.3.2 tk/appname ...... 35 12.3.3 tk/bell ...... 36 12.3.4 tk/bgerror ...... 36 12.3.5 tk/bind ...... 36 12.3.6 tk/bindtags ...... 36 Documentation for R7RS Libraries vi

12.3.7 tk/caret ...... 36 12.3.8 tk/choose-color ...... 36 12.3.9 tk/choose-directory ...... 37 12.3.10 tk/clipboard ...... 37 12.3.11 tk/destroy ...... 37 12.3.12 tk/event ...... 38 12.3.13 tk/focus ...... 38 12.3.14 tk/focus-follows-mouse ...... 38 12.3.15 tk/focus-next ...... 38 12.3.16 tk/focus-prev ...... 38 12.3.17 tk/get-open-file ...... 38 12.3.18 tk/get-save-file ...... 39 12.3.19 tk/grab ...... 39 12.3.20 tk/grid ...... 39 12.3.21 tk/image ...... 40 12.3.22 tk/lower ...... 40 12.3.23 tk/message-box ...... 40 12.3.24 tk/option ...... 41 12.3.25 tk/pack ...... 41 12.3.26 tk/place ...... 42 12.3.27 tk/popup ...... 42 12.3.28 tk/raise ...... 42 12.3.29 tk/scaling ...... 42 12.3.30 tk/selection ...... 42 12.3.31 tk/update ...... 42 12.3.32 tk/useinputmethods ...... 42 12.3.33 tk/wait ...... 43 12.3.34 tk/windowingsystem ...... 43 12.3.35 tk/winfo ...... 43 12.3.36 tk/wm ...... 43 12.3.37 ttk/available-themes ...... 43 12.3.38 ttk-map-widgets ...... 44 12.3.39 ttk/set-theme ...... 44 12.3.40 ttk/style ...... 44 12.4 PS/Tk Functions...... 44 12.4.1 tk-end ...... 44 12.4.2 tk-eval ...... 44 12.4.3 tk-event-loop ...... 44 12.4.4 tk-start ...... 45 Documentation for R7RS Libraries vii

12.4.5 tk-var tk-get-var tk-set-var! ...... 45 12.4.6 tk-wait-for-window ...... 45 12.4.7 tk-wait-until-visible ...... 45 12.4.8 tk-with-lock ...... 45 12.5 History...... 46

13 PS/Tk PlotChart: Chart Plotting Library 47 13.1 Bar Chart...... 47 13.2 Pie Chart...... 49 13.3 XY Plot...... 50

14 SLIB Introduction and Miscellaneous Libraries 53 14.1 Charplot: (import (slib charplot)) ...... 53 14.1.1 charplot:dimensions...... 54 14.1.2 histograph...... 54 14.1.3 plot...... 54 14.2 Database...... 56 14.2.1 Creating a database...... 57 14.2.2 Working with a database...... 58 14.3 Dynamic: (import (slib dynamic)) ...... 58 14.4 Format: (import (slib format)) ...... 59 14.5 Soundex: (import (slib soundex)) ...... 59 14.6 SSAX XML Parser: (import (slib xml-parse)) ...... 59 14.7 URIs: (import (slib uri)) ...... 60 14.7.1 absolute-path...... 60 14.7.2 absolute-uri?...... 60 14.7.3 glob-pattern?...... 60 14.7.4 html syntax...... 60 14.7.5 make-uri...... 61 14.7.6 null-directory?...... 61 14.7.7 parse-ftp-address...... 61 14.7.8 path→uri...... 62 14.7.9 uri→tree...... 62 14.7.10 uri:decode-query...... 62 14.7.11 uri:make-path...... 62 14.7.12 uri:splitfields...... 62 14.7.13 uric:decode/encode...... 62 Documentation for R7RS Libraries viii

15 SLIB Common: (import (slib common)) 63 15.1 add-base-table-implementation...... 63 15.2 base-table-implementations...... 63 15.3 call-with-open-ports...... 63 15.4 char-code-limit...... 63 15.5 gentemp...... 63 15.6 identity...... 63 15.7 make-exchanger...... 63 15.8 most-positive-fixnum...... 64 15.9 open-file...... 64 15.10output-port-height...... 64 15.11output-port-width...... 64 15.12provided?...... 64 15.13slib:version...... 64 15.14slib:warn...... 64 15.15software-type...... 64 15.16system...... 64 15.17tmpnam...... 64 15.18with-load-pathname...... 65

16 SLIB Array Libraries 66 16.1 SRFI 63: (import (srfi 63)) ...... 66 16.2 Array Mapping: (import (slib array-for-each)) ...... 68 16.2.1 array-for-each...... 68 16.2.2 array-indexes...... 68 16.2.3 array-index-for-each...... 68 16.2.4 array-index-map!...... 69 16.2.5 array-map!...... 69 16.2.6 array-map...... 69 16.2.7 array:copy!...... 69 16.3 Array Interpolation: (import (slib array-interpolate)) ...... 70 16.3.1 interpolate-array-ref...... 70 16.3.2 resample-array!...... 70 16.4 Determinant: (import (slib determinant)) ...... 71 16.4.1 determinant...... 71 16.4.2 matrix→array...... 71 16.4.3 matrix→lists...... 71 16.4.4 matrix:difference...... 71 16.4.5 matrix:inverse...... 71 Documentation for R7RS Libraries ix

16.4.6 matrix:product...... 72 16.4.7 matrix:sum...... 72 16.4.8 transpose...... 72 16.5 Subarray: (import (slib subarray)) ...... 72 16.5.1 array-trim...... 72 16.5.2 subarray...... 73

17 SLIB Colour Libraries 75 17.1 NBS/ISCC Colour System: (import (slib nbs-iscc)) ...... 75 17.2 Resene Colour System: (import (slib resene)) ...... 76 17.3 Saturated Colour System: (import (slib saturate)) ...... 77

18 SLIB Mathematics Libraries 78 18.1 Factor: (import (slib factor)) ...... 78 18.1.1 factor...... 78 18.1.2 jacobi-symbol...... 78 18.1.3 prime:trials...... 78 18.1.4 prime?...... 79 18.1.5 primes<...... 79 18.1.6 primes>...... 79 18.2 Maths Integer Functions: (import (slib math-integer)) ...... 79 18.3 Maths Real Functions: (import (slib math-real)) ...... 80 18.4 Minimize: (import (slib minimize)) ...... 80 18.4.1 golden-section-search...... 80 18.5 Random Inexact Numbers: (import (slib random-inexact)) ...... 81 18.5.1 random:exp...... 81 18.5.2 random:hollow-sphere!...... 81 18.5.3 random:normal...... 82 18.5.4 random:normal-vector!...... 82 18.5.5 random:solid-sphere!...... 82 18.5.6 random:uniform...... 82 18.6 Rationalize: (import (slib rationalize)) ...... 82

19 SLIB Time/Date Libraries 84 19.1 (slib common-lisp-time) ...... 85 19.2 (slib time-core) ...... 85 19.3 (slib posix-time) ...... 86 19.4 (slib time-zone) ...... 86 19.5 (slib tzfile) ...... 87 Documentation for R7RS Libraries x

20 Repackaged or Ported Libraries 89 20.1 Automatic Differentiation: (import (autodiff NNNN))...... 89 20.1.1 AD: (import (autodiff AD)) ...... 89 20.2 Natural Language Tool Kit: (import (nltk NNNN)) ...... 90 20.3 Purely Functional Data Structures: (import (pfds NNNN)) ...... 91 20.4 R6RS: (import (r6rs NNNN)) ...... 91 20.5 Rebottled...... 92 20.5.1 CL-PDF: (import (rebottled cl-pdf)) ...... 92 20.5.2 JSON...... 92 20.5.3 Packrat: (import (rebottled packrat)) ...... 92 20.5.4 Portable Regular Expressions: (import (rebottled pregexp)) ...... 93 20.5.5 Quaternions: (import (rebottled quaternions)) ...... 93 20.5.6 Schelog: (import (rebottled schelog)) ...... 93 20.6 SRFI: (import (srfi NN)) ...... 93 20.7 Weinholt Industria: (import (weinholt NNNN)) ...... 93

A Information on Library Imports 94

B Open Works License 126

21 Index 127 Documentation for R7RS Libraries 1 / 131

Chapter 1

Introduction

The R7RS Libraries referred to here are a collection of libraries written for or, mostly, repackaged for R7RS Scheme. The library implementations are available from https://peterlane.netlify.com/r7rs-libs. The collection has been tested on Chibi, Gauche, Kawa, Larceny and Sagittarius implementations (in R7RS mode, if neces- sary). Any incompatibilities or test failures are noted in README.md. In most cases, the collection will work on other R7RS implementations. However, there are some dependencies. For example, (slib directory) requires some interaction with the , which is platform specific. Most of the individual libraries rely on one or more SRFIs. Those SRFIs not currently included with the tested implementations are included in this collection, as are some R6RS libraries. The different libraries have individual license information. A file LICENSE.md in the download provides details. There are 7 subcollections and 168 libraries.

Table 1.1: Information on Subcollections

Name Libraries Exports autodiff 17 145 nltk 6 76 pfds 15 179 rebottled 12 391 robin 10 124 slib 91 711 weinholt 17 191 Total 168 1817

1.1 Getting Started

Many of the libraries are available from http://snow-fort.org/pkg and can be downloaded directly using snow-chibi or a similar client. The collection can be obtained directly and in full by downloading or cloning from the link above. The directories are named according to each group of libraries. Those directories ending "-examples" or "-tests" are not needed if you are only interested in using the libraries (but are a good source of examples to learn from). In most cases, using the libraries from your implementation is straightforward. If the directory containing the files is SCHEME_LIBS, you must call your implementation with SCHEME_LIBS in its library path. e.g. > chibi-scheme-I SCHEME_LIBS-I SCHEME_LIBS/srfis/chibi program.sps > gosh-r7-I SCHEME_LIBS-I SCHEME_LIBS/srfis/gauche program.sps Documentation for R7RS Libraries 2 / 131

> larceny-path SCHEME_LIBS-r7rs-program program.sps > sagittarius-r7-L SCHEME_LIBS-L SCHEME_LIBS/srfis/sagittarius program.sps

Note that Larceny has all required SRFIs to support the complete collection. For the others, you also need to reference the implementation-specific SRFIs, in the directory SCHEME_LIBS/srfis/IMPLEMENTATION. (Your implementation may support alternative ways to define the location of libraries.) Kawa For use in Kawa I recommend precompiling the collection into class files. The script build-kawa, for bash or msdos, compiles the complete collection and packs it into a single jar file: r7rs-libs.jar; the produces some warnings, mostly of unused functions, which can be ignored. Either:

• Add this jar file to your CLASSPATH for use within Kawa.

• Alternatively, for making the collection permanently available, place the .jar file in your kawa/lib directory, and add the .jar file to the list in KAWA_EXTRA_PATH in the relevant kawa/bin script.

Kawa note: names with colons Kawa uses the colon to access properties of a value, such as fields or methods, as explained in https://www.gnu.org/- /kawa/Colon-notation.html. This sometimes causes problems in interpretation: one solution is to rename names with colons on import, or use the | . . . | vertical bar syntax when referring to the library names.

1.2 Documentation

This document begins with the libraries under the robin subcollection, as these are written by myself. These libraries cover a range of functionality, including a logger, statistics library, an implementation of Lisp’s Series package, and a range of functions for working with text. Each library is covered in a separate chapter. The remaining chapters cover collections repackaged from other sources. These include SLIB and a range of smaller collections. Most of these have their own documentation, which is linked to. Some examples and descriptions are provided for libraries that particularly interest me, or which lack alternative information. SLIB’s libraries cover a range of topics, and important topics are covered in separate chapters.

Help Wanted Many of the ported libraries have inadequate documentation / examples, making them hard to pick up and get started with. Send me examples to include in the repository. Write documentation on your web pages or blogs, or send to include here. Documentation for R7RS Libraries 3 / 131

Chapter 2

Abbrev: (import (robin abbrev))

Create unique abbreviations for a list of strings. This library is a port of the equivalent Ruby library.

2.1 abbrev

Input:

• a list of strings • an optional prefix

Output:

• an association list mapping unique abbreviations to its matching string

For example: #|kawa:9|#(import(robin abbrev)) #|kawa:10|#(abbrev’("scheme""scala""lisp")) ((lisp. lisp)(lis. lisp)(li. lisp)(l. lisp) (scala. scala)(scal. scala)(sca. scala) (scheme. scheme)(schem. scheme)(sche. scheme)(sch. scheme))

The first line shows that any prefix to "lisp" is an acceptable, unique abbreviation: because no other word in the list of strings starts with the letter "l". For Scala and Scheme, the unique abbreviations start with three letters, as "s" and "sc" are prefixes to both. The optional prefix will only include words that have that prefix, allowing us to select a subset of the strings to generate abbrevi- ations for. For example: #|kawa:11|#(abbrev’("scheme""scala""lisp")"s") ((scala. scala)(scal. scala)(sca. scala) (scheme. scheme)(schem. scheme)(sche. scheme)(sch. scheme))

With the "s" prefix included, "lisp" is no longer in the output. As a simple application, the abbreviations can be used as a word or command expander: #|kawa:2|#(define shortcuts(abbrev’("scheme""scala""lisp"))) #|kawa:3|#(cdr(assoc"l" shortcuts)) lisp #|kawa:4|#(cdr(assoc"sch" shortcuts)) scheme Documentation for R7RS Libraries 4 / 131

Chapter 3

Constants: (import (robin constants))

This library was born out of frustration in not having PI to hand when needed. It provides some mathematical or physical constants for use in calculations. (You probably want to use only or prefix statements when using this library, as some of the constants are single letters.)

Table 3.1: Currently provided constants

Description Name Newton’s constant of gravitation G Speed of light in a vacuum c PI PI e e

Use very simply: #|kawa:1|#(import(robin constants)) #|kawa:2|#PI 3.141592653589793 #|kawa:3|#G 6.67408E-11 #|kawa:4|#(define(arear)( * PIrr)) #|kawa:5|#(area 3) 28.274333882308138 Documentation for R7RS Libraries 5 / 131

Chapter 4

CSV: (import (robin csv))

A CSV reader/writer library. RFC4180 compliant - http://tools.ietf.org/html/rfc4180 - but allowing:

• choice of separator character, e.g. tab instead of comma • choice of quote character, e.g. single instead of double-quote • "CR LF", "CR" or "LF" are all accepted as line endings when reading

The CSV reader/writer uses a standard input or output port. Records are retrieved or written as lists of field values. Fields are always read as strings. Fields are written using display unless they are strings needing quoting, when they are written character by character, or symbols, which are first converted to strings.

4.1 make-csv-reader

Creates a csv-reader object:

• no arguments: uses current input port, comma as separator and double-quote for quote character • one argument: specifies input port • two arguments: specifies input port and separator character • three arguments: specifies input port, separator character and quote character

4.2 csv-read

Reads a single record (list of fields) from given reader, or current-input-port if no reader given.

4.3 csv-read-all

Reads a list of records (list of fields) from given reader, or current-input-port if no reader given. $ sash-r7-L. sash[r7rs]> (import(robin csv)(scheme file)) sash[r7rs]> (with-input-from-file"data.csv"(lambda()(csv-read-all))) (("123" "field 2" "456") ("789" "see, comma" "12")) sash[r7rs]> Documentation for R7RS Libraries 6 / 131

4.4 make-csv-writer

Creates a csv-writer object:

• no arguments: uses current-output-port, comma as separator and double-quote for quote character • one argument: specifies output port • two arguments: specifies output port and separator character

• three arguments: specifies output port, separator character and quote character

4.5 csv-write

Writes a single record (list of fields) in CSV format:

• one argument: the record, writes to the current-output-port with comma as separator and double-quote for quote character • two arguments: the record and a csv-writer object

4.6 csv-write-all

Writes a list of records in CSV format:

• one argument: the records, writes to the current-output-port with comma as separator and double-quote for quote character • two arguments: the records and a csv-writer object

$ sash-r7-L. sash[r7rs]> (import(robin csv)(scheme file)) sash[r7rs]> (with-output-to-file"data.csv" (lambda()(csv-write-all ’((123 "field 2" 456) (789 "see, comma" 012))))) sash[r7rs]> $ more data.csv 123,field 2,456 789,"see, comma",12 Documentation for R7RS Libraries 7 / 131

Chapter 5

Directory: (import (robin directory))

This library is implementation specific, providing a common interface for working with directories.

5.1 change-directory change-directory changes the current working directory to the given directory.

5.2 current-directory current-directory returns the current working directory (as a string): #|kawa:1|#(import(robin directory)) #|kawa:2|#(current-directory) /home/peter/Software/r7rs-libs/robin

5.3 delete-directory delete-directory deletes the given directory.

5.4 list-directory list-directory returns a list of all files and directories in the given directory: #|kawa:3|#(list-directory".") (pfds announce.txt robin-examples pfds-tests weinholt robin r7rs-libs.jar r6rs pfds-examples build-kawa.sh autodiff-examples nltk-tests rebottled INSTALL.md slib run-tests.sh nltk-examples weinholt-tests slib-examples srfis.gitignore LICENSE.md.git rebottled-tests jacal robin-tests build-kawa-win.bat bin rebottled-examples nltk doc autodiff slib-tests README.md jacal.sh jacal-tests autodiff-tests) Documentation for R7RS Libraries 8 / 131

5.5 list-directory-files list-directory-files returns a list of the filenames in the given directory: #|kawa:3|#(list-directory-files".") (announce.txt r7rs-libs.jar build-kawa.sh INSTALL.md run-tests.sh.gitignore LICENSE.md build-kawa-win.bat README.md jacal.sh)

Giving # as the optional second argument returns a list of the pathnames of files in the given directory: #|kawa:4|#(list-directory-files"."#t) (/home/peter/Software/r7rs-libs/announce.txt /home/peter/Software/r7rs-libs/r7rs-libs.jar /home/peter/Software/r7rs-libs/build-kawa.sh /home/peter/Software/r7rs-libs/INSTALL.md /home/peter/Software/r7rs-libs/run-tests.sh /home/peter/Software/r7rs-libs/.gitignore /home/peter/Software/r7rs-libs/LICENSE.md /home/peter/Software/r7rs-libs/build-kawa-win.bat /home/peter/Software/r7rs-libs/README.md /home/peter/Software/r7rs-libs/jacal.sh)

5.6 list-glob list-glob returns all files matching the given glob. A glob is matched using slib’s filename:match??.

#|kawa:5|#(list-glob" **/*.txt") (/home/peter/Software/r7rs-libs/doc/logger.txt /home/peter/Software/r7rs-libs/doc/statistics.txt /home/peter/Software/r7rs-libs/doc/slib.txt /home/peter/Software/r7rs-libs/doc/r7rs.txt /home/peter/Software/r7rs-libs/doc/summary.txt /home/peter/Software/r7rs-libs/doc/series.txt /home/peter/Software/r7rs-libs/doc/srfi64-utils.txt /home/peter/Software/r7rs-libs/doc/repackaged.txt /home/peter/Software/r7rs-libs/doc/disjoint-set.txt /home/peter/Software/r7rs-libs/doc/constants.txt /home/peter/Software/r7rs-libs/doc/abbrev.txt /home/peter/Software/r7rs-libs/doc/directory.txt /home/peter/Software/r7rs-libs/doc/subdata.txt /home/peter/Software/r7rs-libs/doc/text.txt /home/peter/Software/r7rs-libs/doc/alldata.txt /home/peter/Software/r7rs-libs/rebottled-examples/examples.txt /home/peter/Software/r7rs-libs/robin-tests/output.txt /home/peter/Software/r7rs-libs/robin-tests/voc.txt /home/peter/Software/r7rs-libs/jacal/files.txt /home/peter/Software/r7rs-libs/announce.txt)

5.7 make-directory make-directory creates a directory with the given name: #|kawa:6|#(make-directory"test-directory") Documentation for R7RS Libraries 9 / 131

5.8 Example: Count lines of Scheme code

The program "scmcount.sps" in "robin-examples" illustrates using some of these functions to scan through all child directories from a given directory for Scheme files. The number of code lines in each file is then counted, and a list displayed of the full file paths and the counts. (define(collect-information directory) (let((current(current-directory))) (guard(err(else(display err))); ignore any errors-e.g. permission errors (change-directory directory); 1 (let((chop (+ 1 (string-length(current-directory))))) v (list-glob" **/*.s?*"; 2 (lambda(filename); chop starts directory from filename v (update-information(string-copy filename chop)))); 3 (change-directory current))))); 4v v

1 Move to the given directory v 2 Search for potential Scheme source files in any child directory v 3 Gather information about each potential Scheme file v 4 And return to the original directory v $ sagittarius-L.-L srfis/sagittarius/ robin-examples/scmcount.sps rebottled ------cl-pdf-utils.sld 334 cl-pdf.sld 315 json-parser.sld 306 json-select.sld 270 json-tools.sld 407 packrat.sld 269 pregexp.sld 675 quaternion.sld 286 schelog.sld 518 ------Total files: 9 Total lines: 3380 Documentation for R7RS Libraries 10 / 131

Chapter 6

Disjoint Set: (import (robin disjoint-set))

A disjoint-set data structure holds items in distinct sets (or groups). Efficient procedures are provided for finding a representative of the set any item is contained in, and also for joining two sets together.

6.1 make-disjoint-set make-disjoint-set takes one or two parameters: a single comparator or the equality function to use on terms, and a hash function (e.g. hash, string-hash or default-hash). The return value is a disjoint set.

6.2 disjoint-set? disjoint-set? checks if its argument is a disjoint-set instance or not, returning a boolean value.

6.3 disjoint-set:make disjoint-set:make places an item into the disjoint-set as its own group. Takes two arguments: the disjoint set and the item. Return value is undefined.

6.4 disjoint-set:find disjoint-set:find takes two arguments, the disjoint set and an item, and an optional default value. The function returns the representative item for the group that the given item is in, or the default value if not present (default is ’item-not-found if not provided).

6.5 disjoint-set:union disjoint-set:union takes three arguments, the disjoint set and two items. The disjoint set is modified to combine the groups that the two items are in.

6.6 disjoint-set:size disjoint-set:size takes a disjoint set and returns the number of distinct groups it contains. Documentation for R7RS Libraries 11 / 131

6.7 Example: Kruskal’s Algorithm

This example illustrates how disjoint sets can be used in Kruskal’s algorithm to find a minimal spanning set. (The complete code is in "robin-examples/kruskal.sps") (define(kruskal graph) (let((result ’()) (nodes(delete-duplicates(append(map car graph)(map cadr graph)) eq?))) ; 1. makea disjoint set, with each node an item (let((ds(make-disjoint-set eq? hash-by-identity))); 1 (for-each(lambda(node)(disjoint-set:make ds node)); 2v nodes) v ; 2. set’links’ holds all the links in graph, sorted with the shortest first (let loop((links(sort graph(lambda(ab) (< (caddra)(caddrb)))))) ; 3. if links non-empty and size>1 (when(and(not(null? links)) (> (disjoint-set:size ds) 1)); 3 (let((link(car links))) v (unless(eq?(disjoint-set:find ds(car link)); 4 (disjoint-set:find ds(cadr link))) v (set! result(cons link result)) (disjoint-set:union ds(car link)(cadr link)))); 5 (loop(cdr links))))) v (reverse result)))

;; using it (let* ((graph ’((ab 3) (ae 1) (bc 5) (be 4) (cd 2) (ce 6) (de 7))) (res(kruskal graph))) (format#t"MST has~a links~&"(length res)) (format#t"~{:~a~&~}" res); 6 (format#t"Total length:~a~&"(fold+0(map caddr res)))) v

1 Creates a disjoint set using eq? for equality and hash-by-identity for the hash function, because individual items v are symbols.

2 Each node is added to the disjoint set, initially in its own group. v 3 The number of groups in the disjoint set tells us how many links remain to be added. v 4 Look for a link where its end points are in different groups: tested by finding the representative item of each end point’s v group in the disjoint set.

5 When we add a link, connect the groups in the disjoint set. v 6 Note use of format to print a list of items v Output: MST has4 links :(ae 1) :(cd 2) :(ab 3) :(bc 5) Total length: 11 Documentation for R7RS Libraries 12 / 131

Chapter 7

Logger: (import (robin logger))

The Logger library is used to output messages to an output port. Each message is given a level, and only messages above a certain set level will be output to the port. This allows the developer to control the level of detail output by the program. This logger library uses the same levels as Ruby’s Logger class:

1. unknown: An unknown message that should always be logged. 2. fatal: An unhandleable error that results in a program crash. 3. error: A handleable error condition.

4. warn: A warning. 5. info: Generic (useful) information about system operation. 6. debug: Low-level information for developers.

7.1 new-logger new-logger creates a new logger object. It accepts one argument: if the argument is a port, the logged output will be directed at that port; if the argument is a string, then the string will be treated as a filename, and the logger will open the file and send output to it. Use (current-input-port) to set the logger to output to the terminal.

7.2 logger? logger? checks if the given object is a logger object or not.

7.3 log-close log-close used to close up the logger. This only has an effect if the logger was created with a string, and has opened its own output file: the file port created by the logger is then closed. Documentation for R7RS Libraries 13 / 131

7.4 log-add log-add is used to output a message. It accepts three arguments:

• logger is the log object to use for the output • msg is the message to output, and must be a string • level is the log level to use for the output

Usually you will use one of the functions described in the next subsection, but sometimes it is useful for the program to decide which log level to output a message at.

7.5 log-unknown log-fatal log-error log-warn log-info log-debug log-unknown log-fatal log-error log-warn log-info log-debug all accept two arguments, the log object and a message to output. The message is output if the log level mentioned in the function name is a valid one given the log object’s current log level.

7.6 log-level log-level accepts two arguments, a log object and a log level, and sets the logger’s level.

7.7 log-unknown? log-fatal? log-error? log-warn? log-info? log-debug? log-unknown? log-fatal? log-error? log-warn? log-info? log-debug? all accept one argument, the log object, and return true if a log message at the given level would be output by the log object.

7.8 Example

The following example illustrates how these functions may be used:

(define log(new-logger"log1.txt")); 1 (log-level log’info); 2v (log-info log"some information logged"); 3v (log-debug log"this will be ignored"); 4v (log-level log’debug); 5v (log-debug log"but this included"); 6v (log-close log); 7v v

1 Create a new logger, output to the given file v 2 Sets the log level to "info" v 3 Outputs a line at "info" level, which will be output v 4 Tries to output a line at "debug" level, but this will be ignored as it is lower than the set level v 5 Sets the log level to "debug" v 6 And now the log message at "debug" level will be output v Documentation for R7RS Libraries 14 / 131

7 Finally, close the logger, which closes the file port it opened v The output from the above example is sent to the file "log1.txt", which contains two lines. Notice the log level precedes each message. $ more log1.txt info: some information logged debug: but this included Documentation for R7RS Libraries 15 / 131

Chapter 8

Series: (import (robin series))

An implementation of Richard Waters’ Lisp Series package. The original package is documented at:

1. Optimization of Series Expressions: Part I:User’s Manual for the Series Macro Package, by Richard C. Waters, A.I. Memo No. 1082, MIT, 1989. pdf 2. Optimization of Series Expressions: Part II:Overview of the Theory and Implementation, by Richard C. Waters, A.I. Memo No. 1083, MIT, 1989. pdf

Note This package is still experimental. In particular, it is not optimised.

8.1 Scanners

Scanners create series.

8.1.1 series series

8.1.2 series? series?

8.1.3 make-series make-series

8.1.4 scan scan

8.1.5 scan-list scan-list Documentation for R7RS Libraries 16 / 131

8.1.6 scan-vector scan-vector

8.1.7 scan-string scan-string

8.1.8 scan-range scan-range

8.1.9 scan-sublists scan-sublists

8.1.10 scan-alist scan-alist

8.1.11 scan-file scan-file

8.1.12 scan-fn scan-fn

8.1.13 scan-fn-inclusive scan-fn-inclusive

8.2 Mapping

8.2.1 map-fn map-fn

8.3 Truncation

8.3.1 until until

8.3.2 until-if until-if Documentation for R7RS Libraries 17 / 131

8.4 Other On-Line Transducers

8.4.1 previous previous

8.5 Choosing and Expanding

8.5.1 choose choose

8.5.2 choose-if choose-if

8.5.3 spread spread

8.5.4 expand expand

8.6 Other Off-Line Transducers

8.6.1 catenate catenate

8.6.2 subseries subseries

8.6.3 positions positions

8.6.4 mask mask

8.6.5 mingle mingle Documentation for R7RS Libraries 18 / 131

8.7 Collectors

8.7.1 collect-last collect-last

8.7.2 collect-first collect-first

8.7.3 collect-nth collect-nth

8.7.4 collect collect

8.7.5 collect-string collect-string

8.7.6 collect-append collect-append

8.7.7 collect-alist collect-alist

8.7.8 collect-file collect-file

8.7.9 collect-length collect-length

8.7.10 collect-sum collect-sum

8.7.11 collect-max collect-max Documentation for R7RS Libraries 19 / 131

8.7.12 collect-min collect-min

8.7.13 collect-and collect-and

8.7.14 collect-or collect-or

8.7.15 collect-fn collect-fn Documentation for R7RS Libraries 20 / 131

Chapter 9

SRFI 64 Utilities: (import (robin srfi64-utils))

Some convenience functions for unit testing with SRFI 64.

9.1 test-all-equal test-all-equal accepts two arguments: a function to test and an association list of ( argument . result ) pairs. The function effectively calls (test-equal result (function argument)) for all pairs. (test-all-equal daitch-mokotoff-soundex ’(("MANHEIM"."665600") ("MINTZ"."664000") ("TOPF"."370000") ("AUERBACH"."097500")))

9.2 test-approx-same test-approx-same checks if two inexact numbers are within a given bound. This is the same as test-approximate except that the tolerance is optional, and defaults to 0.001. #|kawa:32|#(test-approx-same 1 1.001) #|kawa:33|#(test-approx-same 1 1.001 0.0001) robin/srfi64-utils.sld:65: FAIL

9.3 test-compare test-compare checks if two given items satisfy the given comparison procedure. This is useful for testing equality of more complex data. For example, we might want to check if just the first item of sublists are the same: #|kawa:34|#(import(srfi 1)) #|kawa:41|#(define(equal-cars? i1 i2)(every(lambda(l1 l2)(equal?(car l1)(car l2))) ←- i1 i2)) #|kawa:42|#(test-compare equal-cars? ’((1 2) (3 4)) ’((1 5) (3 6))) #|kawa:43|#(test-compare equal-cars? ’((1 2) (3 4)) ’((1 5) (4 6))) robin/srfi64-utils.sld:69: FAIL Documentation for R7RS Libraries 21 / 131

9.4 test-no-error test-no-error is used to confirm that a piece of code has not thrown an error. In the following example, the first line raises an error, and so the test fails. The second line does not raise an error, and so the test passes. #|kawa:27|#(test-no-error(if(zero? 0) (error"")#t)) robin/srfi64-utils.sld:55: FAIL #|kawa:28|#(test-no-error(if(zero? 1) (error"")#t)) #|kawa:29|# Documentation for R7RS Libraries 22 / 131

Chapter 10

Statistics: (import (robin statistics))

A library of functions to compute statistical or other information about sets of data.

10.1 arithmetic-mean

Same as mean.

10.2 arithmetic-geometric-mean

The arithmetic-geometric-mean is defined as the limit of a sequence of two terms, replacing the first term with their arithmetic mean and the second with their geometric mean, until the two are equal. The function is useful in mathematical applications, see description at http://mathworld.wolfram.com/Arithmetic-GeometricMean.html The function takes two arguments and an optional tolerance: > (arithmetic-geometric-mean 1 (/ 1 (sqrt 2))) 0.8472130848351929 > (arithmetic-geometric-mean 1 (/ 1 (sqrt 2)) 1e-12) 0.8472130847939792

10.3 coefficient-of-variation coefficient-of-variation describes the amount of spread in a dataset relative to its mean. In the following example, both lists have the same mean (3), but the spread is greater in the second. #|kawa:32|#(coefficient-of-variation ’(1 2 3 4 5)) 52.70462766947299 #|kawa:33|#(coefficient-of-variation ’(-2 2 3 4 8)) 120.18504251546631

10.4 combinations combinations returns the number of ways to take k things from n without replacement, when the order does not matter. The form is (combinations n k) Documentation for R7RS Libraries 23 / 131

#|kawa:2|#(combinations 5 2) 10 #|kawa:3|#(combinations 1000 500) 270288240945436569515614693625975275496152008446548287007392875106625428705522193898612483924502370165362606085021546104802209750050679917549894219699518475423665484263751733356162464079737887344364574161119497604571044985756287880514600994219426752366915856603136862602484428109296905863799821216320 ←-

10.5 geometric-mean

The geometric mean takes the nth root of the product of the numbers, where n is the size of the data. This yields the central number within a geometric progression. #|kawa:3|#(geometric-mean ’(1 2 3 4 5)) 2.605171084697352 #|kawa:4|#(geometric-mean ’(1 3 9 27 81)) 9.000000000000002 #|kawa:5|#(geometric-mean ’(1 3 9 27)) 5.196152422706632

10.6 harmonic-mean

The harmonic mean is the reciprocal of the arithmetic mean of the reciprocals. #|kawa:6|#(harmonic-mean ’(1 2 3 4 5)) 300/137 #|kawa:7|#(inexact(harmonic-mean ’(1 2 3 4 5))) 2.18978102189781

10.7 jaccard-distance

The Jaccard Distance is simply (1 - (jaccard-index)), and measures how dissimilar the two sets are. #|kawa:46|#(jaccard-distance ’(1 2 3 4 5) ’(3 4 5 6 7)) 4/7

10.8 jaccard-index

The Jaccard Index returns a number from 0 to 1 indicating how similar two sets are. Sets here are represented as lists, and duplicates are ignored. An optional third argument provides the set-equality function (which defaults to equal?). #|kawa:40|#(jaccard-index ’(1 2 3 4 5) ’(3 4 5 6 7)) 3/7 #|kawa:42|#(jaccard-index ’(1 2 3 4 5) ’(3 4 5 1 2 2 1 1)) 1 #|kawa:43|#(jaccard-index’("a""b""c") ’("A""B""F")) 0 #|kawa:45|#(jaccard-index’("a""b""c") ’("A""B""D") string-ci=?) 1/2

Note Interestingly, the Jaccard Index is a distance metric satisfying, in particular, the triangle inequality. Documentation for R7RS Libraries 24 / 131

10.9 mean

Computes the arithmetic mean of a list of numbers. This is the familiar "add up all the numbers, divide by the total" average. #|kawa:2|#(mean ’(1 2 3 4 5)) 3

10.10 median

The median is the central number, when all the numbers are put in order (or, when there are an even number of numbers, the average of the two middle numbers). #|kawa:8|#(median ’(5 3 1 2 4)) 3

10.11 mode

The mode is the number appearing most often. The mode function returns two values: a list of the most frequent number or numbers, and their number of occurrences. #|kawa:9|#(mode ’(5 3 1 2 4)) (1 2 3 4 5) 1 #|kawa:11|#(let-values (((items count)(mode ’(5 3 5 1 2 4)))) #|.....12|#(display items)(newline)(display count)(newline)) (5) 2

10.12 percentile percentile takes two arguments, a list of data and a percent value, and returns the item in the list at that percentile position along the list, or an average of the nearest two values. percent values must be in the range 1 to 99, inclusive. Note that a percent of 50 corresponds to the median. #|kawa:13|#(percentile ’(1 2 3 4 5) 50) 3 #|kawa:14|#(percentile ’(1 2 3 4 5) 75) 4 #|kawa:16|#(percentile ’(1 2 3 4 5) 99) 5 #|kawa:19|#(percentile ’(1 2 3 4 5) 85) 5 #|kawa:20|#(percentile ’(1 2 3 4 5) 80) 9/2

10.13 perlin-noise perlin-noise is a function returning a value computed using a gradient function. Perlin Noise was invented by Ken Perlin and has been widely applied in computer graphics. The implementation here is a conversion of the Java reference implementation. perlin-noise takes three numbers as input, and returns a single number (all numbers inexact). sash> (perlin-noise 12.3 4.2 5.7) 0.4085747160714242 Documentation for R7RS Libraries 25 / 131

10.14 permutations permutations returns the number of ways to take k things from n without replacement, when the order matters. The form is (permutations n k) #|kawa:4|#(permutations 5 2) 20 #|kawa:5|#(permutations 100 20) 1303995018204712451095685346159820800000

10.15 population-standard-deviation population-standard-deviation of a list of data: #|kawa:28|#(population-standard-deviation ’(1 2 3 4 5)) 1.4142135623730951

Optionally, if you know the mean of your data, pass that as a second argument so the function does not have to recompute it: #|kawa:39|#(population-standard-deviation ’(1 2 3 4 5) 3) 1.4142135623730951

10.16 population-variance population-variance of a list of data: #|kawa:29|#(population-variance ’(1 2 3 4 5)) 2

Optionally, if you know the mean of your data, pass that as a second argument so the function does not have to recompute it.

10.17 random-normal random-normal is used to return a random number normally distributed with a given mean and standard deviation. #|kawa:2|#(random-normal 0 10) 3017/1250 #|kawa:3|#(inexact(random-normal 0 10)) 0.05948 #|kawa:4|#(inexact(random-normal 0 10)) 0.48029 #|kawa:5|#(inexact(random-normal 0 10)) -3.83553 #|kawa:7|#(inexact(random-normal 20 10)) 21.81053 #|kawa:8|#(inexact(random-normal 20 10)) 15.54491 Documentation for R7RS Libraries 26 / 131

10.18 random-pick random-pick returns a random selection from a given list #|kawa:20|#(random-pick ’(1 2 3 4 5 6)) 6 #|kawa:21|#(random-pick ’(1 2 3 4 5 6)) 3 #|kawa:22|#(random-pick ’(1 2 3 4 5 6)) 2

10.19 random-sample random-sample returns a random sample of n chosen from a list of items, without replacement #|kawa:25|#(random-sample 3 ’(1 2 3 4 5 6)) (1 4 5) #|kawa:26|#(random-sample 3 ’(1 2 3 4 5 6)) (6 5 1) #|kawa:27|#(random-sample 3 ’(1 2 3 4 5 6)) (2 3 6)

10.20 random-weighted-sample random-weighted-sample returns a random sample of n chosen from a list of items, without replacement, but with the items weighted by the given list of weights. The following gives a heavy bias to choosing 1 and 6: #|kawa:28|#(random-weighted-sample 3 ’(1 2 3 4 5 6) ’(10 1 1 1 1 10)) (6 1 5) #|kawa:29|#(random-weighted-sample 3 ’(1 2 3 4 5 6) ’(10 1 1 1 1 10)) (1 6 4) #|kawa:30|#(random-weighted-sample 3 ’(1 2 3 4 5 6) ’(10 1 1 1 1 10)) (1 6 5)

The following is a lighter bias to choosing 1 and 4: #|kawa:34|#(random-weighted-sample 3 ’(1 2 3 4 5 6) ’(2 1 1 2 1 1)) (4 6 2) #|kawa:35|#(random-weighted-sample 3 ’(1 2 3 4 5 6) ’(2 1 1 2 1 1)) (5 4 3) #|kawa:36|#(random-weighted-sample 3 ’(1 2 3 4 5 6) ’(2 1 1 2 1 1)) (1 3 2)

10.21 sign sign returns 1 for positive numbers, 0 for zero, -1 for negative numbers #|kawa:36|#(sign 10) 1 #|kawa:37|#(sign 0) 0 #|kawa:38|#(sign -0.7) -1 Documentation for R7RS Libraries 27 / 131

10.22 sorenson-dice-index

The Sorenson Dice Index is a measure of the similarity of two sets. Sets here are represented as lists, and duplicates are ignored. An optional third argument provides the set-equality function (which defaults to equal?). #|kawa:47|#(sorenson-dice-index ’(1 2 3 4 5) ’(3 4 5 6 7)) 3/5 #|kawa:48|#(sorenson-dice-index’("a""b""c") ’("A""B""D")) 0 #|kawa:49|#(sorenson-dice-index’("a""b""c") ’("A""B""D") string-ci=?) 2/3

10.23 standard-deviation standard-deviation of a list of data: #|kawa:30|#(standard-deviation ’(1 2 3 4 5)) 1.5811388300841898

Optionally, if you know the mean of your data, pass that as a second argument so the function does not have to recompute it.

10.24 standard-error-of-the-mean standard-error-of-the-mean describes the mean of the sampling distribution. #|kawa:35|#(standard-error-of-the-mean ’(1 2 3 4 5)) 0.7071067811865476

10.25 variance variance of a list of data: #|kawa:31|#(variance ’(1 2 3 4 5)) 5/2

Optionally, if you know the mean of your data, pass that as a second argument so the function does not have to recompute it. Documentation for R7RS Libraries 28 / 131

Chapter 11

Text: (import (robin text))

The text library contains a collection of functions for working with strings or text documents, including similarity measures, a stemmer and layout.

11.1 daitch-mokotoff-soundex

The Daitch-Mokotoff Soundex algorithm is a variant of the Russell Soundex algorithm, designed to work better for Slavic and Yiddish names. The implementation here uses the table from http://www.jewishgen.org/InfoFiles/soundex.html. #|kawa:6|#(daitch-mokotoff-soundex"LONDON") 863600 #|kawa:9|#(daitch-mokotoff-soundex"LEWINSKY") 876450 #|kawa:10|#(daitch-mokotoff-soundex"LEVINSKI") 876450

For some words, multiple codes are possible - pass an optional second argument ’all to get a list of codes: #|kawa:2|#(daitch-mokotoff-soundex"auerbach") 097500 #|kawa:3|#(daitch-mokotoff-soundex"auerbach"’all) (097500 097400)

11.2 hamming-distance

The hamming-distance is the number of mismatched items between two equal-length sequences. The hamming-distance function takes two arguments and an optional comparison procedure. The sequences can be strings, lists, vectors or bytevectors. The comparison procedure defaults to char=? for strings, = for bytevectors, and equal? for everything else. #|kawa:2|#(hamming-distance"This string""that strong") 4 #|kawa:3|#(hamming-distance"This string""that strong" char-ci=?) 3 #|kawa:4|#(hamming-distance #(1 2 3 4) #(0 2 3 5)) 2 Documentation for R7RS Libraries 29 / 131

11.3 levenshtein-distance

The levenshtein-distance counts the minimum number of insertions/deletions/substitutions to convert one sequence into another. The levenshtein-distance function takes two arguments and an optional comparison procedure. The sequences can be strings, lists, vectors or bytevectors. The comparison procedure defaults to char=? for strings, = for bytevectors, and equal? for everything else. #|kawa:2|#(levenshtein-distance"sitting""kitten") 3 #|kawa:3|#(levenshtein-distance"Saturday""sunday") 4 #|kawa:4|#(levenshtein-distance"Saturday""sunday" char-ci=?) 3

11.4 metaphone

The Metaphone Algorithm was created as an improvement on Soundex, better taking account of variations in English pronoun- ciation. The algorithm was created by Lawrence Philips, in "Computer Language" December 1990 issue. There have been many published variants of Metaphone. A summary can be found at http://aspell.net/metaphone/. The metaphone function simply takes a word to convert into a coded representation of its sound: #|kawa:2|#(metaphone"smith") SM0 #|kawa:3|#(metaphone"smythe") SM0 #|kawa:4|#(metaphone"lewinsky") LWNSK #|kawa:5|#(metaphone"levinski") LFNSK

Note, the output code is all upper-case letters, with "0" standing in for "TH".

11.5 optimal-string-alignment-distance optimal-string-alignment-distance is a modification of the Levenshtein distance to include transpositions as well as deletions, insertions or substitutions. A transposition is where two characters have been swapped, such as when typing too quiclky. The optimal-string-alignment-distance function takes two arguments and an optional comparison procedure. The sequences can be strings, lists, vectors or bytevectors. The comparison procedure defaults to char=? for strings, = for bytevectors, and equal? for everything else. > (levenshtein-distance"kitten""sitting") 3 > (optimal-string-alignment-distance"kitten""sitting") 3 > (levenshtein-distance"this string""that strnig") 4 > (optimal-string-alignment-distance"this string""that strnig") 3

Notice the difference between the two algorithms in the last case, where "n" and "i" have been transposed. Documentation for R7RS Libraries 30 / 131

11.6 porter-stem porter-stem is an implementation of the well-known Porter Stemming Algorithm, for reducing words to a base form. More details of the algorithm are at https://tartarus.org/martin/PorterStemmer/ The function simply takes the word to change, and returns the stemmed form: > (porter-stem"running") "run" > (porter-stem"apples") "appl" > (porter-stem"apple") "appl" > (porter-stem"approximation") "approxim" > (porter-stem"sympathize") "sympath" > (porter-stem"sympathise") "sympathis"

11.7 russell-soundex russell-soundex is the same as soundex, exported from (slib soundex)

11.8 sorenson-dice-similarity sorenson-dice-similarity returns a measure of how similar two strings are, based on n-grams of characters. An op- tional third argument provides the number of characters in the n-grams, which defaults to 2: > (sorenson-dice-similarity"rabbit""racket") 1/5 > (sorenson-dice-similarity"sympathize""sympthise") 10/17 > (sorenson-dice-similarity"sympathize""sympthise" 1) 8/9 > (sorenson-dice-similarity"sympathize""sympthise" 3) 2/5

11.9 soundex soundex is exported from (slib soundex).

11.10 string→n-grams string→n-grams separates a string into overlapping groups of n letters. > (string->n-grams"ABCDE" 1) ("A""B""C""D""E") > (string->n-grams"ABCDE" 3) ("ABC""BCD""CDE")

For n greater than the length of the string, the string itself is returned. If n is less than 1, an error is raised. Documentation for R7RS Libraries 31 / 131

11.11 words→with-commas words→with-commas is a function taking a list of strings and adding commas in between the items up to the last item, which is preceded by an "and". For example: > (words->with-commas ’()) "" > (words->with-commas’("apple")) "apple" > (words->with-commas’("apple""banana")) "apple and banana" > (words->with-commas’("apple""banana""chikoo")) "apple, banana and chikoo" > (words->with-commas’("apple""banana""chikoo""damson")) "apple, banana, chikoo and damson" > (words->with-commas’("apple""banana""chikoo""damson")#t) "apple, banana, chikoo, and damson"

An optional second argument controls whether the final "and" should be preceded by a comma. The default is not to have the comma.

11.12 word-wrap word-wrap takes two arguments, a string and a target width. It returns a list of strings, each item in the list representing a line of text. Each line is formatted so words do not go beyond the target width. The algorithm is a simple greedy algorithm. If a single word is longer than the target width, it is allowed to overlap. For example, setting: (define *text* "Programming languages should be designed not by piling feature on top of ←- feature, but by removing the weaknesses and restrictions that make additional features ←- appear necessary. Scheme demonstrates thata very small number of rules for forming ←- expressions, with no restrictions on how they are composed, suffice to forma practical ←- and efficient that is flexible enough to support most of the major ←- programming paradigms in use today.")

We can wrap to a width of 50 characters using: > (word-wrap *text* 50) Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary. Scheme demonstrates thata very small number of rules for forming expressions, with no restrictions on how they are composed, suffice to forma practical and efficient programming language that is flexible enough to support most of the major programming paradigms in use today. and we can wrap to a width of 60 characters using: > (word-wrap *text* 60) Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary. Scheme demonstrates thata very small number of rules for forming expressions, with no restrictions on how they are composed, suffice to forma practical and efficient programming language that is flexible enough to support most of the major programming paradigms in use today. Documentation for R7RS Libraries 32 / 131

Chapter 12

PS/Tk: Tk Graphical User Interface Toolkit

To use the library: (import (rebottled pstk)) The PS/Tk library enables a Scheme program to interact with Tk, to create cross-platform graphical user interfaces. Virtually all of Tcl/Tk is available through Scheme. Other examples of using Tk in this way include LTk from Lisp, Tkinter from Python, Perl/Tk and Ruby/Tk. PS/Tk must communicate with the separate Tcl/Tk program, a process managed in an implementation-specific manner. The current R7RS version of PS/Tk has support for, and has been tested on, the following:

• Chibi Scheme: under Linux (calls to "/bin/sh")

• Gauche Scheme: under Linux (calls to "/bin/sh") • Sagittarius Scheme: under Linux and Windows. (Should work on Mac OS too.)

Further Scheme versions or platforms can be added by extending the cond-expand statement in the source code. For more information:

• Several small examples of using the library are included.

• Some notes on using PS/Tk with Sagittarius Scheme on Linux and Windows: https://peterlane.netlify.com/posts/2017-05-12- gui-programs-with-sagittarius-scheme/ • Documentation about Tk: https://www.tcl.tk/man/tcl8.6/TkCmd/contents.htm

• Some documentation on using Tk from various languages: http://www.tkdocs.com/ Documentation for R7RS Libraries 33 / 131

12.1 Simple Example

Get started with the following program: (import(scheme base) (scheme write) (rebottled pstk))

(let((tk(tk-start))); 1 (tk/pack(tk’create-widget; 2v ’button’text:"Hello" v ’command:(lambda()(display"Hello world")(newline))); 3 ’padx: 20 ’pady: 20) v (tk-event-loop tk)); 4 v

1 Starts the TK shell working. The returned value is used to interact with the shell. v 2 Creates a button with a label and command, and packs it onto the default frame. v 3 Commands are given as Scheme functions of zero arguments. v 4 Starts the TK event loop. v Documentation for R7RS Libraries 34 / 131

12.2 Working with Widgets

The example above shows how widgets are created by sending instructions to the Tk process. The manner of operation is very close to, but a little different to that used in Tcl/Tk itself. In this section, some descriptions and examples are given to help in translating the Tcl/Tk documentation into Scheme. In Tk, widgets are created using appropriately named functions, providing a name for the new widget as a string. Tk parses this string to work out the parent widget and provide some structure. In PS/Tk we instead represent widgets as functions; these functions take a command and associated arguments. Commands that the widgets respond to include:

• get-id: returns the Tk id

• create-widget: used to create a child widget • configure: used to alter parameters of a widget • cget: returns value of a configuration option

For example, having created a button, we can later change the displayed text using configure, or retrieve the text using cget: sash> (hello’configure’text:"Goodbye") () sash> (hello’cget’text:) "Goodbye"

Apart from representing widgets as functions, most of the Tk parameters and functions map across into Scheme. Consider the Tcl/Tk equivalent of the example program above: button .hello -text Hello -command{puts stdout"Hello world"} pack .hello -padx 20 -pady 20

The first line creates a widget named ".hello". The "." means it is attached to the top-most frame. The widget is referred to in the second line, which packs the widget into the frame. Comparing the second line with the Scheme program illustrates how direct most conversions can be: pack -padx 20 -pady 20

(tk/pack ’padx: 20 ’pady: 20)

Notice these three principles:

1. Instead of a string for the widget name, we have what is returned by creating the widget (a function); for the top-most frame ("." in tcl/tk) we have the return value of tk-start (called tk here).

2. The parameters -padx are converted to symbols with a trailing colon ’padx: 3. The function name pack becomes tk/pack Documentation for R7RS Libraries 35 / 131

In addition, Scheme values are converted to Tcl values. So Scheme’s #t/#f are Tcl’s "1"/"0", symbols can be used in place of strings, etc. Creating a widget is done through the create-widget command mentioned above: button .hello -text Hello -command{puts stdout"Hello world"}

(define hello (tk’create-widget’button ’text:"Hello" ’command:(lambda()(display"Hello world")(newline))))

Instead of calling a button function, as in Tcl, the parent widget’s function is requested to create a button widget. The parameters defining the button are the same as in the Tcl example, just mapped to Scheme equivalents. This call returns a function defining the new button, which we can name in a Scheme variable. Notice how the command ’create-widget is passed as a symbol without a trailing colon; compare with how the parameter ’text: is given. This use of symbols as commands arises elsewhere, for example with winfo: winfo screenwidth.# TCL version

(tk/winfo’screenwidth tk); Scheme version

All the Tk widgets can be created and used in this way. For a list of available widgets see any Tk documentation or https://www.tcl.tk/- man/tcl8.6/TkCmd/contents.htm.

12.3 Tk Functions

These functions map directly onto underlying Tk functions. The names start tk/ with the remainder of the name mapping onto the Tk equivalent function:

• tk/bell is equivalent to Tk’s bell

• tk/choose-color is equivalent to Tk’s tk_chooseColor

12.3.1 tk/after tk/after takes a time in milliseconds and an optional function. After the given time, it calls the function or continues processing. In the analogue clock example, the function to redraw the hands in the clock uses tk/after to delay for a second before calling itself to draw the hands in the new position and repeating. (define(hands canvas)

; code to redraw the clock

(tk/after 1000 (lambda()(hands canvas))))

12.3.2 tk/appname tk/appname gets or sets the application name. Documentation for R7RS Libraries 36 / 131

sash> (tk/appname) "tclsh" sash> (tk/appname"new name set") "new name set" sash> (tk/appname) "new name set"

12.3.3 tk/bell tk/bell rings the bell.

12.3.4 tk/bgerror tk/bgerror is used to tell the Tcl process that an error has occurred.

12.3.5 tk/bind tk/bind binds actions to events. For example, a function can be called when a mouse button is clicked, or a key pressed. First argument is a window, or the symbol all; second argument is the pattern for the event to bind to; and third argument is the function to call. (tk/bind’all"" ‘(,(lambda(x)(displayx)(newline)#f)%x))

12.3.6 tk/bindtags tk/bindtags gets or sets the binding tags of a given window.

12.3.7 tk/caret tk/caret is used to query or set the current caret position in a given window. sash> (tk/caret tk); 1 "-height0-x0-y0" v sash> (tk/caret tk’height: 10 ’x: 2 ’y: 3); 2 "" v

1 tk refers to the default, or top-most window, as it is the value returned by tk-start. v 2 Sets the height or x/y position of the caret in the given window. v 12.3.8 tk/choose-color tk/choose-color opens a dialog from which to select a colour. Returns the RGB code of the selected colour, or "" if cancel is clicked. sash> (tk/choose-color) "#7ce679" Documentation for R7RS Libraries 37 / 131

Optional parameters let you select the initialcolor parent and title. See the Tk documentation for details: https://www.tcl.tk/- man/tcl8.6/TkCmd/chooseColor.htm

12.3.9 tk/choose-directory tk/choose-directory opens a dialog from which to select a directory. Returns the directory name as a string or "" if cancel is clicked. sash> (tk/choose-directory) "/home/peter/Software/r7rs-libs"

Optional parameters let you select the initialdir parent title and whether the chosen directory must exist. See the Tk documentation for details: https://www.tcl.tk/man/tcl8.6/TkCmd/chooseDirectory.htm

12.3.10 tk/clipboard tk/clipboard provides access to the clipboard, with its parameter specifying an action: append clear get See Tk documentation for details: https://www.tcl.tk/man/tcl8.6/TkCmd/clipboard.htm

12.3.11 tk/destroy tk/destroy deletes the window or windows given as arguments. Documentation for R7RS Libraries 38 / 131

12.3.12 tk/event tk/event is used to create and manage events. See the Tk documentation for details: https://www.tcl.tk/man/tcl8.6/TkCmd/event.htm

12.3.13 tk/focus tk/focus manages the input focus. See the Tk documentation for details: https://www.tcl.tk/man/tcl8.6/TkCmd/focus.htm

12.3.14 tk/focus-follows-mouse tk/focus-follows-mouse changes the focus status so it follows the mouse rather than changes with a click.

12.3.15 tk/focus-next tk/focus-next returns the next window from the given window, in the focus order.

12.3.16 tk/focus-prev tk/focus-prev returns the previous window from the given window, in the focus order.

12.3.17 tk/get-open-file tk/get-open-file opens a dialog from which the user can select a file. Returns the file path in a string or "" if cancel is clicked. sash> (tk/get-open-file) "/home/peter/Software/r7rs-libs/rebottled-examples/pstk/example-menu.sps"

Optional parameters let you select the initialdir parent title filetypes etc. See the Tk documentation for details: https://www.tcl.tk/man/tcl8.6/TkCmd/getOpenFile.htm Documentation for R7RS Libraries 39 / 131

12.3.18 tk/get-save-file tk/get-save-file opens a dialog from which the user can select a file. Returns the file path in a string or "" if cancel is clicked. sash> (tk/get-save-file) "/home/peter/Software/r7rs-libs/rebottled-examples/pstk/newfile.txt"

Optional parameters let you select the initialdir parent title filetypes etc. See the Tk documentation for details: https://www.tcl.tk/man/tcl8.6/TkCmd/getSaveFile.htm

12.3.19 tk/grab tk/grab provides a way to redirect mouse or keyboard events to specific windows. See Tk documentation for details: https://www.tcl.tk/man/tcl8.6/TkCmd/grab.htm

12.3.20 tk/grid tk/grid is the first of three techniques used to place widgets within a frame. This geometry manager is probably the most important of the three, and can be used to arrange widgets by row and column. The following sample, taken from the example "example-temp-conversion.sps" illustrates some of the possibilities:

(tk/grid celsius’column: 2 ’row: 1 ’sticky:’we’padx: 5 ’pady: 5); 1 (tk/grid label’column: 2 ’row: 2 ’sticky:’we’padx: 5 ’pady: 5); 2v (tk/grid button’column: 2 ’row: 3 ’sticky:’we’padx: 5 ’pady: 5) v (tk/grid(tk’create-widget’label’text:"celsius") ’column: 3 ’row: 1 ’sticky:’w’padx: 5 ’pady: 5); 3 (tk/grid(tk’create-widget’label’text:"is") v ’column: 1 ’row: 2 ’sticky:’e’padx: 5 ’pady: 5); 4 (tk/grid(tk’create-widget’label’text:"fahrenheit") v ’column: 3 ’row: 2 ’sticky:’w’padx: 5 ’pady: 5)

1 Places the celsius widget in row 1, column 2. The sticky option means the widget will fill the space in the horizontal v direction. The pad options place some space around the widget. Note, rows and columns are indexed from 1.

2 Similarly, the label is placed in column 2 row 2. v 3 This option only has w for the sticky option: the text label is left-justified. v 4 With the e option for sticky, this label is right-justified. v Documentation for R7RS Libraries 40 / 131

The final layout is:

For more of the many options, see: https://www.tcl.tk/man/tcl8.6/TkCmd/grid.htm

12.3.21 tk/image tk/image used to create, delete and query images. sash> (define im(tk/image’create’photo’file:"doc/pstk-hello.png")); 1 # v sash> (tk/pack(tk’create-widget’label’image: im)); 2 "" v

1 Loads an image from a file. The type should be photo or bitmap. v 2 Puts the image onto a label in the current frame. v

See the Tk documentation for more details: https://www.tcl.tk/man/tcl8.6/TkCmd/image.htm

12.3.22 tk/lower tk/lower lowers the given window below all its siblings in the current stacking order.

12.3.23 tk/message-box tk/message-box displays a Tk message box. These dialogs can be straightforward or display a range of options and an icon. The simplest information box shows a given message, and adds an "OK" button: sash> (tk/message-box’message:"Hello") "ok"; 1 v

1 The function returns the string label of the clicked button. v Documentation for R7RS Libraries 41 / 131

We can also add a title to the box, and select an icon from one of: (error info question warning) The type of box specifies the buttons. The choices are:

• "abortretryignore" - which displays three buttons, "abort" "retry" "ignore" • "ok" - which displays one button "ok"

• "okcancel" - which displays two buttons "ok" or "cancel" • "retrycancel" • "yesno"

• "yesnocancel" sash> (tk/message-box’title:"Error on opening file"’icon:’question’message:"What to ←- do now?"’type:"abortretryignore") "ignore" sash> (tk/message-box’title:"Error on opening file"’icon:’question’message:"What to ←- do now?"’type:"abortretryignore") "abort"

For a full set of options, see the Tk documentation: https://www.tcl.tk/man/tcl8.6/TkCmd/messageBox.htm

12.3.24 tk/option tk/option is used to add or retrieve window options to or from the option database. For details see the Tk documentation: https://www.tcl.tk/man/tcl8.6/TkCmd/option.htm

12.3.25 tk/pack tk/pack is the second of three techniques used to place widgets within a frame. (tk/pack command ...)

The tk pack command takes a number of options to control the order and spacing of widgets placed within a frame. For the Tk documentation, see: https://www.tcl.tk/man/tcl8.6/TkCmd/pack.htm Documentation for R7RS Libraries 42 / 131

12.3.26 tk/place tk/place is the third of three techniques used to place widgets within a frame. It provides a way to place widgets at specific coordinates. For the Tk documentation, see: https://www.tcl.tk/man/tcl8.6/TkCmd/place.htm

12.3.27 tk/popup tk/popup takes three arguments, a menu and x/y coordinates. The function pops up a menu at the given position.

12.3.28 tk/raise tk/raise raises the given window above its siblings in the current stacking order.

12.3.29 tk/scaling tk/scaling is used to get or set the number of pixels per point on a display. An optional displayof argument is used to specify a window. sash> (tk/scaling) "1.3333333333333333"

12.3.30 tk/selection tk/selection provides access to the X selection (e.g. text highlighted with the mouse). In the following image, the text "get-save" was highlighted with the mouse, and returned by calling the function with the symbol ’get:

12.3.31 tk/update tk/update updates any pending events - "Use with extreme care" (Nils Holm)

12.3.32 tk/useinputmethods tk/useinputmethods is used for XIM filtering. According to the Tcl wiki, this is useful in some locales, such as Japanese or Korean, to use particular input devices. This only works under X. (tk/useinputmethods[’displayof: window][boolean])

For querying: sash> (tk/useinputmethods) "1" Documentation for R7RS Libraries 43 / 131

12.3.33 tk/wait tk/wait is a general-purpose wait function, where the arguments specify events to wait for. In case of visibility/window types, tk-wait-for-window and tk-wait-until-visible are better choices. This function can also wait for changes to variables. See the Tk documentation for details: https://www.tcl.tk/man/tcl8.6/TkCmd/tkwait.htm

12.3.34 tk/windowingsystem tk/windowingsystem returns a string naming the underlying window system. sash> (tk/windowingsystem) "x11"

12.3.35 tk/winfo tk/winfo is used to find out information about windows currently being managed by tk. For example, the screen width and height can be found using: sash> (tk/winfo’screenwidth tk) "1920"; 1 sash> (tk/winfo’screenheight tk) v "1080"

1 The values are returned as strings, use string→number to convert to numbers. v Similarly, information about a named window: sash> (tk/winfo’x tk) "860" sash> (tk/winfo’y tk) "464"

There are many kinds of information that may be queried. For a full list, see the Tk documentation: https://www.tcl.tk/man/- tcl8.6/TkCmd/winfo.htm

12.3.36 tk/wm tk/wm is used to communicate with the Window Manager of the operating system. A simple use is to set the title of the top-most window: (tk/wm’title tk"GMT Clock")

More complex uses include fixing a window’s size, specifying an operating-system-specific window type or setting an icon. For the Tk documentation, see: https://www.tcl.tk/man/tcl8.6/TkCmd/wm.htm

12.3.37 ttk/available-themes ttk/available-themes returns a list of the available themes. sash> (define tk(tk-start)) # sash> (ttk/available-themes) ("clam""alt""default""classic") Documentation for R7RS Libraries 44 / 131

12.3.38 ttk-map-widgets

Tile is an alternative set of widgets for Tk supporting a more attractive set of themes as well as some additional widgets, such as a treeview. ttk-map-widgets is used to map native Tk widgets to their TTk equivalents. To use all the Tile widgets, call: (ttk-map-widgets’all)

(A value of none will not use any Tile widgets. Alternatively, list the specific widgets you want to map.)

12.3.39 ttk/set-theme ttk/set-theme is used to set the theme to one of those available. sash> (ttk/set-theme"classic") ""

12.3.40 ttk/style ttk/style is used to query or change the Tk style database. For the Tk documentation, see: https://www.tcl.tk/man/tcl8.6/- TkCmd/ttk_style.htm

12.4 PS/Tk Functions

These functions are included within the library but do not have direct Tk equivalents. (The function names start "tk-".)

12.4.1 tk-end tk-end is used to shutdown the Tk process, and effectively end the program. (tk-end)

12.4.2 tk-eval tk-eval evaluates a piece of TCL code, provided as a string. sash> (tk-eval"bell") "" sash> (tk-eval"puts3")

An error occurred inside Tcl/Tk --> 3 #

12.4.3 tk-event-loop tk-event-loop is used to enter the TK event loop. It takes the tk value returned from tk-start as a parameter, and does not end until tk-end is called. (tk-event-loop tk) Documentation for R7RS Libraries 45 / 131

12.4.4 tk-start tk-start is used to initiate the Tk process. It returns a function used to send commands to Tk. An optional argument names the tcl/tk program to use: on Linux, this program is "tclsh", but for easy distribution, you may wish to use "tclkit".

(let((tk(tk-start"tclkit"))) ...); 1 v

1 Starts the Tk program called "tclkit" and stores the result in the tk variable. v 12.4.5 tk-var tk-get-var tk-set-var!

These three functions work as a group and deal with how variables are linked to widget controls. tk-var is used to register a new tk-var with the given symbol name. tk-get-var is used to retrieve the value of a tk-var tk-set-var! is used to change the value of a tk-var For example:

(tk-var’cb-value); 1 (tk’create-widget’checkbutton’text:"Check me" v ’variable:(tk-var’cb-value)); 2 (display(tk-get-var’cb-value)); 3v v

1 Set up symbol cb-value as the name of variable v 2 Associates the cb-value variable with the check button v 3 Retrieves the cb-value value to display the check button’s state v 12.4.6 tk-wait-for-window tk-wait-for-window waits until the given window is destroyed (such as a dialog being closed).

12.4.7 tk-wait-until-visible tk-wait-until-visible waits until the given window becomes visible.

12.4.8 tk-with-lock tk-with-lock is used to protect functions which are working with state in a multi-threaded environment. (tk’create-widget’button ’command:(lambda() (tk-with-lock (lambda() do-something-critical)))) Documentation for R7RS Libraries 46 / 131

12.5 History

The PSTK library has had a long history in the Scheme community and, in one form or another, is available for many Scheme implementations. The current file includes its history starting from an implementation of Chicken/Tk by Wolf-Dieter Busch from 2004 based on earlier code by Sven Hartrumpf from 1997. Nils Holm made the library portable, and so created PSTK. Ken Dickey created an R6RS version. Some links to versions for other Scheme implementations and documentation:

• http://snow.iro.umontreal.ca/?tab=Packages • https://sourceforge.net/projects/pstk/ • http://mirror.informatimago.com/scheme/www.t3x.org/pstk/pstk.html Documentation for R7RS Libraries 47 / 131

Chapter 13

PS/Tk PlotChart: Chart Plotting Library

To use the library: (import (rebottled pstk) (rebottled pstk-plotchart)) The PlotChart library is part of tklib, a library of additional functions to use with Tk. This library provides access from Scheme to (part of) PlotChart. Before using this library, you will need to install tklib. On Linux, tklib can be installed through your standard package manager. For example: sudo apt-get install tklib

Alternatively, download the Tcl sourcecode from a site such as:

• https://core.tcl.tk/tklib/wiki?name=Releases • https://github.com/tcltk/tklib and install by running the Tcl script "installer.tcl". Check your installation by running one of the Tcl example programs. The Tcl documentation available for plotchart is easily converted into Scheme. The following examples illustrate how to use the library, and more examples (some converted from tklib’s examples) are included with r7rs-lib.

13.1 Bar Chart

Bar charts are used to display and compare some measurable quantity of discrete categories of data. One or more series of data may be shown per category, and the series may be shown side-by-side or stacked. The first example shows a single series of data: (import(scheme base) (rebottled pstk) (rebottled pstk-plotchart))

(define tk(tk-start)); 1 (import-plotchart); 2v v (define canvas(tk’create-widget’canvas ’background:’white ’width: 400 ’height: 400))

(define bar-chart(create-bar-chart canvas; 3 v Documentation for R7RS Libraries 48 / 131

’(Venus Earth Mars Pluto); 4 ’(0 6 2); 5v 1)); 6v (bar-chart’plot’mydata ’(0 1 2 5) ’green); 7v (bar-chart’title"Number of Moons"); 8v (bar-chart’legend’mydata"Moons"); 9v v (tk/pack canvas)

(tk-event-loop tk)

1 Start and use Tk in the usual manner. v 2 Plotchart must be imported (this loads the package into Tk). v 3 Create a bar chart on a given canvas. v 4 Define the x-axis labels. v 5 Define the y-axis scale: (minimum maximum label-gap) . v 6 Number of series to plot on the bar chart. v 7 Add a series of data. mydata is the name assigned to the series. The list of numbers give the column sizes. v 8 Set a title to the bar chart. v 9 And a label to the named series, to place in the legend. v

As a second example, three series of data are plotted in a stacked arrangement: Documentation for R7RS Libraries 49 / 131

(define bar-chart(create-bar-chart canvas ’(Q1 Q2 Q3 Q4) ’(0 30 2) ’stacked)); 1 (bar-chart’plot’yr2014 ’(4 2 3 5) ’green) v (bar-chart’plot’yr2015 ’(7 6 3 8) ’red) (bar-chart’plot’yr2016 ’(6 4 7 9) ’blue); 2 (bar-chart’title"Quarterly Sales") v (bar-chart’legend’yr2014"2014") (bar-chart’legend’yr2015"2015") (bar-chart’legend’yr2016"2016"); 3 v

1 stacked is used instead of a count of the number of series. v 2 Data are given for each series separately. v 3 Similarly, a separate identifier is given for the legend. v

13.2 Pie Chart

Pie charts represent a set of values as proportions of a disk. (define pie-chart(create-pie-chart canvas)) (pie-chart’plot’("Earth"1"Mars"2"Jupiter" 53; 1 "Saturn" 53"Uranus" 27"Neptune" 13"Pluto" 5)) v (pie-chart’title"Number of Moons")

1 Data are given in a list where alternate values give the label and count. v Documentation for R7RS Libraries 50 / 131

13.3 XY Plot

An xy-plot is used to display various kinds of data in a 2D arrangement. The first example plots two simple functions: (import(scheme base) (rebottled pstk) (rebottled pstk-plotchart))

(define tk(tk-start)) (import-plotchart)

(define canvas(tk’create-widget’canvas ’background:’white ’width: 400 ’height: 400))

(define graph(create-xy-plot canvas; 1 ’(-10 10 2) v ’(-100 100 20))) ;; label the graph and axes (graph’title"Two Functions") (graph’xtext"inputx") (graph’ytext"outputy") ;; colour the two lines (graph’dataconfig"square"’colour:’blue) (graph’dataconfig"cube"’colour:’green) ;; line labels in the legend (graph’legendconfig’position:’bottom-right); 2 (graph’legend"square""x *x"); 3v v Documentation for R7RS Libraries 51 / 131

(graph’legend"cube""x *x*x") ;; add data (do((i -10 (+i 0.1))) ((>i 10) ) (graph’plot"square"i(squarei)); 4 (graph’plot"cube"i( * iii))) v (tk/pack canvas)

(tk-event-loop tk)

1 When creating the xy-plot, the ranges and tick spacing of the x and y axes are defined. v 2 Sets the position of the legend: this must be done first v 3 Sets the text to use for the legend for this series. v 4 (x y) values are plotted in turn for each series. v

The second example illustrates a scatter plot with a trend line: (define tk(tk-start)) (import-plotchart)

(define canvas(tk’create-widget’canvas ’background:’white ’width: 400 ’height: 400))

(define graph(create-xy-plot canvas ’(0 20000 4000) Documentation for R7RS Libraries 52 / 131

’(0 100 20))) ;; label the graph and axes (graph’title"Crater Diameter vs Depth") (graph’xtext"Depth(feet)") (graph’ytext"Diameter(miles)") ;; (graph’dataconfig"values"’type:’symbol’symbol:’upfilled’colour:"blue"); 1 (graph’dataconfig"relation"’colour:"green") v ;; add data (for-each(lambda(pair) (graph’plot"values"(car pair)(cdr pair)) (graph’trend"relation"(car pair)(cdr pair))); 2 ’((14500 . 81) (2000 . 2) (10500 . 73) (7000 . 51) (16000 . 77))) v (tk/pack canvas)

;; finally save the plot (graph’saveplot"craters.ps"); 3 v (tk-event-loop tk)

1 The type can be line symbol or none for lines/symbols/nothing to be drawn for the series. v 2 The trend command records the datavalues and draws a line indicating the trend of the data. v 3 A copy of any plot can be saved as a postscript file, but call this after the canvas has been packed. v Documentation for R7RS Libraries 53 / 131

Chapter 14

SLIB Introduction and Miscellaneous Libraries

SLIB is a collection of packages of Scheme code, mostly written by Aubrey Jaffer, but some collected from other sources. Looking through the files, some of the original dates go back to 1991, and the precedence parser into 1989. A number of ideas now found in Scheme and captured in the SRFIs can be traced back to SLIB. The repackaged files in r7rs-libs have been adapted to work with R7RS Scheme implementations: using R7RS functionality, the library system, and operations now found in SRFIs. SLIB’s official documentation is available at http://people.csail.mit.edu/jaffer/slib and is still applicable, with some minor adjust- ments, to the version provided here. There are 91 libraries within the R7RS SLIB collection. These fall within four main groups of functionality:

1. Textual Conversion Packages, including a parser, I/O routines, html and xml processing, pretty-printing of Scheme objects, and procedures to handle times and dates. 2. Mathematical Libraries, including prime numbers, some random number distributions, plotting functions (to text and eps), root/limit finding libraries and a 3D modelling suite.

3. Database Packages, which implement a relational database system, and a library for weighted trees. 4. Other Packages

a. Data Structures: for enhancing arrays, working with pnm files, an object system and queues. b. Sorting and Searching: trees, chapter-order, topological sort, along with some space filling curves and sequence comparisons. c. Other Procedures: a library of metric units for computing conversions.

The github page for r7rs-libs and the wiki, https://github.com/petercrlane/r7rs-libs/wiki, provide additional information about SLIB and its conversion for use as R7RS libraries. The "examples" and "tests" directories provide (some) examples of using SLIB. Limited documentation for some of the libraries follows. This section introduces some of the smaller libraries in the SLIB collection. The following chapters go into some of the libraries into more depth, especially those libraries related with a common theme such as array handling or time.

14.1 Charplot: (import (slib charplot))

This library provides a way to quickly visualise some data in graphical or histogram form from the REPL or command-line interface. There are two basic functions: histograph and plot, the latter drawing graphs of data or functions. Documentation for R7RS Libraries 54 / 131

14.1.1 charplot:dimensions

This parameter allows you to change the size of display. The dimensions are a two-valued list: the height and width in characters. Example below.

14.1.2 histograph histograph is used to plot histograms of numeric data. Given a list or vector of numbers, it will arrange them into a suitable set of bins and display: > (histograph ’(1 1 2 3 5 5 5 7 8 9) "sample") ______| | | | 3|-I| |I| |I| 2.5|-I| |I| |I| 2|-II| |II| |II| 1.5|-II| |II| |II| 1|-IIIIIII| |IIIIIII| |IIIIIII| 0.5|-IIIIIII| |IIIIIII| |IIIIIII| 0|-IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII------| |._____:_____._____:_____._____:_____._____:_____._____:_____.___| sample 2 4 6 8 10

> (charplot:dimensions ’(10 50)) > (histograph ’(1 1 2 3 5 5 5 7 8 9) "sample") ______3|-I| |I| 2|-II| |II| 1|-IIIIIII| |IIIIIII| 0|-IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII--| |_.____:____.____:____.____:____.___| sample 2.5 5 7.5 >

14.1.3 plot plot can be used in two ways: to display a function, or to display some data. Plotting a function plot will plot the values of a single argument function (taking and returning a number). The function should be given as the first argument. The second and third arguments specify the range of x values over which to plot the graph - be careful of infinite values from your function, which will crash plot. An optional fourth argument specifies how many points to plot along the range of x values. Documentation for R7RS Libraries 55 / 131

> (plot(lambda(x)( * xxx)) -5 5) ______140|- : | | : | 120|- : * | | : * | 100|- : * | | : * | 80|- : * | | : ** | 60|- : * | | : ** | 40|- : * | | : *** | 20|- : ** | | *** : ***** | 0|------*********************------| | ** : | -20|- ** : | | *** : | -40|- * : | | ** : | -60|- * : | | ** : | -80|- * : | | * : | -100|- * : | | * : | -120|-* : | |_._____:_____._____:_____._____:_____._____:_____._____:_____.___| -4 -2 0 2 4

> (plot(lambda(x)( * xxx)) -5 5 30) ______140|- : | | : | 120|- : * | | : | 100|- : * | | : | 80|- : * | | : | 60|- : * | | : * | 40|- : * | | : * | 20|- : * | | * : ** | 0|------*-*-*-*-*:*-*-*-*-*------| | * : | -20|- * : | | * : | -40|- * : | | * : | -60|- * : | | : | -80|- * : | | : | -100|- * : | | : | -120|-* : | Documentation for R7RS Libraries 56 / 131

|_._____:_____._____:_____._____:_____._____:_____._____:_____.___| -4 -2 0 2 4

Plotting some data This second form of plot directly plots a list or vector of pairs of (x, y) coordinates. Second and third arguments give labels to the two axes.

> (define data(map(lambda(x)(listx( * xxx))) (iota 11 -5))) > data ((-5 -125) (-4 -64) (-3 -27) (-2 -8) (-1 -1) (0 0) (1 1) (2 8) (3 27) (4 64) (5 125)) > (plot data"x-values""y-values") y-values ______140|- : | | : | 120|- : * | | : | 100|- : | | : | 80|- : | | : | 60|- : * | | : | 40|- : | | : * | 20|- : | | * : * | 0|------*-----*-----*------| | : | -20|- : | | * : | -40|- : | | : | -60|- * : | | : | -80|- : | | : | -100|- : | | : | -120|-* : | |_._____:_____._____:_____._____:_____._____:_____._____:_____.___| x-values -4 -2 0 2 4

14.2 Database

SLIB includes a relational database system, written entirely in Scheme. This is a complex and inter-related set of libraries. The following example (from "slib-examples/db-1.sps") provides an introduction to creating, opening and using a simple database.

Note The database system stores information in files. It also sets up locks on those files to prevent multiple users trying to change the same data. The code has been tested under Linux, but requires further tests and possible modification on other operating systems. If your application fails with any errors, it is possible the lock files will remain and must be deleted before you can access the database again: the lock files start ".$" and ".#", and are thus hidden on Linux and similar systems.

More information on SLIB’s database system is available at: http://people.csail.mit.edu/jaffer/slib/Using-Databases.html. After understanding the example below, work through section 6.1.2 on Table Operations. Documentation for R7RS Libraries 57 / 131

14.2.1 Creating a database

A database can be created using one or more "backends". Currently, only an association list backend is supported, as provided by (slib alist-table). A database is created to a given filename: (import(scheme base) (slib databases) (slib alist-table))

(define db(create-database"mydb"’alist-table))

The above code imports the necessary libraries, and creates a database in the file "mydb" using an association-list backend. A reference to this database is stored in db. Next, the database can be opened: (define rdb(open-database! db))

As we will see below, a database can be opened using either the database reference from the create-database command, or from the filename. So (open-database! "mydb") works just as well. Databases can be opened in mutable or immutable modes: opened to be changed, or just for reading. The exclamation mark ! indicates that the database is mutable. Data in a database is stored within tables. Before we can use our new database, we need to create at least one table. A table is defined from three elements:

1. its name 2. its primary key field(s) 3. its other fields

In our example, we make an example with name "testit", a single primary key "id", and two fields "first" and "second". Each field is defined with an associated type (allowed types are described in the online documentation). In this case, our "id" field will be a number, and the two other fields strings. The basic definition is: (testit; the table name ((id number)) ; list of primary key field(name type) pairs ((first string)(second string))) ; list of other field(name type) pairs

When defining a table, we can also provide a list of data to add. The data are simply given in rows, with values for all fields: ((1 "Peter""Lane") ; row 1: (id first second) (2 "Joe""Smith")) ; row 2: (id first second)

Putting the definitions together, the following line of code creates the testit table, and adds some initial data: (define-tables rdb’(testit((id number)) ((first string)(second string)) ((1"Peter""Lane") (2"Joe""Smith"))))

Finally, don’t forget to close the database, which ensures everything is saved on disk: (close-database rdb)

You can examine the file "mydb" to read the definition and data. Documentation for R7RS Libraries 58 / 131

14.2.2 Working with a database

Databases should only need constructing once. Afterwards, you will open and work with the existing file. To open an existing database, you need to know its filename: (define mydb(open-database!"mydb")); opena mutable database

To access information in a table, you need to extract the table of interest: (define table(open-table! mydb’testit))

If you were to examine table, you would find it is a procedure. The table procedure takes an operation definition as its argument, and returns a new procedure to perform that operation on some data. For example, if we wish to retrieve a row of data. The operation definition is ’row:retrieve. The returned procedure then takes the primary key(s) to locate in the database: ((table’row:retrieve) 1); returns the row with id 1: (1"Peter""Lane")

Try displaying all rows (note, the third case will return #f): (display"Retrieving 1:")(display((table’row:retrieve) 1)) (newline) (display"Retrieving 2:")(display((table’row:retrieve) 2)) (newline) (display"Retrieving 3:")(display((table’row:retrieve) 3)) (newline)

A new row can be inserted in a similar way: ((table’row:insert) ’(3"Jane""Wheeler"))

Further row operations exist to update and delete. Operations are also available to work on multiple rows. A useful case is for-each-row: ((table’for-each-row)(lambda(row)(display"Row:")(display row)(newline)))

Finally, don’t forget to close the database, which ensures everything is saved on disk: (close-database mydb)

14.3 Dynamic: (import (slib dynamic))

Provides a kind of name-value store, which can be accessed globally. (This is essentially the same as R7RS parameters, with a different syntax.) make-dynamic creates a dynamic object wrapping a given object. dynamic? returns true only if the given object is a dynamic. dynamic-ref returns the value of a given dynamic object. dynamic-set! changes the value of the given dynamic object. call-with-dynamic-binding temporarily rebinds a given dynamic object to a new value within the given procedure.

(let((x(make-dynamic’a)); 1 (y(make-dynamic’b))) v (dynamic?x); 2 (eq?’a(dynamic-refx)); 3v (eq?’b(dynamic-refy)) v (dynamic-set!x’c); 4 (call-with-dynamic-bindingx’d; 5v (lambda()(eq?’d(dynamic-refx)))) v (eq?’c(dynamic-refx))); 6 v Documentation for R7RS Libraries 59 / 131

1 Names x as the dynamic object with value ’a v 2 Returns #t as x is a dynamic object v 3 Retrieves the value of the given dynamic object, and checks it is correct v 4 Changes the value of the given dynamic object v 5 Within the lambda x is now bound to ’d v 6 and x reverts to holding ’c after the call v 14.4 Format: (import (slib format))

This library provides an almost complete implementation of ’s format function. The format string syntax is complex. Good descriptions are:

• SLIB’s documentation: http://people.csail.mit.edu/jaffer/slib/Format.html

• in Peter Seibel’s : http://www.gigamonkeys.com/book/a-few-format-recipes.html • in Guy Steele’s Common Lisp: The Language, 2nd edition: https://www.cs.cmu.edu/Groups/AI/util/html/cltl/clm/node200.html

14.5 Soundex: (import (slib soundex))

This implementation of the Russell Soundex algorithm is based on Knuth, Vol. 3 "Sorting and searching", pp.391-2: note, reexported by (robin text) The soundex algorithm returns a code for a word, and equivalent sounding words should return equivalent codes: > (soundex"pair") "P600" > (soundex"pare") "P600" > (soundex"rabbit") "R130" > (soundex"racket") "R230" > (soundex"smith") "S530" > (soundex"smythe") "S530"

14.6 SSAX XML Parser: (import (slib xml-parse))

This SLIB library exposes various levels of the XML parsing process. For more details, see http://people.csail.mit.edu/jaffer/slib/Parsing-XML.html#Parsing-XML More information on SSAX parsing is available at http://ssax.sourceforge.net/ The main top-level function is ssax:xml→sxml. This takes two arguments: an input port, and an (optionally empty) associa- tion list of namespace prefixes to URIs. The function returns an s-expression containing the contents of the XML document read from the input port. Documentation for R7RS Libraries 60 / 131

#|kawa:2|# (|ssax:xml->sxml| (open-input-string"content") ’()) (*TOP* (tag content)) #|kawa:3|#(define *str* "Peter1234") #|kawa:4|# (|ssax:xml->sxml| (open-input-string *str*) ’()) (*TOP* (person(@(gender male)) (name Peter)(number 1234)))

(The vertical bars around the function calls are sometimes required in Kawa.) Notice the XML strings are converted to s-expressions. Attributes are marked "@". All values are strings.

14.7 URIs: (import (slib uri))

A package for creating, decoding and testing various forms of URI.

14.7.1 absolute-path absolute-path? returns true if the given filename is an absolute path, or false if it depends on the current directory. > (absolute-path?"/usr/local/bin/scheme") #t > (absolute-path?"../filename") #f

14.7.2 absolute-uri? absolute-uri? returns true if the given uri is an absolute uri (containing a complete description of the named resource), or false otherwise. > (absolute-uri?"ftp://example.org/resource.txt") #t > (absolute-uri?"resource.txt") #f

14.7.3 glob-pattern? glob-pattern? returns true if the given string contains any symbol typically used in a glob, i.e. * ? [ ]

> (glob-pattern?"/home/dir/ */file.txt") #t > (glob-pattern?"/home/dir/x/file?.txt") #t > (glob-pattern?"/home/dir/x/fil[e].txt") #t > (glob-pattern?"/home/dir/x/file.txt") #f

14.7.4 html syntax

The following four functions generate html text for different purposes:

• html:anchor creates a named location given a name as a string. Documentation for R7RS Libraries 61 / 131

• html:base returns a string representing the base of given uri. • html:isindex creates a string for a search prompt (now deprecated for html forms). • html:link takes a uri and title, and returns a link to uri displaying the title.

> (html:anchor"location");; 1 v > (html:base"http:peterlane.info") > (html:isindex"Search term:") > (html:link"http://peterlane.info""home page") home page

1 Use "" to link back to this location. v 14.7.5 make-uri make-uri constructs a URI given from 0 to 5 arguments. These are: scheme, authority, path, query, fragment. These are optional from the front, so a single argument will be treated as the fragment; two arguments as a query and then a fragment, etc.

> (make-uri) ; 1 v > (make-uri"xyz"); 2 #xyz v > (make-uri"query""xyz"); 3 ?query#xyz v > (make-uri"http""peterlane.info""/files/location""query""xyz"); 4 http://peterlane.info/files/location?query#xyz v

1 Returns the empty string v 2 Single argument is a Fragment v 3 Query and Fragment v 4 All components: the authority in this case is the web address, and the path the relative location of files v 14.7.6 null-directory? null-directory? takes a string and returns true if the string names the current directory (so changing to it would not make any change).

14.7.7 parse-ftp-address parse-ftp-address converts a string, representing an ftp address, into a list of up to four values: the username, password, remote site, and remote directory. #f is returned if any of these values is not present, or #f instead of a list if the string is not an ftp address. > (parse-ftp-address"ftp://[email protected]/") ("username"#f"ftp.someplace.site"#f) > (parse-ftp-address"ftp://username:[email protected]/dir") ("username""password""ftp.someplace.site""dir") Documentation for R7RS Libraries 62 / 131

14.7.8 path→uri path→uri converts a given path (as a string) into a URI with an absolute address. > (path->uri"filename.txt") file:/home/NAME/CURRENT-DIRECTORY/filename.txt > (path->uri"/usr/local/filename.txt") file:/usr/local/filename.txt

14.7.9 uri→tree uri→tree takes a URI and returns a list of five values corresponding to the scheme, authority, path, query, fragment: > (uri->tree"file:/usr/local/filename.txt") (file#f("""usr""local""filename.txt")#f#f)

14.7.10 uri:decode-query uri:decode-query converts a given query string into an association list of key-value pairs: > (uri:decode-query"name=XXX&date=32") ((date"32")(name"XXX"))

14.7.11 uri:make-path uri:make-path takes a list of strings, and returns a path component by joining the strings together with a suitable separator: > (uri:make-path’("a""b""c")) "a/b/c"

14.7.12 uri:splitfields uri:splitfields splits a string at a given character. > (uri:splitfields"some text to split"#\space) ’("some""text""to""split")

14.7.13 uric:decode/encode uric:decode and uric:encode convert a string to and from a form with certain characters rewritten using % octal values: > (uric:decode"xxx%20yyy") "xxx yyy" > (uric:encode"xxx yyy") "xxx%20yyy"

An optional second argument to uric:encode provides a string of characters to allow. Documentation for R7RS Libraries 63 / 131

Chapter 15

SLIB Common: (import (slib common))

This library contains some core functions required throughout the SLIB collection. Apart from (slib:version) users of SLIB probably do not need to call these functions.

15.1 add-base-table-implementation

Internal support for database library: adds a supported base implementation to the list of such implementations.

15.2 base-table-implementations

Internal support for database library: contains a list of supported base implementations.

15.3 call-with-open-ports http://people.csail.mit.edu/jaffer/slib/Input_002fOutput.html#index-call_002dwith_002dopen_002dports-89

15.4 char-code-limit

A constant 256: One greater than the largest integer which can be returned by char→integer

15.5 gentemp

Returns a new symbol.

15.6 identity

A single-parameter identity function.

15.7 make-exchanger

Provides mutually exclusive access to its resource: when called, it returns its current content replacing it with its argument. http://people.csail.mit.edu/jaffer/slib/Miscellany.html#index-make_002dexchanger-114 Documentation for R7RS Libraries 64 / 131

15.8 most-positive-fixnum

Constant #xFFFFFFFF

15.9 open-file

A general method to open a port to read or write.

15.10 output-port-height

A constant 24: default display height (used e.g. in char-plot)

15.11 output-port-width

A constant 79: default display width (used e.g. in char-plot)

15.12 provided?

Checks if features, such as big integers, are supported by the current implementation.

15.13 slib:version

Returns the current version SLIB.

15.14 slib:warn

Displays a warning to the current-error-port before proceeding.

15.15 software-type

Returns a symbol indicating the generic operating system type: the choice of possible return types has been reduced for R7RS to ’windows, ’posix or ’unix.

15.16 system

Calls the operating system.

15.17 tmpnam

A unique string name, used for temporary files. Documentation for R7RS Libraries 65 / 131

15.18 with-load-pathname

Takes a path and a thunk, evaluates thunk with an internal variable bound to the path. http://people.csail.mit.edu/jaffer/slib/Vicinity.html#index-with_002dload_002dpathname-74 Documentation for R7RS Libraries 66 / 131

Chapter 16

SLIB Array Libraries

SLIB provides a number of libraries for defining and working with arrays. The array type used is SRFI 63, which was originally a package in SLIB. SRFI 63 provides functions to create, modify and examine arrays. The collection includes:

• array-for-each: Functions for applying functions to arrays. • array-interpolate: Functions to reduce/resample arrays. • byte: A library for arrays of small integers (although R7RS includes bytevector, several libraries in SLIB make use of byte). • determinant: A number of standard matrix-algebra functions. • subarray: Functions to reduce or access sub-arrays.

16.1 SRFI 63: (import (srfi 63))

SLIB uses the array data type from SRFI 63. This section covers some simple examples to illustrate basic use of the array data type. For more details, refer to the SLIB documentation: http://people.csail.mit.edu/jaffer/slib/Arrays.html

Note When using (srfi 63) you must not export equal? from (scheme base). There are two basic ways of creating arrays:

1. an empty array, using make-array 2. an array with pre-determined content:

a. using list→array, or b. using vector→array

An empty array is constructed from a prototype, which is the initial value in a given array, vector or string; an empty prototype will leave the initial value unspecified. Following the prototype are the dimensions of the array. For example, to construct a 3x2 array filled with 0:

#|kawa:65|#(definea(make-array #(0) 3 2)); 1 #|kawa:66|#a v srfi.63$array@7e6f74c #|kawa:68|#(array->lista); 2 ((0 0) (0 0) (0 0)); 3v v Documentation for R7RS Libraries 67 / 131

1 The prototype #(0) is used to fill the array with 0s. v 2 array→list is provided to convert our array into a list-of-lists form. v 3 We end up with 3 rows, each of size two, filled with 0s. v To construct an array with pre-determined content from a list of lists: list→array must also be given the "rank" (number of dimensions) of the array and, as above, a prototype.

#|kawa:71|#(defineb(list->array 2 #(0) ’((1 2) (3 4) (5 6)))); 1 #|kawa:72|#b v srfi.63$array@bcec361 #|kawa:73|#(array->listb) ((1 2) (3 4) (5 6))

1 Constructs an array of rank 2, with 0 as the prototype, and the given values v To construct an array with pre-determined content from a vector. The input vector is simply a vector of the values. The second argument is the prototype, as above. The remaining arguments give the required dimensions of the array. #|kawa:92|#(definec(vector->array #(1 2 3 4 5 6 7 8 9 10 11 12) #(0) 3 4)) #|kawa:93|#(array->listc) ((1 2 3 4) (5 6 7 8) (9 10 11 12)) #|kawa:94|#(array->vectorc); 1 #(1 2 3 4 5 6 7 8 9 10 11 12) v #|kawa:95|#(definec(vector->array #(1 2 3 4 5 6 7 8 9 10 11 12) #(0) 2 3 2)) #|kawa:96|#(array->listc) (((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12)))

1 array→vector is an alternative way to retrieve the elements of an array, this time into a vector in row-major order. v Access elements in an array using array-ref and array-set!: #|kawa:75|#(array->lista) ((0 0) (0 0) (0 0)) #|kawa:78|#(array-refa 2 1); 1 0 v #|kawa:79|#(array-set!a’x 2 1) #|kawa:80|#(array-refa 2 1) x #|kawa:81|#(array->lista) ((0 0) (0 0) (0x))

1 Note order of indexes is the same as in make-array v Information about the array can be found using array-rank to find the number of dimensions of an array, array-dimensions to return a list of the dimensions, and array-in-bounds? returns true if its indices are valid for the given array: #|kawa:82|#(array-ranka) 2 #|kawa:83|#(array-dimensionsa) (3 2) #|kawa:84|#(array-in-bounds?a 2 1) #t #|kawa:85|#(array-in-bounds?a 1 2) #f

Finally, array? is used to tell if an object is of this array type or not, and equal? is extended to test if two arrays are equal. Documentation for R7RS Libraries 68 / 131

#|kawa:86|#(array? 2) #f #|kawa:87|#(array?a) #t #|kawa:88|#(array->lista) ((0 0) (0 0) (0x)) #|kawa:89|#(equal?a 2) #f #|kawa:90|#(equal?a ’((0 0) (0 0) (0x))) #f #|kawa:91|#(equal?a(list->array 2 #(0) ’((0 0) (0 0) (0x)))) #t

The following libraries provide more functionality when working with arrays.

16.2 Array Mapping: (import (slib array-for-each))

This library provides implementations of for-each and map for arrays, as well as functions to work on the indices of an array.

16.2.1 array-for-each array-for-each takes a procedure and one or more arrays. The procedure is applied to the equivalent elements of each array in row-major order. The example below simply displays each element in the given array and returns #t. sash[r7rs]> (definex(list->array 2 #() ’((1 2) (3 4)))) # sash[r7rs]> (array-for-each displayx) 1234#t

16.2.2 array-indexes array-indexes takes an array as an argument and returns a new array of the same dimensions with lists of indexes in each element position. sash[r7rs]> (definex(list->array 2 #() ’((1 2) (3 4)))) # sash[r7rs]> (array-indexesx) #< 0x2b52960> sash[r7rs]> (matrix->lists(array-indexesx)) (((0 0) (0 1)) ((1 0) (1 1)))

16.2.3 array-index-for-each array-index-for-each takes an array and a procedure and applies the procedure to the indices of each element in the array. sash[r7rs]> (definex(list->array 2 #() ’((1 2) (3 4)))) # sash[r7rs]> (array-index-for-eachx(lambda args(map display args))) 11011000#t

Notice the order of application is not specified. Documentation for R7RS Libraries 69 / 131

16.2.4 array-index-map! array-index-map! takes an array and a procedure and applies the procedure to the indices of each element in the array storing the return value in the corresponding element of the array. sash[r7rs]> (definea(vector 0 0 0)) # sash[r7rs]>a #(0 0 0) sash[r7rs]> (array-index-map!a(lambda args(apply+ args))) #t sash[r7rs]>a #(0 1 2)

In this case, the original array a has the sum of its indices placed into its elements.

16.2.5 array-map! array-map! takes a result array, a procedure and one or more source arrays. The procedure is applied to the equivalent elements of each source array in row-major order. The return values of the procedure are placed into the respective element of the result array. In the example below x is used as both the result array and the first source array. sash[r7rs]> (definex(list->array 2 #() ’((1 2) (3 4)))) # sash[r7rs]> (definey(list->array 2 #() ’((5 6) (7 8)))) # sash[r7rs]> (array-map!x+xy) #t sash[r7rs]> (matrix->listsx); 1 ((6 8) (10 12)) v

1 matrix→lists is from (slib determinant) v 16.2.6 array-map array-map takes an array prototype, a procedure and one or more arrays. The procedure is applied to the equivalent elements of each array in row-major order. The return values of the procedure are placed into the respective element of a new array built using the type of the given prototype. sash[r7rs]> (definex(list->array 2 #() ’((1 2) (3 4)))) # sash[r7rs]> (definey(list->array 2 #() ’((5 6) (7 8)))) # sash[r7rs]> (matrix->lists(array-map #() +xy)); 1 ((6 8) (10 12)) v

1 matrix→lists is from (slib determinant) v 16.2.7 array:copy! array:copy! copies the elements of the second vector or array into the corresponding positions of the first vector or array; the destination must be at least as large as the source in each dimension. Documentation for R7RS Libraries 70 / 131

sash[r7rs]> (definev(vector 1 2 3)) # sash[r7rs]> (definew(vector 4 5 6)) # sash[r7rs]>v #(1 2 3) sash[r7rs]> (array:copy!vw) #t sash[r7rs]>v #(4 5 6)

16.3 Array Interpolation: (import (slib array-interpolate))

This library provides two functions to obtain interpolated values or arrays formed from interpolated values of a source array.

16.3.1 interpolate-array-ref interpolate-array-ref takes an array and a sequence of index positions as real numbers. This is very similar to array-ref, however the index positions need not be integers and so define a point within the array. The function returns an interpolated value based on the coordinates nearest to that point. For example: > (define arr(list->array 2 #() ’((1 2 3) (4 5 6)))) > (interpolate-array-ref arr 1 0.1) 4.1

The call to interpolate-array-ref selects the row of index 1, which is (4 5 6), and position 0.1 within that row. The value returned is (+ (* 0.9 4) (* 0.1 5)) = 4.1, the intermediate value between 4 and 5 lying a tenth of the way from 4. Similarly: > (define arr(list->array 2 #() ’((1 2 3) (4 5 6)))) > (interpolate-array-ref arr 0.5 0.25) 2.75

The first index is mid-way between rows index 0 and index 1, and the second index is between the columns index 0 and index 1. The interpolated value is calculated as:

1. (+ (* 0.75 4) (* 0.25 5)) = 4.25, a quarter of the way between the 4 and 5 (columns 0 and 1 in row 1) 2. (+ (* 0.75 1) (* 0.25 2)) = 1.25, a quarter of the way between the 1 and 2 (columns 0 and 1 in row 2) 3. (+ (* 0.5 4.25) (* 0.5 1.25)) = 2.75, midway between these two values (rows 1 and 2)

16.3.2 resample-array! resample-array! takes two arrays of equal rank but unequal dimension. The first array is filled with values formed by interpolating its values from the second array. > (define arr1(list->array 2 #() ’((1 2 3 4) (5 6 7 8)))) > (define arr2(make-array #() 2 3)) > (array->list arr2) ((0 0 0) (0 0 0)) > (resample-array! arr2 arr1) > (array->list arr2) ((1 5/2 4) (5 13/2 8)) Documentation for R7RS Libraries 71 / 131

The interpolation process retains the outer corners. So arr2 preserves the 1, 4, 5 and 8 in its corners. The value of 5/2 in the first row is obtained from the middle value of the first row, computed as: (interpolate-array-ref arr1 0 1.5)

16.4 Determinant: (import (slib determinant))

This library is a little misnamed. Apart from determinants, it also provides a range of functions on single and pairs of arrays, here treating the arrays as matrices. All the functions take either a SRFI-63 array or a list of lists as the matrix definition.

16.4.1 determinant determinant returns the determinant of a given matrix. sash[r7rs]> (determinant ’((1 2) (3 4))) -2

16.4.2 matrix→array matrix→array returns a SRFI-63 array from given matrix definition (e.g. list-of-lists): sash[r7rs]> (matrix->array ’((1 2) (3 4))) #< 0x2a6a400>

16.4.3 matrix→lists matrix→lists converts a given matrix definition into a list of lists: sash[r7rs]> (matrix->lists(matrix->array ’((1 2) (3 4)))) ((1 2) (3 4)) sash[r7rs]> (matrix->lists ’((1 2) (3 4))) ((1 2) (3 4))

16.4.4 matrix:difference matrix:difference takes two matrices of numbers and returns their element-wise difference. If the matrices are not of equal dimension, returns a matrix of the smallest size. sash[r7rs]> (matrix:difference ’((1 2) (3 4)) ’((5 6) (7 8))) ((-4 -4) (-4 -4)) sash[r7rs]> (matrix:difference ’((1 2) (3 4)) ’((5 6 7) (8 9 10))) ((-4 -4) (-5 -5))

16.4.5 matrix:inverse matrix:inverse returns the inverse of a given square matrix. If the matrix is singular, the function returns #f. sash[r7rs]> (matrix:inverse ’((1 2) (3 4))) ((-2 1) (3/2 -1/2)) sash[r7rs]> (matrix:inverse ’((0 0) (0 0))) #f Documentation for R7RS Libraries 72 / 131

16.4.6 matrix:product matrix:product takes two arguments, at least one of which must be a matrix. If the other argument is a scalar, returns the element-wise product of the scalar with the matrix. If the other argument is a matrix, returns the matrix product. sash[r7rs]> (matrix:product ’((1 2) (3 4)) ’((5 6) (7 8))) ((19 22) (43 50)) sash[r7rs]> (matrix:product ’((1 2) (3 4)) 2) ((2 4) (6 8)) sash[r7rs]> (matrix:product 2 ’((1 2) (3 4))) ((2 4) (6 8))

16.4.7 matrix:sum matrix:sum takes two matrices of numbers and returns their element-wise sum. If the matrices are not of equal dimension, returns a matrix of the smallest size. sash[r7rs]> (matrix:sum ’((1 2) (3 4)) ’((5 6) (7 8))) ((6 8) (10 12)) sash[r7rs]> (matrix:sum ’((1 2 3) (4 5 6)) ’((7 8) (9 10))) ((8 10) (13 15))

16.4.8 transpose transpose returns a copy of the given matrix with entries flipped about the diagonal. sash[r7rs]> (transpose ’((1 2 3) (4 5 6) (7 8 9))) ((1 4 7) (2 5 8) (3 6 9))

16.5 Subarray: (import (slib subarray))

The subarray library is used to identify smaller components of arrays. The returned array shares storage with the original, so a copy should be made if required.

16.5.1 array-trim array-trim is a simplified version of subarray. Its first argument should be a vector or array. The following arguments, one per dimension of the array, indicate how much to remove from one or other end. Positive values take from the "left", low-index, side and negative values from the "right", high-index side. #|kawa:46|#(definea(list->array 2 #() ’((1 2 3) (4 5 6) (7 8 9)))) #|kawa:47|#(array->list(array-trima 1 0)); 1 ((4 5 6) (7 8 9)) v #|kawa:48|#(array->list(array-trima 0 1)); 2 ((2 3) (5 6) (8 9)) v #|kawa:49|#(array->list(array-trima 2 -1)); 3 ((7 8)) v

1 Trim the first row v 2 Trim the first column v 3 Trim the first two rows and last column v As with subarray, the trimmed array shares storage with the source array. Documentation for R7RS Libraries 73 / 131

16.5.2 subarray subarray precisely selects contiguous subsets of a given array. Its first argument should be an array. There follow one argument per dimension of the array. Each argument is either:

• an integer: selecting that index of the given dimension • a pair of integers: selecting that range of indices in the given dimension • #f: making no selection, and so that dimension is not altered.

If there are less arguments than dimensions, the remainder are treated as #f. #|kawa:4|#(definea(list->array 2 #() ’((1 2 3) (4 5 6) (7 8 9)))) #|kawa:11|#(array->list(subarraya1#f)); 1 (4 5 6) v #|kawa:12|#(array->list(subarraya#f 1)); 2 (2 5 8) v #|kawa:14|#(array->list(subarraya#f ’(0 1))); 3 ((1 2) (4 5) (7 8)) v #|kawa:15|#(array->list(subarraya ’(1 0) #f)); 4 ((4 5 6) (1 2 3)) v #|kawa:17|#(array->list(subarraya ’(2 1) ’(0 1))); 5 ((7 8) (4 5)) v

1 Selects a single row in the array: the second row v 2 Selects a single column in the array: the second column v 3 Selects the first and second columns v 4 Selects the last two rows, but in reverse order v 5 Selects the last two rows in reverse, and the first two columns v Although the arrays are shared, information is reported as appropriate: #|kawa:18|#(defineb(subarraya ’(2 1) ’(0 1))) #|kawa:19|#(array-dimensionsa) (3 3) #|kawa:20|#(array-dimensionsb) (2 2) #|kawa:21|#(array-rankb) 2 #|kawa:25|#(array-set!b’X 0 0) #|kawa:26|#(array->lista); 1 ((1 2 3) (4 5 6) (X 8 9)) v #|kawa:27|#(array->listb) ((X 8) (4 5))

1 The source array, a, has also been changed in the appropriate place v There is no array-copy function in SLIB. The following can be used:

#|kawa:39|#(definec(array-map #() identityb)); 1 #|kawa:40|#(array->listc) v ((X 8) (4 5)) #|kawa:42|#(array-set!c’y 1 1) #|kawa:43|#(array->listc); 2 ((X 8) (4y)) v Documentation for R7RS Libraries 74 / 131

#|kawa:44|#(array->lista); 3 ((1 2 3) (4 5 6) (X 8 9)) v #|kawa:45|#(array->listb) ((X 8) (4 5))

1 array-map from (slib array-for-each), identity from (slib common) v 2 c is updated v 3 a and b are not updated, as c is no longer shared v Documentation for R7RS Libraries 75 / 131

Chapter 17

SLIB Colour Libraries

SLIB includes a number of libraries for defining, storing and manipulating colours.

• color: defines a datatype for colours • color-name: a framework to store/retrieve colour names in SLIB’s database implementation • color-space: conversions in colour spaces • daylight: models the sun and sky colours • nbs-iscc: mapping of colour names to colours • resene: mapping of colour names to colours • saturate: mapping of colour names to colours

The following are good references for:

• an overview of these libraries: http://people.csail.mit.edu/jaffer/Color/Color-Scheme • more about colours and their names: http://people.csail.mit.edu/jaffer/Color/

17.1 NBS/ISCC Colour System: (import (slib nbs-iscc))

This library provides a mapping of colour names to colour values (as defined in (slib color)) based on the NBS/ISCC colour system. For more information see http://tx4.us/nbs-iscc.htm Two functions are provided:

1. nbs-iscc-names returns a list of all the names 2. nbs-iscc returns the named colour sash[r7rs]> (length(nbs-iscc-names)) 267 sash[r7rs]> (list-ref(nbs-iscc-names) 0) "vivid yellowish green" sash[r7rs]> (list-ref(nbs-iscc-names) 100) "vivid purplish red" sash[r7rs]> (nbs-iscc"vivid yellowish green") #< 0x2f629a0> sash[r7rs]> (color->string(nbs-iscc"vivid yellowish green")); 1 v Documentation for R7RS Libraries 76 / 131

"sRGB:39/166/76" sash[r7rs]> (nbs-iscc(list-ref(nbs-iscc-names) 100)) #< 0x226a900> sash[r7rs]> (color->string(nbs-iscc(list-ref(nbs-iscc-names) 100))) "sRGB:206/70/118" sash[r7rs]> (nbs-iscc"rnd"); 2 #f v

1 color→string is available from the (slib color) library v 2 nbs-iscc returns #f if the name is not recognised v 17.2 Resene Colour System: (import (slib resene))

This library provides a mapping of colour names to colour values (as defined in (slib color)) based on the Resene colour system. For more information see http://www.resene.co.nz Two functions are provided:

1. resene-names returns a list of all the names 2. resene returns the named colour sash[r7rs]> (import(slib resene)) # sash[r7rs]> (length(resene-names)) 1379 sash[r7rs]> (list-ref(resene-names) 0) "mantis" sash[r7rs]> (list-ref(resene-names) 100) "st tropaz" sash[r7rs]> (resene"mantis") #< 0x2d78ea0> sash[r7rs]> (color->string(resene"mantis")); 1 "sRGB:127/193/92" v sash[r7rs]> (resene(list-ref(resene-names) 100)) #< 0xd6fa40> sash[r7rs]> (color->string(resene(list-ref(resene-names) 100))) "sRGB:50/84/130" sash[r7rs]> (resene"rnd"); 2 #f v

1 color→string is available from the (slib color) library v 2 resene returns #f if the name is not recognised v Note, if you include the Resene RGB Values List in binary form in a program, then you must include its license with your program:

• Resene RGB Values List • For further information refer to http://www.resene.co.nz • Copyright Resene Paints Ltd 2001 • Permission to copy this dictionary, to modify it, to redistribute it, to distribute modified versions, and to use it for any purpose is granted, subject to the following restrictions and understandings. Documentation for R7RS Libraries 77 / 131

1. Any text copy made of this dictionary must include this copyright notice in full. 2. Any redistribution in binary form must reproduce this copyright notice in the documentation or other materials provided with the distribution. 3. Resene Paints Ltd makes no warranty or representation that this dictionary is error-free, and is under no obligation to provide any services, by way of maintenance, update, or otherwise. 4. There shall be no use of the name of Resene or Resene Paints Ltd in any advertising, promotional, or sales literature without prior written consent in each case. 5. These RGB colour formulations may not be used to the detriment of Resene Paints Ltd.

17.3 Saturated Colour System: (import (slib saturate))

This library provides a mapping of saturated colour names to colour values (as defined in (slib color)). Two functions are provided:

1. saturate-names returns a list of all the names

2. saturate returns the named colour sash[r7rs]> (import(slib saturate)) # sash[r7rs]> (length(saturate-names)) 19 sash[r7rs]> (saturate-names) ("green""greenish blue""reddish purple""purplish blue""yellow green""bluish purple"" ←- yellow""blue""blue green""purplish red""red purple""yellowish orange""bluish green ←- ""reddish orange""purple""red""yellowish green""greenish yellow""orange") sash[r7rs]> (saturate"red") #< 0x35c02c0> sash[r7rs]> (color->string(saturate"red")); 1 "CIEXYZ:0.735484/0.264516/0" v sash[r7rs]> (saturate"rnd"); 2 #f v

1 color→string is available from the (slib color) library v 2 saturate returns #f if the name is not recognised v Documentation for R7RS Libraries 78 / 131

Chapter 18

SLIB Mathematics Libraries

SLIB provides a lot of valuable support for various mathematical tasks; Aubrey Jaffer, the main implementor and maintainer of SLIB, also wrote JACAL, a symbolic mathematics program relying heavily on features provided by SLIB.

18.1 Factor: (import (slib factor))

Functions for testing if numbers are primes, generating prime numbers, and to factor numbers. These functions use the Solovay-Strassen primality test:

• Robert Solovay and Volker Strassen, A Fast Monte-Carlo Test for Primality, SIAM Journal on Computing, 1977, pp 84-85.

18.1.1 factor factor takes one argument and returns a list of the prime factors of that number: the numbers are in no guaranteed order. > (factor 5) (5) > (factor 100) (5 5 2 2)

18.1.2 jacobi-symbol

The jacobi-symbol is used in modular arithmetic with one application, as here, being tests for primality. The function returns 0, -1 or 1 given two integers. > (jacobi-symbol 15 7) 1 > (jacobi-symbol 63 7) 0 > (jacobi-symbol 7 15) -1

18.1.3 prime:trials prime:trials controls the likelihood that prime? will accept a composite number as a prime. The probability is 2ˆ(- prime:trials) prime:trials is a parameter object, so you can change it to a higher value, if required: Documentation for R7RS Libraries 79 / 131

> (prime:trials) 30 > (prime:trials 100) > (prime:trials) 100

18.1.4 prime? prime? returns true or false depending on if the given number passes the Solovay-Strassen primality test. > (prime? 17) #t > (prime? 1) #f

18.1.5 primes< primes< accepts two arguments: a start value and a count. It returns a list of count prime numbers less than the start value. > (primes< 18 2) (13 17)

18.1.6 primes> primes> accepts two arguments: a start value and a count. It returns a list of count prime numbers greater than the start value. > (primes> 18 2) (19 23)

18.2 Maths Integer Functions: (import (slib math-integer))

Using the functions in this library means that integer values will return integer results. Using non-integer values generates errors. Further documentation: http://people.csail.mit.edu/jaffer/slib/Irrational-Integer-Functions.html#Irrational-Integer-Functions For example: sash[r7rs]> (expt 2.1 3) 9.261000000000001 sash[r7rs]> (integer-expt 2.1 3) Unhandled exception Condition components: 1. &error 2. &message integer-expt 3. &irritants (2.1 3) 4. &stack-trace ... sash[r7rs]> (integer-expt 2 3) 8

Additionally, in cases where an inexact result might be expected, these functions will return the nearest integer equivalent: For example: Documentation for R7RS Libraries 80 / 131

sash[r7rs]> (sqrt 9) 3 sash[r7rs]> (sqrt 10) 3.1622776601683795 sash[r7rs]> (integer-sqrt 9) 3 sash[r7rs]> (integer-sqrt 10) 3

18.3 Maths Real Functions: (import (slib math-real))

The aim of this library is to prevent non-real numbers creeping into calculations. An error is raised if non-real arguments are given to functions, or if non-real results are returned. Further documentation: http://people.csail.mit.edu/jaffer/slib/Irrational-Real-Functions.html#Irrational-Real-Functions For example: sash[r7rs]> (sqrt -2) 0.0+1.4142135623730951i sash[r7rs]> (real-sqrt -2) Unhandled exception Condition components: 1. &error 2. &message real-sqrt 3. &irritants (-2) 4. &stack-trace sash[r7rs]> (sin 0+i) 0.0+1.1752011936438014i sash[r7rs]> (real-sin 0+i) Unhandled exception Condition components: 1. &error 2. &message real-sin 3. &irritants (0+1i) 4. &stack-trace

18.4 Minimize: (import (slib minimize))

The Golden Section Search algorithm can find minima of functions where derivatives are expensive to compute or unavailable.

18.4.1 golden-section-search golden-section-search takes four arguments:

1. the function to minimize (of one argument) 2. the lowest value of x to search from 3. the highest value of x to search to

4. a stopping condition for the search, which is one of

a. a positive number defines a target tolerance Documentation for R7RS Libraries 81 / 131

b. a negative number is negated to define the number of iterations c. a function of (x0 x1 a b fa fb count) ends the search by returning #t

The function returns a dotted pair: the value of x for the minimum and f(x) sash[r7rs]> (golden-section-search square -10 10 -100); 1 (4.258043576850981e-21 . 1.8130935102361897e-41); 2v v

1 Find the minimum of the square value in range (-10, 10) for 100 iterations v 2 The minimum is x=0 and (square x)=0 v The following example minimizes its function to within the specified tolerance: sash[r7rs]> (golden-section-search(lambda(x) (+ ( * xxx)( * -2x) -5)) 0 1 (/ 10000))) (0.8164883855245578 . -6.0886621077391165)

Further documentation: http://people.csail.mit.edu/jaffer/slib/Minimizing.html

18.5 Random Inexact Numbers: (import (slib random-inexact))

A set of functions for generating random inexact numbers. This library is built on top of SRFI 27. All the functions take an optional last argument to define the state. The state is implementation dependent. The functions all use the default random source, which you can randomise before use using SRFI 27’s: > (random-source-randomize! default-random-source)

18.5.1 random:exp random:exp returns an inexact real in an exponential distribution with mean 1. sash[r7rs]> (random:exp) 0.34154536262153173 sash[r7rs]> (random:exp) 0.05480703829750473 sash[r7rs]> (random:exp) 3.949150883906155

18.5.2 random:hollow-sphere! random:hollow-sphere! fills a given vector with numbers generated by random:normal, but ensures the vector is on the n-dimensional unit sphere, where n is the length of the given vector. sash[r7rs]> (definev(vector 0 0 0)) # sash[r7rs]> (random:hollow-sphere!v) #t sash[r7rs]>v #(0.15379204615082398 0.8499736823380848 0.5038777092443952) sash[r7rs]> (+ (square(vector-refv 0)) (square(vector-refv 1)) (square(vector-refv 2) ←- )) 0.9999999999999999 Documentation for R7RS Libraries 82 / 131

18.5.3 random:normal random:normal returns an inexact real in a normal distribution, mean 0 and standard deviation 1. sash[r7rs]> (random:normal) 0.7092759009436378 sash[r7rs]> (random:normal) 1.0895040600796109 sash[r7rs]> (random:normal) -0.03239748330944343

18.5.4 random:normal-vector! random:normal-vector! fills a given vector with numbers generated by random:normal. sash[r7rs]> (definev(vector 0 0 0)) # sash[r7rs]> (random:normal-vector!v) 1.838805009717658 sash[r7rs]>v #(-0.6720177712702253 -0.9211383829955655 0.7339626722027299)

18.5.5 random:solid-sphere! random:solid-sphere! fills a given vector with numbers generated by random:normal, but ensures the vector fits within the n-dimensional unit sphere, where n is the length of the given vector. sash[r7rs]> (definev(vector 0 0 0)) # sash[r7rs]> (random:solid-sphere!v) 0.810489476742576 sash[r7rs]>v #(-0.7899861662963674 -0.09111554959314132 -0.15656629775645328) sash[r7rs]> (+ (square(vector-refv 0)) (square(vector-refv 1)) (square(vector-refv 2) ←- )) 0.6568931919104545

18.5.6 random:uniform random:uniform is the same as SRFI 27’s random-real, and returns a uniformly distributed inexact number in the range (0,1). sash[r7rs]> (random:uniform) 0.7868209548678019 sash[r7rs]> (random:uniform) 0.2504803406880286

18.6 Rationalize: (import (slib rationalize))

R7RS includes the function rationalize which takes two arguments, x and y, and returns the simplest rational number differing from x by no more than y. Note that rationalize only works for rational values of x and y. With inexact values of x or y it returns an inexact value differing from x by no more than y. Documentation for R7RS Libraries 83 / 131

> (rationalize 355/113 1/10) 16/5 > (inexact 355/113) 3.14159292035398 > (inexact 16/5) 3.2 > (rationalize 3.14159729 1/10) 3.2

The first example shows an approximation to a value with a 0.1 difference. However, notice the last example, where an inexact number is returned when seeking an approximation for PI. The library includes the following two functions:

• find-ratio which returns a list of the simplest numerator and denominator whose quotient gives a rational number differing from x by no more than y. • find-ratio-between which returns a list of the simplest numerator and denominator whose quotient gives a rational number between the given x and y.

These two functions work equally well with exact or inexact values for x and y. For example, find-ratio can be used to find increasingly better approximations to PI: #|kawa:1|#(import(slib rationalize)) #|kawa:2|#(find-ratio 3.14159729 0.01) (22 7) #|kawa:3|#(find-ratio 3.14159729 0.001) (201 64) #|kawa:4|#(find-ratio 3.14159729 0.0001) (333 106) #|kawa:5|#(find-ratio 3.14159729 0.00001) (355 113) find-ratio-between is used as follows: #|kawa:6|#(find-ratio-between 2/7 3/5) (1 2) Documentation for R7RS Libraries 84 / 131

Chapter 19

SLIB Time/Date Libraries

The R7RS standard has a library (scheme time) which contains three functions: current-second, to obtain the cur- rent time in seconds since 1/1/1970; current-jiffy, which returns an implementation-defined fraction of a second from an implementation-specific start point; and jiffies-per-second, which returns the implementation-specific number of "jiffies" per second. The libraries provided in SLIB help convert to and from larger units of time (such as days and years), and also take account of time-zones. SRFI 19 provides a useful standard library for working with dates and times, where available. SLIB provides a small set of libraries for managing times, dates and time-zones. These reflect Lisp and Posix treatments of time. The libraries use a variety of data formats:

Calendar Time number of seconds since 1st January 1970 (as used by R7RS current-second) Decoded Time nine values for second, minute, hour, date, month, year, day-of-week, daylight-saving-time? and time-zone. Note that months start with January = 1, days of week start with Monday = 0 TM Time (C’s struct tm) nine values for seconds, minutes, hours, date, month, year, day-of-week, days-in-year, daylight-saving- time?. Note that months start with January = 0, years start with 1900 = 0, days of week start with Sunday = 0 Universal Time number of seconds since 1st January 1900

The libraries themselves are:

• (slib common-lisp-time): From Lisp, using Decoded Time and Universal Time. • (slib posix-time): From C/Posix, using TM Time and Calendar Time. • (slib time-core): main time conversion functions

• (slib time-zone): computes time-zones and daylight-saving times from the time-zone environment variable or files • (slib tzfile): reads from a time-zone file

Time zone information is ultimately read via tzfile which looks for either the environment variable "TZ" or in one of a specified set of paths. (This currently does not appear to support Windows.) None of these libraries handles leap seconds. Documentation for R7RS Libraries 85 / 131

19.1 (slib common-lisp-time)

These functions are based on those in Common Lisp to convert between Decoded Time and Universal Time. get-decoded-time returns the current time in Decoded Time format, as nine values. (get-decoded-time) is short for (decode-universal-time (get-universal-time)). > (get-decoded-time) ((values) 58 15 18 18 4 2017 1 #f 0) get-universal-time returns the current time of day as a single integer in Universal Time format representing the number of seconds since 1/1/1900: note for comparison how R7RS’s (current-second) returns a much smaller value (Calendar Time, the number of seconds since 1/1/1970). > (get-universal-time) 3701527370.61162 > (current-second) 1492540922.30859 decode-universal-time converts a universal time (with an optional time-zone) into the nine values of Decoded Time format. > (decode-universal-time(get-universal-time)) ((values) 41 2 18 18 4 2017 1 #f 0)

The optional time-zone is the number of hours away from GMT. This is backwards from what you might expect: British Summer Time, one hour ahead of GMT, is given by -1. > (decode-universal-time(get-universal-time) -1); current time in London(BST= GMT+1) ((values) 26 4 19 18 4 2017 1 #f -1) > (decode-universal-time(get-universal-time) -5.5); current time in New Delhi(GMT+5.5) ((values) 54 35 23 18 4 2017 1 #f -11/2) encode-universal-time takes the first six values of Decoded Time format, and returns a Universal Time representation. > (encode-universal-time 8 50 21 18 3 2017) 3698862608.0

19.2 (slib time-core)

A collection of functions to help in time conversions based around TM Time. current-time is the same as current-second. This is the Calendar Time, defined relative to 1/1/1970. > (current-time) 1492540922.30859 difftime subtracts two times, given as seconds. leap-year? returns true if given year is a leap-year, false otherwise. > (leap-year? 2000) #t > (leap-year? 2004) #t > (leap-year? 1900) #f offset-time adds two times together, given as seconds. time:gmtime takes a time in seconds and returns the TM Time information, assuming the location is GMT: Documentation for R7RS Libraries 86 / 131

> (time:gmtime(current-time)) #(39 45 18 18 3 117 2 107 0 0"GMT"); 1 v

1 time is 18:45 39s, 18 is the date, month is April (3), year is 2017 (117+1900), day of week is Tuesday (2), 108 days from v 1st January. The last 0 is for the offset due to the time zone.

Note that time:gmtime calls time:split: (time:gmtime tm) = (time:split tm 0 0 "GMT")

19.3 (slib posix-time)

This library provides data structures and functions similar to those in C’s "time.h". asctime converts a TM time into a string representation: > (asctime(gmtime(current-time))) "Tue Apr 18 20:18:15 2017\n" gmtime takes a Calendar time (in seconds) and returns the TM Time information, assuming the location is GMT (the same as time:gmtime). gtime is short for (asctime (gmtime ..)) > (gtime(current-time)) "Tue Apr 18 20:38:28 2017\n" localtime converts a Calendar time into a TM Time. An optional second argument specifies the time zone. > (localtime(current-time)(read-tzfile"Asia/Calcutta")) #(51 16 2 19 3 117 3 108 0 -19800 #(73 83 84)) > (localtime(current-time)) #(8 47 21 18 3 117 2 107 1 -3600 #(66 83 84)) ctime is short for (asctime (localtime ...)) > (ctime(current-time)) "Tue Apr 18 21:44:32 2017\n" > (ctime(current-time)(read-tzfile"Asia/Calcutta")) "Wed Apr 19 02:16:20 2017\n" mktime converts the TM Time to Calendar time: > (current-time) 1492548597.89966 > (localtime(current-time)) #(8 50 21 18 3 117 2 107 1 -3600 #(66 83 84)) > (mktime(localtime(current-time))) 1492552289.0 gmktime is the same as mktime, except it assumes a GMT time zone.

19.4 (slib time-zone) read-tzfile takes a path or, if given #f, uses a known path to a time-zone file. The function then calls tzfile:read from (slib tzfile) and returns the result (see below). read-tzfile is used by time-zone to read the specific time-zone information for a given locality: Documentation for R7RS Libraries 87 / 131

> (read-tzfile"Asia/Dili") #(tz:file"/usr/share/zoneinfo/Asia/Dili" #(#(#(76 77 84) 30140 #f#f#f) #(#(84 76 84) ←- 28800 #f#f#f) #(#(74 83 84) 32400 #f#f#f) #(#(84 76 84) 32400 #f#f#f) #(#(87 73 84 ←- 65) 28800 #f#f#f) #(#(84 76 84) 32400 #f#f#f)) #() #(-2147483648 -1830414140 ←- -879152400 -766054800 199897200 969120000) #(0 1 2 3 4 3)) > (read-tzfile"GMT") #(tz:file"/usr/share/zoneinfo/GMT" #(#(#(71 77 84) 0 #f#f#f)) #() #() #()) time-zone will either:

• return its argument, if it is a vector (i.e. already a time-zone description) • use read-tzfile if the argument is #f or a time-zone file name prefixed with ":" • use string→time-zone if the argument is a string without ":" at start

– The string is in POSIX format for a time zone, see https://www.ibm.com/developerworks/aix/library/au-aix-posix/

• return #f if it could not read the time-zone

> (time-zone#(tz:file"/usr/share/zoneinfo/GMT" #(#(#(71 77 84) 0 #f#f#f)) #() #() #())) #(tz:file"/usr/share/zoneinfo/GMT" #(#(#(71 77 84) 0 #f#f#f)) #() #() #()) > (time-zone":Asia/Dili") #(tz:file"/usr/share/zoneinfo/Asia/Dili" #(#(#(76 77 84) 30140 #f#f#f) #(#(84 76 84) ←- 28800 #f#f#f) #(#(74 83 84) 32400 #f#f#f) #(#(84 76 84) 32400 #f#f#f) #(#(87 73 84 ←- 65) 28800 #f#f#f) #(#(84 76 84) 32400 #f#f#f)) #() #(-2147483648 -1830414140 ←- -879152400 -766054800 199897200 969120000) #(0 1 2 3 4 3)) > (time-zone"CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00") #(tz:rule"CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00""CST""CDT" 21600 18000 (3 2 0 7200) (11 ←- 1 0 7200))

19.5 (slib tzfile)

There is only one exported function: tzfile:read. This function reads time-zone information from a system-specified file. For example, on Linux, the file may be "/etc/localtime": > (import(slib tzfile)) > (tzfile:read"/etc/localtime") ("/etc/localtime" #(#(#(76 77 84) -75 #f#f#f) #(#(66 83 84) 3600 #t#t#f) #(#(71 77 84) 0 #f#t#f) #(#(66 68 83 84) 7200 #t#t#f) #(#(66 83 84) 3600 #f #f#f) #(#(66 83 84) 3600 #t#t#t) #(#(71 77 84) 0 #f#t#t) #(#(71 77 84) 0 #f#f#f)) #() #(-2147483648 -1691964000 -1680472800 -1664143200 -1650146400 -1633903200 -1617487200 -1601848800 -1586037600 -1570399200 -1552168800 -1538344800 -1522533600 -1507500000 -1490565600 -1473631200 -1460930400 -1442786400 -1428876000 -1410732000 -1396216800 -1379282400 -1364767200 -1348437600 -1333317600 -1315778400 -1301263200 -1284328800 -1269813600 -1253484000 -1238364000 -1221429600 -1206914400 -1189980000 -1175464800 -1159135200 -1143410400 -1126476000 -1111960800 -1095631200 -1080511200 -1063576800 -1049061600 -1032127200 -1017612000 -1001282400 -986162400 -969228000 -950479200 -942012000 -904518000 -896050800 -875487600 -864601200 -844038000 -832546800 -812588400 -798073200 -781052400 -772066800 -764805600 -748476000 -733356000 -719445600 -717030000 -706748400 -699487200 -687996000 -668037600 -654732000 -636588000 -622072800 -605743200 -590623200 -574293600 -558568800 -542239200 -527119200 -512604000 -496274400 -481154400 -464220000 -449704800 -432165600 -417650400 -401320800 -386200800 -369266400 -354751200 -337816800 -323301600 -306972000 -291852000 -276732000 -257983200 -245282400 -226533600 -213228000 -195084000 -182383200 -163634400 -150933600 -132184800 -119484000 -100735200 -88034400 -68680800 -59004000 -37242000 57722400 69818400 Documentation for R7RS Libraries 88 / 131

89172000 101268000 120621600 132717600 152071200 164167200 183520800 196221600 214970400 227671200 246420000 259120800 278474400 290570400 309924000 322020000 341373600 354675600 372819600 386125200 404269200 417574800 435718800 449024400 467773200 481078800 499222800 512528400 530672400 543978000 562122000 575427600 593571600 606877200 625626000 638326800 657075600 670381200 688525200 701830800 719974800 733280400 751424400 764730000 782874000 796179600 814323600 820454400 828234000 846378000 859683600 877827600 891133200 909277200 922582800 941331600 954032400 972781200 985482000 1004230800 1017536400 1035680400 1048986000 1067130000 1080435600 1099184400 1111885200 1130634000 1143334800 1162083600 1174784400 1193533200 1206838800 1224982800 1238288400 1256432400 1269738000 1288486800 1301187600 1319936400 1332637200 1351386000 1364691600 1382835600 1396141200 1414285200 1427590800 1445734800 1459040400 1477789200 1490490000 1509238800 1521939600 1540688400 1553994000 1572138000 1585443600 1603587600 1616893200 1635642000 1648342800 1667091600 1679792400 1698541200 1711846800 1729990800 1743296400 1761440400 1774746000 1792890000 1806195600 1824944400 1837645200 1856394000 1869094800 1887843600 1901149200 1919293200 1932598800 1950742800 1964048400 1982797200 1995498000 2014246800 2026947600 2045696400 2058397200 2077146000 2090451600 2108595600 2121901200 2140045200) #(2 1 2 1 2 1212121212121212121212121212121212121212 1212131313131312121312121212121212121212 1212121212121212121212146121212121212121 2125656565656565656565656565656567565656 5656565656565656565656565656565656565656 56565656565656565656565656565656565656)) Documentation for R7RS Libraries 89 / 131

Chapter 20

Repackaged or Ported Libraries

Most of the libraries available in this collection have been repackaged or ported from earlier versions of Scheme, or Lisp, to work under R7RS Scheme implementations. Modifications have been kept to a minimum to make the code work. Test scripts and examples are available for some parts of these libraries and may be examined for ideas on how each library works. This chapter provides an overview of these repackaged collections: some of these have links to their own detailed documentation.

20.1 Automatic Differentiation: (import (autodiff NNNN))

A repackaging of code written by Jeffrey Mark Siskind for R6RS: https://github.com/qobi/R6RS-AD The first library, AD supports automatic differentiation itself. The remaining libraries are, according to JMS, "experimental packages to support nondeterministic and stochastic programming, including constraint satisfaction problems". Some examples are provided, but otherwise this collection needs documenting.

20.1.1 AD: (import (autodiff AD))

This library is the automatic differentiation library itself, providing functions in both forward- and reverse-mode.

Warning This library seems to work fine within a program script (e.g. within the test suite), but not from the REPL.

The library works by redefining all standard mathematical operators to work with dual numbers, pairs containing the "usual" result and its derivative. So, the first thing to be careful of is not to include those operators from (scheme base) or (scheme inexact)!

(import(except(scheme base) + - * / expt square = < > <= >= zero? positive? negative? ←- real?) (except(scheme inexact) sqrt exp log sin cos atan) )

To illustrate how this library is used, consider the function (* x x). It’s derivative is 2x. To get a function to compute the derivative at a given point, we apply the derivative-F function to it ("F" for forward-mode).

(import(except(scheme base) + - * / expt square = < > <= >= zero? positive? negative? ←- real?) (scheme write) (autodiffAD))

(define(fx)( * xx)) Documentation for R7RS Libraries 90 / 131

(display"(f 3)=")(display(f 3)) (display";(f’ 3)=")(display((derivative-Ff) 3)) (newline)

The output is: (f 3) = 9 ; (f’ 3) = 6

Some further examples:

(define(gx) (/ ( * (+x 1) (-x 2)) (+x 3)))

(display"(g 3)=")(display(g 3)) (display";(g’ 3)=")(display((derivative-Fg) 3)) (newline)

(define(hx) (-x (/ (+ ( * 4x) 2) (+x 3))))

(display"(h 3)=")(display(h 3)) (display";(h’ 3)=")(display((derivative-Fh) 3)) (newline)

(display"(fx)= (1+x+e^x).sinx;f’(0)=") (display((derivative-F(lambda(x)( * (+ 1x(expx)) (sinx)))) 0)) (newline)

With output: (g 3) = 2/3 ; (g’ 3) = 13/18 (h 3) = 2/3 ; (h’ 3) = 13/18 (fx) = (1+x+e^x).sinx;f’(0) = 2.0 derivative-R directional-derivative-list-F directional-derivative-vector-F f-gradient-vector-vector-R gradient-list-F gradient-list-R gradient-vector-F gradient-vector-R write-real is used to write out the "real" part of a given number (without its dual or tape part).

20.2 Natural Language Tool Kit: (import (nltk NNNN))

A repackaging of libraries from the Natural Language ToolKit: https://sourceforge.net/projects/snltk/

• dfsa • lang-en

• lang-hr • n-grams Documentation for R7RS Libraries 91 / 131

• sequence • vectorspace

(Not the cgi package, as the necessary support libraries are not present.) These libraries support natural-language processing tasks, such as dividing text into n-grams, analysing or displaying the n-grams, and working with a deterministic finite-state automaton. Some tests and examples are provided, but otherwise this collection needs documenting. SNLTK publication from European Lisp Symposium, 2011.

20.3 Purely Functional Data Structures: (import (pfds NNNN))

A repackaging of Purely Functional Data Structures, originally written for R6RS Scheme: https://github.com/ijp/pfds These data structures implement algorithms from a variety of sources (see the README at above link).

• bounded-balance-tree • deque • difference-list • fector: Functional Vectors, from https://github.com/ijp/fectors • fingertree • hash-array-mapped-trie • heap • priority-search-queue • queue • sequence • set

And, to support implementation:

• alist • bitwise • lazy-list • list-helpers • vector

Some tests and examples are provided, but otherwise this collection needs documenting.

20.4 R6RS: (import (r6rs NNNN))

As many of the libraries have been ported from R6RS implementations, they depend on some R6RS functionalities - particularly fixnum arithmetic and bytevectors. Some of these have been taken from http://snow-fort.org in support of the repackaging (particularly for Weinholt). Documentation for R7RS Libraries 92 / 131

20.5 Rebottled

Some libraries ported from older Scheme versions or Common Lisp: these libraries are individual or very few files.

20.5.1 CL-PDF: (import (rebottled cl-pdf))

Originally written for Common Lisp by Marc Battyani, this library was then ported to Scheme by Bruce Butterfield. The library allows us to construct and output PDF documents. The following example displays two repeated blocks of text and a title in a variety of fonts, sizes and positions in the document. (define(ex1) (pdf:with-document-to-file "ex1.pdf" (let((helvetica(pdf:build-font"Helvetica")) (courier(pdf:build-font"Courier"))) (pdf:with-page (pdf:in-text-mode (pdf:set-font(pdf:font-name helvetica) 36) (pdf:move-text 100 750) (pdf:draw-text"scm-pdf: Example1")) (pdf:in-text-mode (dotimes(i 25) (pdf:set-font(pdf:font-name helvetica)( * i 1.5)) (pdf:move-text (+i 5) (+i 10)) (pdf:draw-text"Helvetica"))) (pdf:in-text-mode (dotimes(i 25) (pdf:set-font(pdf:font-name courier)( * i 1.5)) (pdf:move-text (+i 5) (- 50 (+i 10))) (pdf:draw-text"Courier")))))))

This library needs documentation, and some helper functions to layout larger blocks of text.

20.5.2 JSON

A collection of JSON utilities provided by Takashi Kato for R6RS. See https://github.com/ktakashi/json-tools for more details and documentation. Four packages:

• (import (rebottled json)) • (import (rebottled json-parser)) • (import (rebottled json-select))

• (import (rebottled json-tools))

20.5.3 Packrat: (import (rebottled packrat))

Packrat parser library by Tony Garnock-Jones.

• Documentation: http://tech.labs.oliverwyman.com/downloads/dev.lshift.net/tonyg/packrat.pdf

• General Information: http://bford.info/packrat/ Documentation for R7RS Libraries 93 / 131

20.5.4 Portable Regular Expressions: (import (rebottled pregexp))

Written by Dorai Sitaram, this library is documented at: http://ds26gte.github.io/pregexp/index.html

20.5.5 Quaternions: (import (rebottled quaternions))

Written by Dorai Sitaram, this library is documented at: http://www.ccs.neu.edu/home/dorai/squat/squat.html The quaternions library extends the Scheme numeric tower.

20.5.6 Schelog: (import (rebottled schelog))

Written by Dorai Sitaram, this library is documented at: https://ds26gte.github.io/schelog/index.html

20.6 SRFI: (import (srfi NN))

The r7rs-libs include some SRFIs required by this collection for those implementations which do not otherwise provide them. For documentation on the SRFIs, see http://srfi.schemers.org/final-srfis.html

20.7 Weinholt Industria: (import (weinholt NNNN))

This collection is only partially repackaged for R7RS Scheme, as some of the code requires support from the implementation (such as for the networking) or use of syntax case. The implemented portion contains a collection of algorithms for working with (some) compression algorithms and performing cryptography. Documentation is available at: https://weinholt.se/industria/manual/ See https://github.com/petercrlane/r7rs-libs for information on which libraries are currently available. Documentation for R7RS Libraries 94 / 131

Appendix A

Information on Library Imports

The following tables show, for each library, the non-R7RS imports which it requires, and also the libraries that it is imported into - no libraries such as (scheme base) are shown. The intention is to help decide which additional libraries you need to include when adding a library to an application. e.g. (robin statistics) relies on SRFIs 1, 27, 69 and 95. (WARNING: The lists do not currently list libraries imported using cond-expand statements. For example (robin text) requires SRFI 13 or equivalent functions from other libraries.) These tables are automatically generated from the individual library source files.

Table A.1: Library (autodiff AD)

Imports Imported by (autodiff reduced-gradient) (autodiff stochastic-scheme)

Table A.2: Library (autodiff QobiScheme)

Imports Imported by (autodiff lazy-stochastic-montague-grammar) (autodiff nondeterministic-constraints) (autodiff nondeterministic-recognizer) (autodiff nondeterministic-scheme) (autodiff reduced-gradient) (autodiff stochastic-constraints) (autodiff stochastic-montague-grammar) (autodiff stochastic-recognizer) (autodiff stochastic-scheme)

Table A.3: Library (autodiff deterministic-memoization)

Imports Imported by (autodiff nondeterministic-memoization) (autodiff nondeterministic-stochastic-memoization) Documentation for R7RS Libraries 95 / 131

Table A.3: (continued)

Imports Imported by (autodiff stochastic-memoization) (autodiff stochastic-montague-grammar)

Table A.4: Library (autodiff lazy-stochastic-montague-grammar)

Imports Imported by (autodiff QobiScheme) (autodiff stochastic-scheme) (autodiff stochastic-promises) (autodiff reduced-gradient)

Table A.5: Library (autodiff nondeterministic-constraints)

Imports Imported by (autodiff QobiScheme) (autodiff nondeterministic-scheme)

Table A.6: Library (autodiff nondeterministic-memoization)

Imports Imported by (autodiff nondeterministic-scheme) (autodiff nondeterministic-recognizer) (autodiff deterministic-memoization) (autodiff stochastic-montague-grammar)

Table A.7: Library (autodiff nondeterministic-promises)

Imports Imported by (autodiff nondeterministic-scheme)

Table A.8: Library (autodiff nondeterministic-recognizer)

Imports Imported by (autodiff QobiScheme) (autodiff nondeterministic-scheme) (autodiff nondeterministic-memoization) Documentation for R7RS Libraries 96 / 131

Table A.9: Library (autodiff nondeterministic-scheme)

Imports Imported by (autodiff QobiScheme) (autodiff nondeterministic-constraints) (autodiff nondeterministic-memoization) (autodiff nondeterministic-promises) (autodiff nondeterministic-recognizer) (autodiff nondeterministic-stochastic-memoization) (autodiff stochastic-montague-grammar)

Table A.10: Library (autodiff nondeterministic-stochastic-memoization)

Imports Imported by (autodiff nondeterministic-scheme) (autodiff stochastic-scheme) (autodiff deterministic-memoization)

Table A.11: Library (autodiff reduced-gradient)

Imports Imported by (autodiff AD) (autodiff lazy-stochastic-montague-grammar) (autodiff QobiScheme) (autodiff stochastic-montague-grammar)

Table A.12: Library (autodiff stochastic-constraints)

Imports Imported by (autodiff QobiScheme) (autodiff stochastic-scheme)

Table A.13: Library (autodiff stochastic-memoization)

Imports Imported by (autodiff stochastic-scheme) (autodiff stochastic-recognizer) (autodiff deterministic-memoization)

Table A.14: Library (autodiff stochastic-montague-grammar)

Imports Imported by (autodiff QobiScheme) (autodiff nondeterministic-scheme) Documentation for R7RS Libraries 97 / 131

Table A.14: (continued)

Imports Imported by (autodiff stochastic-scheme) (autodiff deterministic-memoization) (autodiff nondeterministic-memoization) (autodiff reduced-gradient)

Table A.15: Library (autodiff stochastic-promises)

Imports Imported by (autodiff stochastic-scheme) (autodiff lazy-stochastic-montague-grammar)

Table A.16: Library (autodiff stochastic-recognizer)

Imports Imported by (autodiff QobiScheme) (autodiff stochastic-scheme) (autodiff stochastic-memoization)

Table A.17: Library (autodiff stochastic-scheme)

Imports Imported by (autodiff AD) (autodiff lazy-stochastic-montague-grammar) (autodiff QobiScheme) (autodiff nondeterministic-stochastic-memoization) (autodiff stochastic-constraints) (autodiff stochastic-memoization) (autodiff stochastic-montague-grammar) (autodiff stochastic-promises) (autodiff stochastic-recognizer)

Table A.18: Library (nltk dfsa)

Imports Imported by (nltk sequence)

Table A.19: Library (nltk lang-en)

Imports Imported by (nltk sequence) Documentation for R7RS Libraries 98 / 131

Table A.20: Library (nltk lang-hr)

Imports Imported by (nltk sequence)

Table A.21: Library (nltk n-grams)

Imports Imported by (nltk vectorspace) (nltk sequence)

Table A.22: Library (nltk sequence)

Imports Imported by (nltk dfsa) (nltk lang-en) (nltk lang-hr) (nltk n-grams) (nltk vectorspace)

Table A.23: Library (nltk vectorspace)

Imports Imported by (nltk sequence) (nltk n-grams)

Table A.24: Library (pfds alist)

Imports Imported by (pfds hash-array-mapped-trie)

Table A.25: Library (pfds bounded-balance-tree)

Imports Imported by (pfds list-helpers) (pfds set) Documentation for R7RS Libraries 99 / 131

Table A.26: Library (pfds deque)

Imports Imported by (pfds lazy-list) (pfds list-helpers)

Table A.27: Library (pfds difference-list)

Imports Imported by only (scheme NNNN)

Table A.28: Library (pfds fector)

Imports Imported by only (scheme NNNN)

Table A.29: Library (pfds fingertree)

Imports Imported by (pfds list-helpers) (pfds sequence)

Table A.30: Library (pfds hash-array-mapped-trie)

Imports Imported by (pfds alist) (pfds list-helpers) (pfds vector) (srfi 151)

Table A.31: Library (pfds heap)

Imports Imported by (pfds list-helpers)

Table A.32: Library (pfds lazy-list)

Imports Imported by (pfds deque) Documentation for R7RS Libraries 100 / 131

Table A.32: (continued)

Imports Imported by (pfds queue)

Table A.33: Library (pfds list-helpers)

Imports Imported by (pfds bounded-balance-tree) (pfds deque) (pfds fingertree) (pfds hash-array-mapped-trie) (pfds heap) (pfds queue) (pfds sequence) (pfds set)

Table A.34: Library (pfds priority-search-queue)

Imports Imported by only (scheme NNNN)

Table A.35: Library (pfds queue)

Imports Imported by (pfds list-helpers) (pfds lazy-list)

Table A.36: Library (pfds sequence)

Imports Imported by (pfds fingertree) (pfds list-helpers)

Table A.37: Library (pfds set)

Imports Imported by (pfds bounded-balance-tree) (pfds list-helpers) Documentation for R7RS Libraries 101 / 131

Table A.38: Library (pfds vector)

Imports Imported by (pfds hash-array-mapped-trie)

Table A.39: Library (rebottled cl-pdf)

Imports Imported by (rebottled cl-pdf-utils) (slib format)

Table A.40: Library (rebottled cl-pdf-utils)

Imports Imported by (rebottled pregexp) (rebottled cl-pdf) (slib common-list-functions) (slib format) (robin statistics)

Table A.41: Library (rebottled json)

Imports Imported by (rebottled packrat)

Table A.42: Library (rebottled json-parser)

Imports Imported by (rebottled packrat) (rebottled json-select)

Table A.43: Library (rebottled json-select)

Imports Imported by (rebottled json-tools) (rebottled json-parser) Documentation for R7RS Libraries 102 / 131

Table A.44: Library (rebottled json-tools)

Imports Imported by (rebottled json-select)

Table A.45: Library (rebottled packrat)

Imports Imported by (rebottled json) (rebottled json-parser)

Table A.46: Library (rebottled pregexp)

Imports Imported by (rebottled cl-pdf-utils) (robin text)

Table A.47: Library (rebottled pstk)

Imports Imported by (rebottled pstk-plotchart)

Table A.48: Library (rebottled pstk-plotchart)

Imports Imported by (rebottled pstk)

Table A.49: Library (rebottled quaternion)

Imports Imported by only (scheme NNNN)

Table A.50: Library (rebottled schelog)

Imports Imported by only (scheme NNNN) Documentation for R7RS Libraries 103 / 131

Table A.51: Library (robin abbrev)

Imports Imported by only (scheme NNNN)

Table A.52: Library (robin constants)

Imports Imported by only (scheme NNNN)

Table A.53: Library (robin csv)

Imports Imported by only (scheme NNNN)

Table A.54: Library (robin directory)

Imports Imported by (slib format) (slib filename)

Table A.55: Library (robin disjoint-set)

Imports Imported by only (scheme NNNN)

Table A.56: Library (robin logger)

Imports Imported by only (scheme NNNN)

Table A.57: Library (robin series)

Imports Imported by only (scheme NNNN) Documentation for R7RS Libraries 104 / 131

Table A.58: Library (robin srfi64-utils)

Imports Imported by only (scheme NNNN)

Table A.59: Library (robin statistics)

Imports Imported by (srfi 27) (rebottled cl-pdf-utils) (srfi 151) (robin text)

Table A.60: Library (robin text)

Imports Imported by (rebottled pregexp) (robin statistics) (slib soundex)

Table A.61: Library (slib alist)

Imports Imported by (slib string-search)

Table A.62: Library (slib alist-table)

Imports Imported by (slib common) (slib databases) (slib common-list-functions) (slib relational-database)

Table A.63: Library (slib array-for-each)

Imports Imported by (slib common) (slib array-interpolate) (srfi 63) (slib charplot) (slib eps-graph) (slib ncbi-dna) (slib pnm) (slib solid) Documentation for R7RS Libraries 105 / 131

Table A.64: Library (slib array-interpolate)

Imports Imported by (slib array-for-each) (slib subarray) (srfi 63)

Table A.65: Library (slib byte)

Imports Imported by (srfi 63) (slib byte-number) (slib crc) (slib pnm) (slib transact) (slib tzfile)

Table A.66: Library (slib byte-number)

Imports Imported by (slib byte) (slib common) (srfi 151)

Table A.67: Library (slib chapter-order)

Imports Imported by only (scheme NNNN)

Table A.68: Library (slib charplot)

Imports Imported by (slib array-for-each) (slib common) (slib printf) (srfi 63) Documentation for R7RS Libraries 106 / 131

Table A.69: Library (slib coerce)

Imports Imported by (srfi 63) (slib getopt-parameters) (slib http) (slib uri)

Table A.70: Library (slib collect)

Imports Imported by (slib yasos)

Table A.71: Library (slib color)

Imports Imported by (slib color-space) (slib color-names) (slib printf) (slib eps-graph) (slib scanf) (slib nbs-iscc) (slib string-case) (slib resene) (slib saturate) (slib solid)

Table A.72: Library (slib color-names)

Imports Imported by (slib color) (slib databases)

Table A.73: Library (slib color-space)

Imports Imported by (srfi 151) (slib color) (slib daylight) (slib solid)

Table A.74: Library (slib common)

Imports Imported by (slib alist-table) (slib array-for-each) (slib byte-number) Documentation for R7RS Libraries 107 / 131

Table A.74: (continued)

Imports Imported by (slib charplot) (slib common-lisp-time) (slib commutative-ring) (slib database-browse) (slib database-commands) (slib databases) (slib db-html) (slib diff) (slib directory) (slib eps-graph) (slib factor) (slib filename) (slib format) (slib hash) (slib html-for-each) (slib http) (slib line-io) (slib math-real) (slib metric-units) (slib minimize) (slib modular) (slib ncbi-dna) (slib parameters) (slib pnm) (slib pprint-file) (slib precedence-parse) (slib pretty-print) (slib relational-database) (slib scanf) (slib space-filling) (slib string-case) (slib time-zone) (slib transact) (slib tzfile) (slib uri) (slib xml-parse)

Table A.75: Library (slib common-lisp-time)

Imports Imported by (slib common) (slib time-core) (slib time-zone)

Table A.76: Library (slib common-list-functions)

Imports Imported by (rebottled cl-pdf-utils) Documentation for R7RS Libraries 108 / 131

Table A.76: (continued)

Imports Imported by (slib alist-table) (slib database-commands) (slib db-html) (slib getopt-parameters) (slib html-form) (slib http)

Table A.77: Library (slib commutative-ring)

Imports Imported by (slib common) (slib databases) (slib relational-database)

Table A.78: Library (slib crc)

Imports Imported by (slib byte) (srfi 151)

Table A.79: Library (slib database-browse)

Imports Imported by (slib common) (slib databases) (slib printf)

Table A.80: Library (slib database-commands)

Imports Imported by (slib common) (slib db-html) (slib common-list-functions) (slib http) (slib databases) (slib within-database) (slib relational-database) Documentation for R7RS Libraries 109 / 131

Table A.81: Library (slib database-interpolate)

Imports Imported by only (scheme NNNN)

Table A.82: Library (slib databases)

Imports Imported by (slib alist-table) (slib color-names) (slib common) (slib commutative-ring) (slib printf) (slib database-browse) (slib relational-database) (slib database-commands) (slib transact) (slib db-html) (slib html-form) (slib within-database)

Table A.83: Library (slib daylight)

Imports Imported by (slib color-space) (slib solid)

Table A.84: Library (slib db-html)

Imports Imported by (slib common) (slib common-list-functions) (slib databases) (slib database-commands) (slib directory) (slib hash) (slib html-form) (slib pretty-print) (slib printf) (slib string-case) (slib string-search) (slib uri)

Table A.85: Library (slib determinant)

Imports Imported by (srfi 63) Documentation for R7RS Libraries 110 / 131

Table A.86: Library (slib diff)

Imports Imported by (slib common) (srfi 63)

Table A.87: Library (slib directory)

Imports Imported by (slib common) (slib db-html) (slib filename) (slib schmooz) (slib transact) (slib uri)

Table A.88: Library (slib dynamic)

Imports Imported by only (scheme NNNN)

Table A.89: Library (slib eps-graph)

Imports Imported by (slib array-for-each) (slib color) (slib common) (slib filename) (slib line-io) (slib resene) (slib saturate) (srfi 63)

Table A.90: Library (slib factor)

Imports Imported by (slib common) (slib modular) (srfi 27) Documentation for R7RS Libraries 111 / 131

Table A.91: Library (slib filename)

Imports Imported by (slib common) (robin directory) (slib directory) (slib eps-graph) (slib line-io) (slib schmooz) (slib transact)

Table A.92: Library (slib format)

Imports Imported by (slib common) (rebottled cl-pdf) (slib pretty-print) (rebottled cl-pdf-utils) (slib string-case) (robin directory) (slib string-port)

Table A.93: Library (slib fourier-transform)

Imports Imported by (slib subarray) (srfi 151) (srfi 63)

Table A.94: Library (slib generic-write)

Imports Imported by (slib object-string) (slib pretty-print) (slib printf)

Table A.95: Library (slib getopt)

Imports Imported by (slib getopt-parameters)

Table A.96: Library (slib getopt-parameters)

Imports Imported by (slib coerce) Documentation for R7RS Libraries 112 / 131

Table A.96: (continued)

Imports Imported by (slib common-list-functions) (slib getopt) (slib parameters) (slib printf)

Table A.97: Library (slib hash)

Imports Imported by (slib common) (slib db-html)

Table A.98: Library (slib hilbert-fill)

Imports Imported by (srfi 151)

Table A.99: Library (slib html-for-each)

Imports Imported by (slib common) (slib scanf) (slib string-case) (slib string-port)

Table A.100: Library (slib html-form)

Imports Imported by (slib common-list-functions) (slib db-html) (slib databases) (slib http) (slib object-string) (slib parameters) (slib printf) (slib string-search)

Table A.101: Library (slib http)

Imports Imported by (slib common) (slib common-list-functions) Documentation for R7RS Libraries 113 / 131

Table A.101: (continued)

Imports Imported by (slib database-commands) (slib coerce) (slib html-form) (slib parameters) (slib printf) (slib scanf) (slib string-case) (slib string-port) (slib string-search) (slib uri)

Table A.102: Library (slib limit)

Imports Imported by (slib root)

Table A.103: Library (slib line-io)

Imports Imported by (slib common) (slib eps-graph) (slib filename) (slib transact)

Table A.104: Library (slib math-integer)

Imports Imported by (srfi 151)

Table A.105: Library (slib math-real)

Imports Imported by (slib common)

Table A.106: Library (slib metric-units)

Imports Imported by (slib common) (slib precedence-parse) (slib string-port) Documentation for R7RS Libraries 114 / 131

Table A.107: Library (slib minimize)

Imports Imported by (slib common)

Table A.108: Library (slib modular)

Imports Imported by (slib common) (slib factor)

Table A.109: Library (slib nbs-iscc)

Imports Imported by (slib color)

Table A.110: Library (slib ncbi-dna)

Imports Imported by (slib array-for-each) (slib common) (slib printf) (slib scanf) (slib string-case) (slib string-search) (srfi 63)

Table A.111: Library (slib object)

Imports Imported by (slib yasos)

Table A.112: Library (slib object-string)

Imports Imported by (slib generic-write) (slib html-form) (slib string-port) (slib yasos) Documentation for R7RS Libraries 115 / 131

Table A.113: Library (slib parameters)

Imports Imported by (slib common) (slib getopt-parameters) (slib html-form) (slib http)

Table A.114: Library (slib peano-fill)

Imports Imported by (srfi 63)

Table A.115: Library (slib pnm)

Imports Imported by (slib array-for-each) (slib byte) (slib common) (slib subarray) (srfi 63) (srfi 151)

Table A.116: Library (slib posix-time)

Imports Imported by (slib time-core) (slib time-zone)

Table A.117: Library (slib pprint-file)

Imports Imported by (slib common) (slib pretty-print)

Table A.118: Library (slib precedence-parse)

Imports Imported by (slib common) (slib metric-units) Documentation for R7RS Libraries 116 / 131

Table A.118: (continued)

Imports Imported by (slib string-port) (slib string-search)

Table A.119: Library (slib pretty-print)

Imports Imported by (slib common) (slib db-html) (slib generic-write) (slib format) (slib pprint-file)

Table A.120: Library (slib printf)

Imports Imported by (slib generic-write) (slib charplot) (slib color) (slib database-browse) (slib databases) (slib db-html) (slib getopt-parameters) (slib html-form) (slib http) (slib ncbi-dna) (slib solid) (slib transact) (slib uri)

Table A.121: Library (slib priority-queue)

Imports Imported by only (scheme NNNN)

Table A.122: Library (slib queue)

Imports Imported by only (scheme NNNN) Documentation for R7RS Libraries 117 / 131

Table A.123: Library (slib random-inexact)

Imports Imported by (srfi 27)

Table A.124: Library (slib rationalize)

Imports Imported by only (scheme NNNN)

Table A.125: Library (slib read-command)

Imports Imported by (slib string-port)

Table A.126: Library (slib relational-database)

Imports Imported by (slib common) (slib alist-table) (slib commutative-ring) (slib database-commands) (slib databases) (slib within-database)

Table A.127: Library (slib resene)

Imports Imported by (slib color) (slib eps-graph)

Table A.128: Library (slib rev2-procedures)

Imports Imported by (slib xml-parse) Documentation for R7RS Libraries 118 / 131

Table A.129: Library (slib root)

Imports Imported by (slib limit)

Table A.130: Library (slib saturate)

Imports Imported by (slib color) (slib eps-graph)

Table A.131: Library (slib scanf)

Imports Imported by (slib common) (slib color) (slib string-port) (slib html-for-each) (slib http) (slib ncbi-dna) (slib time-zone) (slib transact) (slib uri)

Table A.132: Library (slib schmooz)

Imports Imported by (slib directory) (slib filename) (slib string-search)

Table A.133: Library (slib sierpinski)

Imports Imported by only (scheme NNNN)

Table A.134: Library (slib solid)

Imports Imported by (slib array-for-each) (slib color) (slib color-space) (slib daylight) (slib printf) Documentation for R7RS Libraries 119 / 131

Table A.134: (continued)

Imports Imported by (srfi 63)

Table A.135: Library (slib soundex)

Imports Imported by (robin text)

Table A.136: Library (slib space-filling)

Imports Imported by (slib common) (srfi 63)

Table A.137: Library (slib string-case)

Imports Imported by (slib common) (slib color) (slib db-html) (slib format) (slib html-for-each) (slib http) (slib ncbi-dna) (slib uri)

Table A.138: Library (slib string-port)

Imports Imported by (slib format) (slib html-for-each) (slib http) (slib metric-units) (slib object-string) (slib precedence-parse) (slib read-command) (slib scanf) Documentation for R7RS Libraries 120 / 131

Table A.139: Library (slib string-search)

Imports Imported by (slib alist) (slib db-html) (slib html-form) (slib http) (slib ncbi-dna) (slib precedence-parse) (slib schmooz) (slib transact) (slib uri) (slib xml-parse)

Table A.140: Library (slib subarray)

Imports Imported by (srfi 63) (slib array-interpolate) (slib fourier-transform) (slib pnm)

Table A.141: Library (slib time-core)

Imports Imported by (slib common-lisp-time) (slib posix-time) (slib time-zone)

Table A.142: Library (slib time-zone)

Imports Imported by (slib common) (slib common-lisp-time) (slib scanf) (slib posix-time) (slib time-core) (slib tzfile)

Table A.143: Library (slib topological-sort)

Imports Imported by only (scheme NNNN) Documentation for R7RS Libraries 121 / 131

Table A.144: Library (slib transact)

Imports Imported by (slib byte) (slib databases) (slib common) (slib directory) (slib filename) (slib line-io) (slib printf) (slib scanf) (slib string-search)

Table A.145: Library (slib tree)

Imports Imported by only (scheme NNNN)

Table A.146: Library (slib tzfile)

Imports Imported by (slib byte) (slib time-zone) (slib common)

Table A.147: Library (slib uri)

Imports Imported by (slib coerce) (slib db-html) (slib common) (slib http) (slib directory) (slib printf) (slib scanf) (slib string-case) (slib string-search)

Table A.148: Library (slib within-database)

Imports Imported by (slib databases) (slib database-commands) (slib relational-database) Documentation for R7RS Libraries 122 / 131

Table A.149: Library (slib wt-tree)

Imports Imported by only (scheme NNNN)

Table A.150: Library (slib xml-parse)

Imports Imported by (slib common) (slib rev2-procedures) (slib string-search)

Table A.151: Library (slib yasos)

Imports Imported by (slib object) (slib collect) (slib object-string)

Table A.152: Library (weinholt adler-32)

Imports Imported by (r6rs fixnums) (srfi 151)

Table A.153: Library (weinholt arcfour)

Imports Imported by (r6rs fixnums) (weinholt bytevector)

Table A.154: Library (weinholt bitstream)

Imports Imported by (r6rs bytevectors) (r6rs fixnums) Documentation for R7RS Libraries 123 / 131

Table A.155: Library (weinholt blowfish)

Imports Imported by (r6rs base) (r6rs bytevectors) (r6rs fixnums) (srfi 151)

Table A.156: Library (weinholt bytevector)

Imports Imported by (r6rs base) (weinholt arcfour) (r6rs bytevectors) (weinholt dh) (r6rs fixnums) (weinholt elliptic-curve) (srfi 151) (weinholt lzma)

Table A.157: Library (weinholt des)

Imports Imported by (r6rs bytevectors) (r6rs fixnums) (srfi 151)

Table A.158: Library (weinholt dh)

Imports Imported by (r6rs base) (weinholt bytevector) (weinholt entropy) (weinholt maths)

Table A.159: Library (weinholt elliptic-curve)

Imports Imported by (r6rs base) (r6rs bytevectors) (weinholt bytevector) (weinholt maths) (srfi 151) Documentation for R7RS Libraries 124 / 131

Table A.160: Library (weinholt entropy)

Imports Imported by (srfi 26) (weinholt dh) (srfi 27)

Table A.161: Library (weinholt hmac)

Imports Imported by (r6rs bytevectors) (weinholt sha-2) (r6rs fixnums)

Table A.162: Library (weinholt lzma)

Imports Imported by (r6rs fixnums) (srfi 151) (weinholt bytevector) (weinholt sliding-buffer)

Table A.163: Library (weinholt maths)

Imports Imported by (r6rs base) (weinholt dh) (r6rs fixnums) (weinholt elliptic-curve) (srfi 151)

Table A.164: Library (weinholt md5)

Imports Imported by (r6rs base) (r6rs bytevectors) (r6rs fixnums) (srfi 151)

Table A.165: Library (weinholt sha-1)

Imports Imported by (r6rs bytevectors) (r6rs fixnums) (srfi 151) Documentation for R7RS Libraries 125 / 131

Table A.166: Library (weinholt sha-2)

Imports Imported by (r6rs bytevectors) (r6rs fixnums) (srfi 151) (weinholt hmac)

Table A.167: Library (weinholt sliding-buffer)

Imports Imported by (r6rs base) (weinholt lzma) (r6rs bytevectors) (r6rs fixnums)

Table A.168: Library (weinholt strings)

Imports Imported by only (scheme NNNN) Documentation for R7RS Libraries 126 / 131

Appendix B

Open Works License

This is version 0.9.4 of the Open Works License Terms Permission is hereby granted by the holder(s) of copyright or other legal privileges, author(s) or assembler(s), and contributor(s) of this work, to any person who obtains a copy of this work in any form, to reproduce, modify, distribute, publish, sell, sublicense, use, and/or otherwise deal in the licensed material without restriction, provided the following conditions are met: Redistributions, modified or unmodified, in whole or in part, must retain applicable copyright and other legal privilege notices, the above license notice, these conditions, and the following disclaimer. NO WARRANTY OF ANY KIND IS IMPLIED BY, OR SHOULD BE INFERRED FROM, THIS LICENSE OR THE ACT OF DISTRIBUTION UNDER THE TERMS OF THIS LICENSE, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS, ASSEMBLERS, OR HOLDERS OF COPYRIGHT OR OTHER LEGAL PRIVILEGE BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN ACTION OF CONTRACT, TORT, OR OTHERWISE ARISING FROM, OUT OF, OR IN CONNECTION WITH THE WORK OR THE USE OF OR OTHER DEALINGS IN THE WORK. Documentation for R7RS Libraries 127 / 131

Chapter 21

Index

A change-directory,7 abbrev,3, 103 chapter-order, 105 absolute-path?, 60 charplot, 105 absolute-uri?, 60 choose, 17 AD, 94 choose-if, 17 adler-32, 122 cl-pdf, 92, 101 alist, 98, 104 cl-pdf-utils, 101 alist-table, 104 coefficient-of-variation, 22 arcfour, 122 coerce, 106 arithmetic-geometric-mean, 22 collect, 18, 106 arithmetic-mean, 22 collect-alist, 18 array-dimensions, 67 collect-and, 19 array-for-each, 68, 104 collect-append, 18 array-in-bounds?, 67 collect-file, 18 array-index-for-each, 68 collect-first, 18 array-index-map!, 69 collect-fn, 19 array-indexes, 68 collect-last, 18 array-interpolate, 70, 105 collect-length, 18 array-map, 69 collect-max, 18 array-map!, 69 collect-min, 19 array-rank, 67 collect-nth, 18 array-ref, 67 collect-or, 19 array-set!, 67 collect-string, 18 array-trim, 72 collect-sum, 18 array:copy!, 69 color, 106 array?, 67 color-names, 106 array→list, 67 color-space, 106 array→vector, 67 combinations, 22 asctime, 86 common, 106 autodiff, 89 common-lisp-time, 85, 107 common-list-functions, 107 B commutative-ring, 108 bitstream, 122 constants,4, 103 blowfish, 123 crc, 108 bounded-balance-tree, 98 create-bar-chart, 47 byte, 105 create-pie-chart, 49 byte-number, 105 create-xy-plot, 50 bytevector, 123 csv,5, 103 ctime, 86 C current-directory,7 c,4 current-time, 85 call-with-dynamic-binding, 58 catenate, 17 D Documentation for R7RS Libraries 128 / 131

Daitch-Mokotoff Soundex, 28 G,4 daitch-mokotoff-soundex, 28 generic-write, 111 database, 56 geometric-mean, 23 database-browse, 108 get-decoded-time, 85 database-commands, 108 get-universal-time, 85 database-interpolate, 109 getopt, 111 databases, 109 getopt-parameters, 111 daylight, 109 glob,8, 60 db-html, 109 glob-pattern?, 60 decode-universal-time, 85 gmktime, 86 delete-directory,7 gmtime, 86 deque, 99 golden-section-search, 80 derivative-F, 89 gradient-list-F, 90 derivative-R, 90 gradient-list-R, 90 des, 123 gradient-vector-F, 90 determinant, 71, 109 gradient-vector-R, 90 deterministic-memoization, 94 gtime, 86 dfsa, 97 dh, 123 H diff, 110 hamming-distance, 28 difference-list, 99 harmonic-mean, 23 difftime, 85 hash, 112 directional-derivative-list-F, 90 hash-array-mapped-trie, 99 directional-derivative-vector-F, 90 heap, 99 directory,7, 103, 110 hilbert-fill, 112 disjoint set, 10 histograph, 54 disjoint-set, 103 hmac, 124 disjoint-set:find, 10 html-for-each, 112 disjoint-set:make, 10 html-form, 112 disjoint-set:size, 10 html:anchor, 60 disjoint-set:union, 10 html:base, 61 disjoint-set?, 10 html:isindex, 61 dynamic, 58, 110 html:link, 61 dynamic-ref, 58 http, 112 dynamic-set!, 58 dynamic?, 58 I integer-expt, 79 E integer-sqrt, 79 e,4 interpolate-array-ref, 70 elliptic-curve, 123 encode-universal-time, 85 J entropy, 124 Jaccard Distance, 23 eps-graph, 110 Jaccard Index, 23 equal?, 67 jaccard-distance, 23 expand, 17 jaccard-index, 23 jacobi-symbol, 78 F json, 92, 101 f-gradient-vector-vector-R, 90 json-parser, 101 factor, 78, 110 json-select, 101 fector, 99 json-tools, 102 filename, 111 find-ratio, 83 K find-ratio-between, 83 Kruskal’s Algorithm, 11 fingertree, 99 format, 59, 111 L fourier-transform, 111 lang-en, 97 lang-hr, 98 G lazy-list, 99 Documentation for R7RS Libraries 129 / 131

lazy-stochastic-montague-grammar, 95 mode, 24 leap-year?, 85 modular, 114 levenshtein-distance, 29 limit, 113 N line-io, 113 n-grams, 98 list-directory,7 nbs-iscc, 75, 114 list-directory-files,8 nbs-iscc-names, 75 list-glob,8 ncbi-dna, 114 list-helpers, 100 new-logger, 12 list→array, 66 nltk, 90 localtime, 86 nondeterministic-constraints, 95 log-add, 13 nondeterministic-memoization, 95 log-close, 12 nondeterministic-promises, 95 log-debug, 13 nondeterministic-recognizer, 95 log-debug?, 13 nondeterministic-scheme, 96 log-error, 13 nondeterministic-stochastic-memoization, 96 log-error?, 13 null-directory?, 61 log-fatal, 13 log-fatal?, 13 O log-info, 13 object, 114 log-info?, 13 object-string, 114 log-level, 13 offset-time, 85 log-unknown, 13 optimal-string-alignment-distance, 29 log-unknown?, 13 P log-warn, 13 packrat, 92, 102 log-warn?, 13 parameters, 115 logger, 12, 103 parse-ftp-address, 61 logger?, 12 path→uri, 62 lzma, 124 peano-fill, 115 M percentile, 24 make-array, 66 Perlin Noise, 24 make-directory,8 perlin-noise, 24 make-disjoint-set, 10 permutations, 25 make-dynamic, 58 pfds, 91 make-series, 15 PI,4 make-uri, 61 plot, 54 map-fn, 16 pnm, 115 mask, 17 population-standard-deviation, 25 math-integer, 79, 113 population-variance, 25 math-real, 80, 113 Porter Stemming Algorithm, 30 maths, 124 porter-stem, 30 matrix:difference, 71 positions, 17 matrix:inverse, 71 posix-time, 86, 115 matrix:product, 72 pprint-file, 115 matrix:sum, 72 precedence-parse, 115 matrix→array, 71 pregexp, 93, 102 matrix→lists, 71 pretty-print, 116 md5, 124 previous, 17 mean, 24 prime:trials, 78 median, 24 prime?, 79 metaphone, 29 primes<, 79 Metaphone Algorithm, 29 primes>, 79 metric-units, 113 printf, 116 mingle, 17 priority-queue, 116 minimize, 114 priority-search-queue, 100 mktime, 86 pstk, 32, 102 Documentation for R7RS Libraries 130 / 131

pstk-plotchart, 102 series?, 15 set, 100 Q sha-1, 124 QobiScheme, 94 sha-2, 125 quaternion, 102 sierpinski, 118 quaternions, 93 sign, 26 queue, 100, 116 slib, 53 sliding-buffer, 125 R solid, 118 r6rs, 91 Sorenson Dice Index, 27 random-inexact, 81, 117 sorenson-dice-index, 27 random-normal, 25 sorenson-dice-similarity, 30 random-pick, 26 soundex, 30, 119 random-real, 82 space-filling, 119 random-sample, 26 spread, 17 random-weighted-sample, 26 srfi, 93 random:exp, 81 SRFI 19, 84 random:hollow-sphere!, 81 SRFI 63, 66 random:normal, 82 srfi64-utils, 104 random:normal-vector!, 82 SSAX, 59 random:solid-sphere!, 82 ssax:xml→sxml, 59 random:uniform, 82 standard-deviation, 27 rationalize, 82, 117 standard-error-of-the-mean, 27 read-command, 117 statistics, 22, 104 read-tzfile, 86 stochastic-constraints, 96 real-sin, 80 stochastic-memoization, 96 real-sqrt, 80 stochastic-montague-grammar, 96 rebottled, 92 stochastic-promises, 97 reduced-gradient, 96 stochastic-recognizer, 97 relational database, 56 stochastic-scheme, 97 relational-database, 117 string-case, 119 resample-array!, 70 string-port, 119 resene, 76, 77, 117 string-search, 120 resene-names, 76 string→n-grams, 30 rev2-procedures, 117 strings, 125 root, 118 subarray, 72, 73, 120 Russell Soundex, 59 subseries, 17 russell-soundex, 30 T S test-all-equal, 20 saturate, 77, 118 test-approx-same, 20 saturate-names, 77 test-compare, 20 scan, 15 test-no-error, 21 scan-alist, 16 text, 28, 104 scan-file, 16 time-core, 85, 120 scan-fn, 16 time-zone, 86, 87, 120 scan-fn-inclusive, 16 time:gmtime, 85 scan-list, 15 time:split, 86 scan-range, 16 tk-end, 44 scan-string, 16 tk-eval, 44 scan-sublists, 16 tk-event-loop, 44 scan-vector, 16 tk-get-var, 45 scanf, 118 tk-set-var!, 45 schelog, 93, 102 tk-start, 45 schmooz, 118 tk-var, 45 sequence, 98, 100 tk-wait-for-window, 45 series, 15, 103 tk-wait-until-visible, 45 Documentation for R7RS Libraries 131 / 131

tk-with-lock, 45 uric:encode, 62 tk/after, 35 tk/appname, 35 V tk/bell, 36 variance, 27 tk/bgerror, 36 vector, 101 tk/bind, 36 vector→array, 66 tk/bindtags, 36 vectorspace, 98 tk/caret, 36 tk/choose-color, 36 W tk/choose-directory, 37 weinholt, 93 tk/clipboard, 37 within-database, 121 tk/destroy, 37 word-wrap, 31 tk/event, 38 words→with-commas, 31 tk/focus, 38 write-real, 90 tk/focus-follows-mouse, 38 wt-tree, 122 tk/focus-next, 38 X tk/focus-prev, 38 xml-parse, 59, 122 tk/get-open-file, 38 tk/get-save-file, 39 Y tk/grab, 39 yasos, 122 tk/grid, 39 tk/image, 40 tk/lower, 40 tk/message-box, 40 tk/option, 41 tk/pack, 41 tk/place, 42 tk/popup, 42 tk/raise, 42 tk/scaling, 42 tk/selection, 42 tk/update, 42 tk/useinputmethods, 42 tk/wait, 43 tk/windowingsystem, 43 tk/winfo, 43 tk/wm, 43 topological-sort, 120 transact, 121 transpose, 72 tree, 121 ttk-map-widgets, 44 ttk/available-themes, 43 ttk/set-theme, 44 ttk/style, 44 tzfile, 87, 121 tzfile:read, 87

U until, 16 until-if, 16 uri, 121 uri:decode-query, 62 uri:make-path, 62 uri:splitfields, 62 uri→tree, 62 uric:decode, 62