; Copyright (c) 2003 RT Happe ; See the file COPYING distributed with the Scheme Untergrund Library ;;; a uniform framework for sequence as data + behaviour ;;; in other words: mucho indirection here [ could reduce it ] ;; such records represent behavioural sequence types S ;; maker : integer [t] -> S -- like MAKE-VECTOR ;; predicate : any -> boolean -- like VECTOR? ;; getter : S integer --> any -- like VECTOR-REF ;; setter : S integer any --> unspecified -- like VECTOR-SET! ;; meter : S --> integer -- like VECTOR-LENGTH (define-record-type :sequence-behavior (make-sequence-behavior maker predicate getter setter meter) sequence-behavior? (maker sequence-behavior:maker) (predicate sequence-behavior:predicate) (getter sequence-behavior:getter) (setter sequence-behavior:setter) (meter sequence-behavior:meter)) ;; underlying sequence data + behavioral sequence type (define-record-type :absequence ;; avoiding the make-absequence namning pattern for good reason (make-absequence-record behavior data) absequence? (behavior absequence:behavior) (data absequence:data)) (define (absequence-ref s k) ((sequence-behavior:getter (absequence:behavior s)) (absequence:data s) k)) (define (absequence-set! s k x) ((sequence-behavior:setter (absequence:behavior s)) (absequence:data s) k x)) (define (absequence-length s) ((sequence-behavior:meter (absequence:behavior s)) (absequence:data s))) (define (make-absequence/behavior sb k . maybe-fill) (make-absequence-record sb (apply (sequence-behavior:maker sb) k maybe-fill))) (define (list->absequence/behavior sb xs . opts) (let-optionals opts ((start 0) (end (length xs))) (assert (<= 0 start end)) (let ((s (make-absequence/behavior sb (- end start)))) (do ((i 0 (+ i 1)) (xs xs (cdr xs))) ((= i end) s) (absequence-set! s (- i start) (car xs)))))) (define (absequence/behavior sb . args) (list->absequence/behavior sb args)) (define-record-discloser :absequence (lambda (r) (let ((sq (absequence:data r))) (if (or (vector? sq) (string? sq) (pair? sq)) `(absequence:data ,sq) `(absequence)))))