[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.3.1 Mapping over collection

Generic function: fold proc knil coll coll2 ...
This is a natural extension of fold in SRFI-1 (See section 10.2.5 List fold, unfold & map).

For each element Ei in the collection coll, proc is called as (proc Ei Ri-1), where Ri-1 is the result of (i-1)-th invocation of proc for i > 0, and R0 is knil. Returns the last invocation of proc.
 
(fold + 0 '#(1 2 3 4)) => 10
(fold cons '() "abc")  => (#\c #\b #\a)

If the coll is a sequence, it is guaranteed that the elements are traversed in order. Otherwise, the order of iteration is undefined.

You can fold more than one collection, although it doesn't make much sense unless all of the collections are sequences. Suppose E(k, i) for i-th element of k-th collection. proc is called as
 
(proc E(0,i) E(1,i) ... E(K-1,i) Ri-1)

Different types of collections can be mixed together.

 
(fold acons '() "abc" '#(1 2 3))
  => ((#\c 3) (#\b 2) (#\a 1))

;; calculates dot product of two vectors
(fold (lambda (a b r) (+ (* a b) r)) 0
      '#(3 5 7) '#(2 4 6))
  => 68

When more than one collection is given, fold terminates as soon as at least one of the collections exhausted.

Generic function: map proc coll coll2 ...
This extends the built-in map (See section 6.15.1 Procedures). Apply proc for each element in the collection coll, and returns a list of the results.

If the coll is a sequence, it is guaranteed that the elements are traversed in order. Otherwise, the order of iteration is undefined.

If more than one collection is passed, proc is called with elements for each collection. In such case, map terminates as soon as at least one of the collection is exhausted. Note that passing more than one collection doesn't make much sense unless all the collections are sequences.

 
(map (lambda (x) (* x 2)) '#(1 2 3))
  => #(2 4 6)

(map char-upcase "abc")
  => (#\A #\B #\C)

(map + '#(1 2 3) '#(4 5 6))
  => (5 7 9)

map always returns a list. If you want to get the result in a different type of collection, use map-to described below. If you wonder why (map char-upcase "abc") doesn't return "ABC", read the discussion in the bottom of this subsection.

Generic function: map-to class proc coll coll2 ...
This works the same as map, except the result is returned in a collection of class class. Class must be a collection class and have a builder interface (See section 9.3.4 Fundamental iterator creators).

 
(map-to <vector> + '#(1 2 3) '#(4 5 6))
  => #(5 7 9)

(map-to <string> char-upcase "def")
  => "DEF"

(map-to <vector> char=? "bed" "pet")
  => #(#f #t #f)

Generic function: for-each proc coll coll2 ...
Extension of built-in for-each (See section 6.15.1 Procedures). Applies proc for each elements in the collection(s). The result of proc is discarded. The return value of for-each is undefined.

If the coll is a sequence, it is guaranteed that the elements are traversed in order. Otherwise, the order of iteration is undefined.

If more than one collection is passed, proc is called with elements for each collection. In such case, for-each terminates as soon as one of the collection is exhausted. Note that passing more than one collection doesn't make much sense unless all the collections are sequences.

Generic Function: fold$ proc
Generic Function: fold$ proc knil
Generic Function: map$ proc
Generic Function: for-each$ proc
Partial-application version of fold, map and for-each.

Discussion: It is debatable what type of collection map should return when it operates on the collections other than lists. It may seem more "natural" if (map * '#(1 2) '#(3 4)) returns a vector, and (map char-upcase "abc") returns a string.

Although such interface seems work for simple cases, it'll become problematic for more general cases. What type of collection should be returned if a string and a vector are passed? Furthermore, some collection may only have iterator interface but no builder interface, so that the result can't be coerced to the argument type (suppose you're mapping over database records, for example). And Scheme programmers are used to think map returns a list, and the result of map are applied to the procedures that takes list everywhere.

So I decided to add another method, map-to, to specify the return type explicitly The idea of passing the return type is taken from CommonLisp's map function, but taking a class metaobject, map-to is much flexible to extend using method dispatch. This protocol ("-to" variant takes a class metaobject for the result collection) is used thoughout the collection framework.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by Ken Dickey on November, 28 2002 using texi2html