- Daniel Weinreb qyj@tbbtyr.pbz [2011-06-30 18:12:02 -0400]:
Just for the record, I think extensible sequences would be really great!
Just for the record, CLISP has had extensible sequences since forever (far predating my involvement). See clisp/src/defseq.lisp which defines the standard sequences (vectors, lists et al); the infrastructure is in C file clisp/src/sequence.d:
/* O(seq_types) contains a list of type descriptors for sequences. These are simple-vectors of length 16, containing: SEQ-TYPE ; the type of the sequence, usually a symbol Access functions: SEQ-INIT SEQ-UPD SEQ-ENDTEST SEQ-FE-INIT SEQ-FE-UPD SEQ-FE-ENDTEST SEQ-ACCESS SEQ-ACCESS-SET SEQ-COPY SEQ-LENGTH SEQ-MAKE SEQ-ELT SEQ-SET-ELT SEQ-INIT-START SEQ-FE-INIT-END
Explanation of the functions SEQ-XXX:
A "pointer" is something, that can step through a sequence. There are pointers, that move from left to right; they are created with INIT or INIT-START, copied with COPY, UPD to advance one step, ENDTEST for testing, if they have reached the end of the Sequence, ACCESS for fetching the element, which is pointed to by the pointer, ACCESS-SET for setting the element, which is pointed to by the pointer. There are also pointers, that move from right to left; they are created with FE-INIT or FE-INIT-END, copied with COPY, FE-UPD for moving them one step to the left, FE-ENDTEST for testing, if they have reached the end of the Sequence, ACCESS for fetching the element, which is pointed to by the pointer. For them, ACCESS-SET does not work.
Movement operations: INIT (lambda (seq) ...) -> pointer returns the leftmost pointer of SEQ. UPD (lambda (seq pointer) ...) -> pointer returns a pointer to the adjacent neighbor at the right. SEQ-UPD can assume, that the right border of SEQ is not stepped over. ENDTEST (lambda (seq pointer) ...) -> bool tests, if this pointer is at the right end of SEQ. The same "FROM END" : FE-INIT (lambda (seq) ...) -> pointer returns the rightmost pointer of SEQ. FE-UPD (lambda (seq pointer) ...) -> pointer returns a pointer to the adjacent neighbor at the left. SEQ-FE-UPD can assume, that the left border of SEQ is not stepped over. FE-ENDTEST (lambda (seq pointer) ...) -> bool tests, if this pointer is at the left end of SEQ. Access via pointer: ACCESS (lambda (seq pointer) ...) -> value returns the element in SEQ the pointer is pointing to. ACCESS-SET (lambda (seq pointer value) ...) -> sets the element where the pointer is pointing to in SEQ, to the specified value. Works only for pointers that move from left to right! COPY (lambda (pointer) ...) -> pointer returns a copy of the Pointer to SEQ (because UPD and FE-UPD can operate destructively on the pointers) Total length: LENGTH (lambda (seq) ...) -> size returns the (active) length of the Sequence SEQ. MAKE (lambda (size) ...) -> sequence returns a newly allocated, empty sequence, that has the type SEQ-TYPE and the specified length. Access via index (usually more inefficient than via pointer): ELT (lambda (seq index) ...) -> value returns (ELT SEQ index) SET-ELT (lambda (seq index value) ...) -> sets (ELT SEQ index) to value. INIT-START (lambda (seq index) ...) -> pointer returns a pointer which moves in SEQ from left to right from Position index. Must execute the Range-test by itself. FE-INIT-END (lambda (seq index) ...) -> pointer returns a pointer which moves in SEQ from right to left from Position index. Must execute the Range-test by itself. */
of course, the presence of index accessors prevents things like hash tables, trees and maps from being considered sequences...