Up: Eager comprehensions   [Contents][Index]


2.10.1 Examples using eager comprehension

In all of the examples below, the user must include the module ‘(data rope)’.

  1. We may convert a list of strings into a rope:
    (rope-ec (:list s '("hello" " " "world")) s)
      ⇒ "hello world"
    

    Example 2.11: Creating a rope from a list of strings.

  2. We can eagerly comprehend over a portion of a rope, or even comprehend backwards:
    (define r (rope "hello " "world"))
    
    (list-ec (:rope s r 3 9) s)
      ⇒ ("lo " "wor")
    
    (list-ec (:rope s r 8 2) s)
      ⇒ ("wor" "lo ")
    

    Example 2.12: Eagerly comprehending over a portion of a rope, forward or backward.

  3. We may create a rope from the mapped contents of a list without an intermediate list, while setting the max leaf size to be ‘5’:
    (rope->cons
      (parameterize ((*rope-maximum-leaf-size* 5))
        (rope-ec (:list s '("foo" "bar" "baz"))
                 (string-append s (string-upcase s)))))
      ⇒ ((("fooFO" . "O") . "barBA") ("R" . "bazBA") . "Z")
    

    Example 2.13: Creating a rope from mapped contents of a list.

    Note that the above algorithm prefers fragmented ropes to tightly defragmented ones: the creation of the latter require more memory and time (potentially shifting the entire rope).

  4. Assume that we have a thunk procedure ‘thunk’ that generates strings and denotes end-of-generation by returning an empty string. We may produce a rope out of it using:
    (rope-ec (:do ((s (thunk)))
                  (not (string-null? s))
                  ((thunk)))
             s)
    

    Example 2.14: Creating a rope from a generating thunk.

  5. In similar vein to the previous example, but using additional goodies from SRFI-42, we may create a rope containing the contents of the file ‘example.txt’ as follows:
    (use-modules (ice-9 textual-ports))
    
    ;; We use a single buffer for the reading, to avoid reallocating
    ;; unnecessary buffers.
    (let ((bufsiz 4096))
      (call-with-input-file "example.txt"
        (lambda (port)
          (rope-ec (:let s (make-string bufsiz))
                   (:port x port
                          (lambda (p)
                            (let ((n (get-string-n! p s 0
                                                    (string-length s))))
                              (if (eof-object? n) n
                                  (substring/shared s 0 n)))))
                   x))))
    

    Example 2.15: Creating a rope from a file.

  6. Let us process the characters of the rope in reverse, first by reversing the order of generated strings, and then by examining the strings themselves in reverse, and then finally concatenating everything in a new string:
    (define r (string->random-rope "seiks eulB"))
    (string-ec (:rope s r (1- (rope-length' r)) -1)
               (:range i (1- (string-length s)) -1 -1)
               (string-ref s i))
      ⇒ "Blue skies"
    

    Example 2.16: Processing the characters of a rope in reverse.

    Note in the above example that the :rope generator accepts start and end indices such that start > end, and then it traverses the rope in reverse.

  7. We may wish to process multiple ropes at once. SRFI-42 does not provide a ‘:sequential’ qualifier that would permit this transparently, due to the limitations of ‘define-syntax’ with which the SRFI is implemented. Thankfully we can accomplish the same effect by creating a list of ropes that contains all of our ropes in order.
    (define r1 (cons->rope '(("foo" . "bar") . "baz")))
    (define r2 (string->random-rope "abcdef"))
    (rope->string
      (rope-ec (:list r (list r1 ": " r2))
               (:rope s r)
               s))
      ⇒ "foobarbaz: abcdef"
    

    Example 2.17: Processing multiple ropes together.


Up: Eager comprehensions   [Contents][Index]