aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
blob: 7f1e455dc25f8a56926139e5af303c699c304e85 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Container Iterators

Container iterators are a generic way to access elements in a linearly
ordered collection, such as strings, vectors, and ordered sets.

"Iterators" are in the style of C++: they can (potentially) go forward,
backward, have start and end limits, etc. Not all operations are available
for a concrete iterator.

## Design

The iterators in this library are polymorphic and may only implement a
subset of the possible operations on an iterator, but Scheme has no standard
way to make extensible polymorphic functions. Instead of tying the library
to a specific implementations's object system, the iterators are closures
wrapped in record types. The iterators don't use inheritance or any message
passing: they are more like Go interfaces or Rust traits than the usual
Scheme object system.

Iterator types are created using

    (define-iterator-constructor (cstr cstr-args ...)
      ((method-name . method-formal) method-body ...)
      ...)

This creates a procedure `cstr` that when called creates an iterator whose
type is the `cstr` name as a symbol. Each `method` is defined as a lambda
that takes `method-formal` as arguments and evaluates `method-body` with
`cstr-args` in scope.

To invoke the method, use

    (define-invocation name args ...)

This defines a procedure `name` that takes an iterator and invokes the
method with the same name in the iterator with the number of args in args.

This object system could probably be ported to CLOS-style object systems
with a judicious enough use of macros. Properly implementing the bound
identifiers may require non-hygenic macros.