[[tags: manual]]
[[toc:]]

== Unit data-structures

This unit contains a collection of procedures related to data
structures.  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]])</procedure>

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])</procedure>

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)</procedure>

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])</procedure>

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)</procedure>

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


==== chop

<procedure>(chop LIST N)</procedure>

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.

<enscript highlight=scheme>
(chop '(1 2 3 4 5 6) 2) ==> ((1 2) (3 4) (5 6))
(chop '(a b c d) 3)     ==> ((a b c) (d))
</enscript>


==== compress

<procedure>(compress BLIST LIST)</procedure>

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

<enscript highlight=scheme>
(define nums '(99 100 110 401 1234))
(compress (map odd? nums) nums)      ==> (99 401)
</enscript>


==== flatten

<procedure>(flatten LIST1 ...)</procedure>

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


==== intersperse

<procedure>(intersperse LIST X)</procedure>

Returns a new list with {{X}} placed between each element.


==== join

<procedure>(join LISTOFLISTS [LIST])</procedure>

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

<enscript highlight=scheme>
(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)
</enscript>

{{join}} could be implemented as follows:

<enscript highlight=scheme>
(define (join lstoflsts #!optional (lst '()))
  (apply append (intersperse lstoflists lst)) )
</enscript>


==== shuffle

<procedure>(shuffle LIST RANDOM)</procedure>

Returns {{LIST}} with its elements sorted in a random order given by
procedure {{RANDOM}}. 


==== tail?

<procedure>(tail? X LIST)</procedure>

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

=== Queues


==== list->queue

<procedure>(list->queue LIST)</procedure>

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)</procedure>

Returns a newly created queue.


==== queue?

<procedure>(queue? X)</procedure>

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


==== queue->list

<procedure>(queue->list QUEUE)</procedure>

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)</procedure>

Adds {{X}} to the rear of {{QUEUE}}.


==== queue-empty?

<procedure>(queue-empty? QUEUE)</procedure>

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


==== queue-first

<procedure>(queue-first QUEUE)</procedure>

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


==== queue-last

<procedure>(queue-last QUEUE)</procedure>

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


==== queue-remove!

<procedure>(queue-remove! QUEUE)</procedure>

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)</procedure>

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)</procedure>

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><br>
<procedure>(merge! LIST1 LIST2 LESS?)</procedure>

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><br>
<procedure>(sort! SEQUENCE LESS?)</procedure>

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


==== sorted?

<procedure>(sorted? SEQUENCE LESS?)</procedure>

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

==== topological-sort

<procedure>(topological-sort DAG PRED)</procedure>

Sorts the directed acyclic graph dag {{DAG}} so that for every edge from vertex
u to v, u will come before v in the resulting list of vertices.

{{DAG}} is a list of sublists. The car of each sublist is a
vertex. The cdr is the adjacency list of that vertex, i.e. a list of
all vertices to which there exists an edge from the car vertex.
{{pred}} is procedure of two arguments that should compare vertices
for equality.

Time complexity: O (|V| + |E|)

<enscript highlight=scheme>
(require 'tsort)
(topological-sort
       '((shirt tie belt)
         (tie jacket)
         (belt jacket)
         (watch)
         (pants shoes belt)
         (undershorts pants shoes)
         (socks shoes))
       eq?)

=>

(socks undershorts pants shoes watch shirt belt tie jacket)
</enscript>

=== Random numbers


==== random-seed

<procedure>(random-seed [SEED])</procedure>

Seeds the random number generator with {{SEED}} (an exact integer) or 
{{(current-seconds)}} if {{SEED}} is not given.


=== Strings


==== conc

<procedure>(conc X ...)</procedure>

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

<enscript highlight=scheme>
(define (conc . args)
  (apply string-append (map ->string args)) )
</enscript>



==== ->string

<procedure>(->string X)</procedure>

Returns a string-representation of {{X}}.


==== string-chop

<procedure>(string-chop STRING LENGTH)</procedure>

Returns a list of substrings taken by ''chopping'' {{STRING}} every {{LENGTH}}
characters:

<enscript highlight=scheme>
(string-chop "one two three" 4)  ==>  ("one " "two " "thre" "e")
</enscript>



==== string-chomp

<procedure>(string-chomp STRING [SUFFIX])</procedure>

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><br>
<procedure>(string-compare3-ci STRING1 STRING2)</procedure>

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])</procedure>

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

<enscript highlight=scheme>
(string-intersperse '("one" "two") "three")
</enscript>

is equivalent to

<enscript highlight=scheme>
(apply string-append (intersperse '("one" "two") "three"))
</enscript>


==== string-split

<procedure>(string-split STRING [DELIMITER-STRING [KEEPEMPTY]])</procedure>

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:

<enscript highlight=scheme>
(string-split "one  two  three") ==> ("one" "two" "three")
(string-split "foo:bar::baz:" ":" #t) ==> ("foo" "bar" "" "baz" "")
</enscript>


==== string-translate

<procedure>(string-translate STRING FROM [TO])</procedure>

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)</procedure>

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}}:

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


==== substring=?

<procedure>(substring=? STRING1 STRING2 [START1 [START2 [LENGTH]]])</procedure><br>
<procedure>(substring-ci=? STRING1 STRING2 [START1 [START2 [LENGTH]]])</procedure>

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><br>
<procedure>(substring-index-ci WHICH WHERE [START])</procedure>

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}}.


==== reverse-string-append

<procedure>(reverse-string-append LIST)</procedure>

{{(apply string-append (reverse LIST))}}


=== Combinators


==== any?

<procedure>(any? X)</procedure>

Ignores its argument and always returns {{#t}}. This is actually useful sometimes.


==== none?

<procedure>(none? X)</procedure>

Ignores its argument and always returns {{#f}}. This is actually useful sometimes.


==== always?

<procedure>(always? X)</procedure>

Ignores its arguments and always returns {{#t}}. This is actually useful sometimes.


==== never?

<procedure>(never? X)</procedure>

Ignores its arguments and always returns {{#f}}. This is actually useful sometimes.


==== constantly

<procedure>(constantly X ...)</procedure>

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

<enscript highlight=scheme>
(constantly X) <=> (lambda args X)
</enscript>


==== complement

<procedure>(complement PROC)</procedure>

Returns a procedure that returns the boolean inverse of {{PROC}}.

<enscript highlight=scheme>
(complement PROC) <=> (lambda (x) (not (PROC x)))
</enscript>


==== compose

<procedure>(compose PROC1 PROC2 ...)</procedure>

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

<enscript highlight=scheme>
(compose F G) <=> (lambda args
                      (call-with-values
                         (lambda () (apply G args))
                         F))
</enscript>

{{(compose)}} is equivalent to {{values}}.


==== conjoin

<procedure>(conjoin PRED ...)</procedure>

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 ...)</procedure>

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 ...)</procedure>

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

<enscript highlight=scheme>
(each pp eval)
</enscript>

is equivalent to

<enscript highlight=scheme>
(lambda args 
  (apply pp args)
  (apply eval args) )
</enscript>

{{(each PROC)}} is equivalent to {{PROC}} and {{(each)}} is equivalent to
{{void}}.


==== flip

<procedure>(flip PROC)</procedure>

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)</procedure>

Returns its sole argument {{X}}.


==== list-of?

<procedure>(list-of? PRED)</procedure>

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.

<enscript highlight=scheme>
((list-of? even?) '(1 2 3))   ==> #f
((list-of? number?) '(1 2 3)) ==> #t
</enscript>


==== o

<procedure>(o PROC ...)</procedure>

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


=== Binary searching


==== binary-search

<procedure>(binary-search SEQUENCE PROC)</procedure>

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 expand]]

Next: [[Unit ports]]
