# Unit extras

This unit contains a collection of useful utility definitions. This unit is used by default, unless the program is compiled with the `-explicit-use` option.

## Lists

### alist-ref

    [procedure] (alist-ref KEY ALIST [TEST [DEFAULT]])

Looks up `KEY` in `ALIST` using `TEST` as the comparison function (or `eqv?` if no test was given) and returns the cdr of the found pair, or `DEFAULT` (which defaults to `#f`).

### alist-update!

    [procedure] (alist-update! KEY VALUE ALIST [TEST])

If the list `ALIST` contains a pair of the form `(KEY . X)`, then this procedure replaces `X` with `VALUE` and returns `ALIST`. If `ALIST` contains no such item, then `alist-update!` returns `((KEY . VALUE) . ALIST)`. The optional argument `TEST` specifies the comparison procedure to search a matching pair in `ALIST` and defaults to `eqv?`.

### atom?

    [procedure] (atom? X)

Returns `#t` if `X` is not a pair. This is identical to `not-pair?` from Unit srfi-1 but kept for historical reasons.

### rassoc

    [procedure] (rassoc KEY LIST [TEST])

Similar to `assoc`, but compares `KEY` with the `cdr` of each pair in `LIST` using `TEST` as the comparison procedures (which defaults to `eqv?`.

### butlast

    [procedure] (butlast LIST)

Returns a fresh list with all elements but the last of `LIST`.

### chop

    [procedure] (chop LIST N)

Returns a new list of sublists, where each sublist contains `N` elements of `LIST`. If `LIST` has a length that is not a multiple of `N`, then the last sublist contains the remaining elements.

    (chop '(1 2 3 4 5 6) 2) ==> ((1 2) (3 4) (5 6))
    (chop '(a b c d) 3)     ==> ((a b c) (d))

### compress

    [procedure] (compress BLIST LIST)

Returns a new list with elements taken from `LIST` with corresponding true values in the list `BLIST`.

    (define nums '(99 100 110 401 1234))
    (compress (map odd? nums) nums)      ==> (99 401)

### flatten

    [procedure] (flatten LIST1 ...)

Returns `LIST1 ...` concatenated together, with nested lists removed (flattened).

### intersperse

    [procedure] (intersperse LIST X)

Returns a new list with `X` placed between each element.

### join

    [procedure] (join LISTOFLISTS [LIST])

Concatenates the lists in `LISTOFLISTS` with `LIST` placed between each sublist. `LIST` defaults to the empty list.

    (join '((a b) (c d) (e)) '(x y)) ==> (a b x y c d x y e)
    (join '((p q) () (r (s) t)) '(-))  ==> (p q - - r (s) t)

`join` could be implemented as follows:

    (define (join lstoflsts #!optional (lst '()))
      (apply append (intersperse lstoflists lst)) )

### shuffle

    [procedure] (shuffle LIST)

Returns `LIST` with its elements sorted in a random order.

### tail?

    [procedure] (tail? X LIST)

Returns true if `X` is one of the tails (cdr's) of `LIST`.

## String-port extensions

### call-with-input-string

    [procedure] (call-with-input-string STRING PROC)

Calls the procedure `PROC` with a single argument that is a string-input-port with the contents of `STRING`.

### call-with-output-string

    [procedure] (call-with-output-string PROC)

Calls the procedure `PROC` with a single argument that is a string-output-port. Returns the accumulated output-string.

### with-input-from-string

    [procedure] (with-input-from-string STRING THUNK)

Call procedure `THUNK` with the current input-port temporarily bound to an input-string-port with the contents of `STRING`.

### with-output-to-string

    [procedure] (with-output-to-string THUNK)

Call procedure `THUNK` with the current output-port temporarily bound to a string-output-port and return the accumulated output string.

## Formatted output

### printf

    [procedure] (fprintf PORT FORMATSTRING ARG ...)
    [procedure] (printf FORMATSTRING ARG)
    [procedure] (sprintf FORMATSTRING ARG ...)
    [procedure] (format FORMATSTRING ARG ...)

Simple formatted output to a given port (`fprintf`), the value of `(current-output-port)` (`printf`) or a string (`sprintf`/`format`). The `FORMATSTRING` can contain any sequence of characters. The character `~' prefixes special formatting directives:

    ~%
write newline character
    ~N
the same as `~%`
    ~S
write the next argument
    ~A
display the next argument
    ~\n
skip all whitespace in the format-string until the next non-whitespace character
    ~B
write the next argument as a binary number
    ~O
write the next argument as an octal number
    ~X
write the next argument as a hexadecimal number
    ~C
write the next argument as a character
    ~~
display `~'
    ~!
flush all pending output
    ~?
invoke formatted output routine recursively with the next two arguments as format-string and list of parameters

## Hash tables

CHICKEN implements SRFI-69. For more information, see SRFI-69.

A setter for `hash-table-ref` is defined, so

    (set! (hash-table-ref HT KEY) VAL)

is equivalent to

    (hash-table-set! HT KEY VAL)

As an extension to SRFI-69, `hash-table-update!` and `hash-table-update!/default` return the new value (after applying the update procedure).

## Queues

### list->queue

    [procedure] (list->queue LIST)

Returns `LIST` converted into a queue, where the first element of the list is the same as the first element of the queue. The resulting queue may share memory with the list and the list should not be modified after this operation.

### make-queue

    [procedure] (make-queue)

Returns a newly created queue.

### queue?

    [procedure] (queue? X)

Returns `#t` if `X` is a queue, or `#f` otherwise.

### queue->list

    [procedure] (queue->list QUEUE)

Returns `QUEUE` converted into a list, where the first element of the list is the same as the first element of the queue. The resulting list may share memory with the queue object and should not be modified.

### queue-add!

    [procedure] (queue-add! QUEUE X)

Adds `X` to the rear of `QUEUE`.

### queue-empty?

    [procedure] (queue-empty? QUEUE)

Returns `#t` if `QUEUE` is empty, or `#f` otherwise.

### queue-first

    [procedure] (queue-first QUEUE)

Returns the first element of `QUEUE`. If `QUEUE` is empty an error is signaled

### queue-last

    [procedure] (queue-last QUEUE)

Returns the last element of `QUEUE`. If `QUEUE` is empty an error is signaled

### queue-remove!

    [procedure] (queue-remove! QUEUE)

Removes and returns the first element of `QUEUE`. If `QUEUE` is empty an error is signaled

### queue-push-back!

    [procedure] (queue-push-back! QUEUE ITEM)

Pushes an item into the first position of a queue, i.e. the next `queue-remove!` will return `ITEM`.

### queue-push-back-list!

    [procedure] (queue-push-back-list! QUEUE LIST)

Pushes the items in item-list back onto the queue, so that `(car LIST)` becomes the next removable item.

## Sorting

### merge

    [procedure] (merge LIST1 LIST2 LESS?)
    [procedure] (merge! LIST1 LIST2 LESS?)

Joins two lists in sorted order. `merge!` is the destructive version of merge. `LESS?` should be a procedure of two arguments, that returns true if the first argument is to be ordered before the second argument.

### sort

    [procedure] (sort SEQUENCE LESS?)
    [procedure] (sort! SEQUENCE LESS?)

Sort `SEQUENCE`, which should be a list or a vector. `sort!` is the destructive version of sort.

### sorted?

    [procedure] (sorted? SEQUENCE LESS?)

Returns true if the list or vector `SEQUENCE` is already sorted.

## Random numbers

### random

    [procedure] (random N)

Returns an exact random integer from 0 to `N`-1.

### randomize

    [procedure] (randomize [X])

Set random-number seed. If `X` is not supplied, the current time is used. On startup (when the `extras` unit is initialized), the random number generator is initialized with the current time.

## Input/Output extensions

### make-input-port

    [procedure] (make-input-port READ READY? CLOSE [PEEK])

Returns a custom input port. Common operations on this port are handled by the given parameters, which should be procedures of no arguments. `READ` is called when the next character is to be read and should return a character or `#!eof`. `READY?` is called when `char-ready?` is called on this port and should return `#t` or `#f`. `CLOSE` is called when the port is closed. `PEEK` is called when `peek-char` is called on this port and should return a character or `#!eof`. if the argument `PEEK` is not given, then `READ` is used instead and the created port object handles peeking automatically (by calling `READ` and buffering the character).

### make-output-port

    [procedure] (make-output-port WRITE CLOSE [FLUSH])

Returns a custom output port. Common operations on this port are handled by the given parameters, which should be procedures. `WRITE` is called when output is sent to the port and receives a single argument, a string. `CLOSE` is called when the port is closed and should be a procedure of no arguments. `FLUSH` (if provided) is called for flushing the output port.

### pretty-print

    [procedure] (pretty-print EXP [PORT])
    [procedure] (pp EXP [PORT])

Print expression nicely formatted. `PORT` defaults to the value of `(current-output-port)`.

### pretty-print-width

(Parameter) Specifies the maximal line-width for pretty printing, after which line wrap will occur.

### read-file

    [procedure] (read-file [FILE-OR-PORT [READER [MAXCOUNT]]])

Returns a list containing all toplevel expressions read from the file or port `FILE-OR-PORT`. If no argument is given, input is read from the port that is the current value of `(current-input-port)`. After all expressions are read, and if the argument is a port, then the port will not be closed. The `READER` argument specifies the procedure used to read expressions from the given file or port and defaults to `read`. The reader procedure will be called with a single argument (an input port). If `MAXCOUNT` is given then only up to `MAXCOUNT` expressions will be read in.

### read-line

### write-line

    [procedure] (read-line [PORT [LIMIT]])
    [procedure] (write-line STRING [PORT])

Line-input and -output. `PORT` defaults to the value of `(current-input-port)` and `(current-output-port)`, respectively. if the optional argument `LIMIT` is given and not `#f`, then `read-line` reads at most `LIMIT` characters per line.

### read-lines

    [procedure] (read-lines [PORT [MAX]])

Read `MAX` or fewer lines from `PORT`. `PORT` defaults to the value of `(current-input-port)`. `PORT` may optionally be a string naming a file.

### read-string

### read-string!

### write-string

    [procedure] (read-string [NUM [PORT]])
    [procedure] (read-string! NUM STRING [PORT [START]])
    [procedure] (write-string STRING [NUM [PORT]]

Read or write `NUM` characters from/to `PORT`, which defaults to the value of `(current-input-port)` or `(current-output-port)`, respectively. If `NUM` is `#f` or not given, then all data up to the end-of-file is read, or, in the case of `write-string` the whole string is written. If no more input is available, `read-string` returns the empty string. `read-string!` reads destructively into the given `STRING` argument, but never more characters that would fit into `STRING`. If `START` is given, then the read characters are stored starting at that position. `read-string!` returns the actual number of characters read.

### read-token

    [procedure] (read-token PREDICATE [PORT])

Reads characters from `PORT` (which defaults to the value of `(current-input-port)`) and calls the procedure `PREDICATE` with each character until `PREDICATE` returns false. Returns a string with the accumulated characters.

### with-error-output-to-port

    [procedure] (with-error-output-to-port PORT THUNK)

Call procedure `THUNK` with the current error output-port temporarily bound to `PORT`.

### with-input-from-port

    [procedure] (with-input-from-port PORT THUNK)

Call procedure `THUNK` with the current input-port temporarily bound to `PORT`.

### with-output-to-port

    [procedure] (with-output-to-port PORT THUNK)

Call procedure `THUNK` with the current output-port temporarily bound to `PORT`.

## Strings

### conc

    [procedure] (conc X ...)

Returns a string with the string-represenation of all arguments concatenated together. `conc` could be implemented as

    (define (conc . args)
      (apply string-append (map ->string args)) )

### ->string

    [procedure] (->string X)

Returns a string-representation of `X`.

### string-chop

    [procedure] (string-chop STRING LENGTH)

Returns a list of substrings taken by chopping `STRING` every `LENGTH` characters:

    (string-chop "one two three" 4)  ==>  ("one " "two " "thre" "e")

### string-chomp

    [procedure] (string-chomp STRING [SUFFIX])

If `STRING` ends with `SUFFIX`, then this procedure returns a copy of its first argument with the suffix removed, otherwise returns `STRING` unchanged. `SUFFIX` defaults to `"\n"`.

### string-compare3

    [procedure] (string-compare3 STRING1 STRING2)
    [procedure] (string-compare3-ci STRING1 STRING2)

Perform a three-way comparison between the `STRING1` and `STRING2`, returning either `-1` if `STRING1` is lexicographically less than `STRING2`, `0` if it is equal, or `1` if it s greater. `string-compare3-ci` performs a case-insensitive comparison.

### string-intersperse

    [procedure] (string-intersperse LIST [STRING])

Returns a string that contains all strings in `LIST` concatenated together. `STRING` is placed between each concatenated string and defaults to `" "`.

    (string-intersperse '("one" "two") "three")

is equivalent to

    (apply string-append (intersperse '("one" "two") "three"))

### string-split

    [procedure] (string-split STRING [DELIMITER-STRING [KEEPEMPTY]])

Split string into substrings separated by the given delimiters. If no delimiters are specified, a string comprising the tab, newline and space characters is assumed. If the parameter `KEEPEMPTY` is given and not `#f`, then empty substrings are retained:

    (string-split "one  two  three") ==> ("one" "two" "three")
    (string-split "foo:bar::baz:" ":" #t) ==> ("foo" "bar" "" "baz" "")

### string-translate

    [procedure] (string-translate STRING FROM [TO])

Returns a fresh copy of `STRING` with characters matching `FROM` translated to `TO`. If `TO` is omitted, then matching characters are removed. `FROM` and `TO` may be a character, a string or a list. If both `FROM` and `TO` are strings, then the character at the same position in `TO` as the matching character in `FROM` is substituted.

### string-translate*

    [procedure] (string-translate* STRING SMAP)

Substitutes elements of `STRING` according to `SMAP`. `SMAP` should be an association-list where each element of the list is a pair of the form `(MATCH \. REPLACEMENT)`. Every occurrence of the string `MATCH` in `STRING` will be replaced by the string `REPLACEMENT`:

    (string-translate*
      "<h1>this is a \"string\"</h1>"
      '(("<" . "&lt:") (">" . "&gt;") ("\"" . "&quot;")) )
    =>  "&lt;h1&gt;this is a &quot;string&quot;&lt;/ht&gt;"

### substring=?

    [procedure] (substring=? STRING1 STRING2 [START1 [START2 [LENGTH]]])
    [procedure] (substring-ci=? STRING1 STRING2 [START1 [START2 [LENGTH]]])

Returns `#t` if the strings `STRING1` and `STRING2` are equal, or `#f` otherwise. The comparison starts at the positions `START1` and `START2` (which default to 0), comparing `LENGTH` characters (which defaults to the minimum of the remaining length of both strings).

### substring-index

    [procedure] (substring-index WHICH WHERE [START])
    [procedure] (substring-index-ci WHICH WHERE [START])

Searches for first index in string `WHERE` where string `WHICH` occurs. If the optional argument `START` is given, then the search starts at that index. `substring-index-ci` is a case-insensitive version of `substring-index`.

## Combinators

### any?

    [procedure] (any? X)

Ignores it's argument and always returns `#t`. This is actually useful sometimes.

### constantly

    [procedure] (constantly X ...)

Returns a procedure that always returns the values `X ...` regardless of the number and value of its arguments.

    (constantly X) <=> (lambda args X)

### complement

    [procedure] (complement PROC)

Returns a procedure that returns the boolean inverse of `PROC`.

    (complement PROC) <=> (lambda (x) (not (PROC x)))

### compose

    [procedure] (compose PROC1 PROC2 ...)

Returns a procedure that represents the composition of the argument-procedures `PROC1 PROC2 ...`.

    (compose F G) <=> (lambda args
                          (call-with-values
                             (lambda () (apply G args))
                             F))

`(compose)` is equivalent to `values`.

### conjoin

    [procedure] (conjoin PRED ...)

Returns a procedure that returns `#t` if its argument satisfies the predicates `PRED ...`. <enscript highlight=scheme> ((conjoin odd? positive?) 33) =⇒ #t ((conjoin odd? positive?) -33) =⇒ #f </enscript>

### disjoin

    [procedure] (disjoin PRED ...)

Returns a procedure that returns `#t` if its argument satisfies any predicate `PRED ...`. <enscript highlight=scheme> ((disjoin odd? positive?) 32) =⇒ #t ((disjoin odd? positive?) -32) =⇒ #f </enscript>

### each

    [procedure] (each PROC ...)

Returns a procedure that applies `PROC ...` to its arguments, and returns the result(s) of the last procedure application. For example

    (each pp eval)

is equivalent to

    (lambda args
      (apply pp args)
      (apply eval args) )

`(each PROC)` is equivalent to `PROC` and `(each)` is equivalent to `noop`.

### flip

    [procedure] (flip PROC)

Returns a two-argument procedure that calls `PROC` with its arguments swapped: <enscript highlight=scheme> (flip PROC) ⇔ (lambda (x y) (PROC y x)) </enscript>

### identity

    [procedure] (identity X)

Returns its sole argument `X`.

### project

    [procedure] (project N)

Returns a procedure that returns its `N`th argument (starting from 0).

### list-of

    [procedure] (list-of PRED)

Returns a procedure of one argument that returns `#t` when applied to a list of elements that all satisfy the predicate procedure `PRED`, or `#f` otherwise.

    ((list-of even?) '(1 2 3))   ==> #f
    ((list-of number?) '(1 2 3)) ==> #t

### noop

    [procedure] (noop X ...)

Ignores it's arguments, does nothing and returns an unspecified value.

### o

    [procedure] (o PROC ...)

A single value version of `compose` (slightly faster). `(o)` is equivalent to `identity`.

## Binary searching

### binary-search

    [procedure] (binary-search SEQUENCE PROC)

Performs a binary search in `SEQUENCE`, which should be a sorted list or vector. `PROC` is called to compare items in the sequence, should accept a single argument and return an exact integer: zero if the searched value is equal to the current item, negative if the searched value is less than the current item, and positive otherwise. Returns the index of the found value or `#f` otherwise.

Previous: Unit eval

Next: Unit srfi-1