#!r6rs
(library (obj-lecture collection-delegate)
(export base-collection isEmpty addElem anyElem addAll toList)
(import (rnrs base))
(define (isEmpty c) ((c 'is-empty) c))
(define (addElem c v) ((c 'add-elem) c v))
(define (anyElem c) ((c 'some-elem) c))
(define (addAll c c2) ((c 'add-all-elems) c c2))
(define (toList c) ((c 'to-list) c))
(define (concrete->object)
(lambda (sym)
(cond
((eq? sym 'add-all-elems)
add-all-elems-impl)
((eq? sym 'to-list)
to-list-impl)
(else
(error 'unimplemented-message (symbol->string sym))))))
(define (base-collection)
(concrete->object))
(define (add-all-elems-impl self other-collection)
(if (isEmpty other-collection)
self
(let* ((val-and-other-rest (anyElem other-collection))
(val (list-ref val-and-other-rest 0))
(other-rest (list-ref val-and-other-rest 1)))
(addAll (addElem self val) other-rest))))
(define (to-list-impl self)
(if (isEmpty self)
'()
(let* ((val-and-other-rest (anyElem self))
(val (list-ref val-and-other-rest 0))
(other-rest (list-ref val-and-other-rest 1)))
(cons val (toList other-rest))))))