by Peter McGoron
This SRFI is currently in draft status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-274@nospamsrfi.schemers.org. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
A set of modest extensions to list conversion and list copying procedures is proposed that aligns them with other conversion and copying procedures and allows for some operations on improper and circular lists. Authors of further SRFIs that include list conversion procedures are encouraged to align their behavior with the behavior in this SRFI.
None at present.
In the R7RS, procedures
such as vector-copy and string->list received
optional start and end arguments. These arguments
allow one to copy segments of the string/vector without having to write
an explicit loop for it.
The procedures that operate on lists, such as list-copy
and list->string, do not have these extensions.
The start and end arguments are arguably more
useful for lists, because they allow for conversion of circular lists
to other data types without explicit loops or intermediate allocations.
But by allowing a selection of a portion of a list, the start
and end arguments run into specification issues when passed
dotted lists. How should they be handled?
Finite improper lists are an artefact of the representation of lists as cons cells. They are odd corner cases that many procedures will probably struggle with. But they have their uses, particularly for lazy computation, such as hygienic context propagation and odd sequences.
The common implementation of many procedures, such as
list-ref, list-tail, and map
(when operating on certain sets of multiple arguments),
work fine with improper lists. Critical here is that these procedures
only inspect a portion of a linked list: they don't care if list is
proper after those elements. An example of this behavior is the
“implementation responsibilities” section of many procedures in the
R6RS, which include
statements like
The implementation must check that list is a chain of pairs whose length is at least k. It should not check that it is a chain of pairs beyond this length.
This SRFI imposes a consistent method of dealing with improper lists
for copying and conversion procedures.
When end is supplied as an argument to a procedure,
a dotted list is treated as if it were a proper list: it
is treated as if its final cdr were the empty list, and not some non-list
object. This treatment does not extend to situations where end
is not supplied. For example:
(list->vector '(1 2 3 4 5 . 6))⇒ error(list->vector '(1 2 3 4 5 . 6) 2)⇒ error(list->vector '(1 2 3 4 5 . 6) 2 5)⇒ #(3 4 5)(list->vector '(1 2 3 4 5) 2 5)⇒ #(3 4 5)
This SRFI does not extend this behavior to all list procedures, only the procedures where it makes sense to add an explicit end argument. With the behavior described above, a simple higher-order procedure can convert a one-argument list conversion procedure into the type described by this SRFI:
(define (convert proc)
(case-lambda
((lst) (proc lst))
((lst start) (proc (drop lst start)))
((lst start end) (proc (take (drop lst start)
(- end start))))))
where drop and take are from
SRFI 1.
Implementations are encouraged to implement these procedures without
the extra allocations entailed by drop.
An improper list is a sequence of zero or more cons cells that do not end in an empty list. The elements of an improper list are the cars of the pairs of that sequence of cons cells. The length of an improper list is the number of cons cells before the final cdr. This number may be infinity. If the final cdr of an improper list is replaced with the empty list, then the length of the resulting proper list is equal to the length of the improper list.
Any non-pair and non-null object is a zero-length improper list. For clarity, the term im-list is used in argument lists when an argument is a possibly improper list.
The procedures in this SRFI all take optional start and end arguments. For each procedure taking an argument im-list, it is an error if start and end are not exact integers, and it is an error if the following formula is not satisfied:
0 ≤ start ≤ end ≤ length
where length is the length of im-list.
The index start is always inclusive and the index end is always exclusive.
Unless otherwise specified, it is an error to pass an improper
list to a procedure without an explicit end argument.
(In this SRFI, the only exception is list-copy.)
Each procedure in this SRFI is associated with multiple libraries:
at least one is the
library that contains the original specification of the procedure,
and another is specific to this SRFI. Implementations are encouraged
to have the same implementation from procedures exported from both
libraries: for example, list-copy from
(scheme base) should be the same as the one exported
from (srfi 274 base).
Square brackets [] are used to denote a group of arguments that are optional, but all arguments must be present or absent. If one pair of square brackets are nested in another pair, then the nested pair is optional even when the other arguments are supplied.
(list-copy
im-list
[start
[end]])
If neither start nor end is supplied, then this procedure returns a newly allocated copy of the sequence of pairs at the start of im-list. If im-list is an improper list, so is the result, and the final cdrs are the same in the sense of eqv?. An im-list which is not a list is returned unchanged. It is an error if im-list is circular.
If start but not end is supplied, this procedure
is equivalent to (list-copy (list-tail im-list start)).
If both start and end are supplied, then the startth pair to the endth pair are copied, and the list is terminated with an empty list.
In any case, only the pairs themselves are copied; the cars of the
pairs in the result are the same (in the sense of eqv?) as
the cars of the corresponding pairs that were copied from im-list.
(list-copy '(1 2 3 4 5 . 6))⇒ (1 2 3 4 5 . 6)(list-copy '(1 2 3 4 5 . 6) 2)⇒ (3 4 5 . 6)(list-copy '(1 2 3 4 5 . 6) 2 5)⇒ (3 4 5)(list-copy '(1 2 3 4 5) 2 5)⇒ (3 4 5)(list-copy #1='(1 2 #1#) 1 8)⇒ (2 1 2 1 2 1 2)
(list->string
im-list
[start
[end]])
It is an error if the elements of im-list are not characters.
Returns a newly allocated string formed from the elements of
im-list between start and end.
Order is preserved. This procedure and string->list
are inverses in the following sense for each appropriate
string, list, start, and
end:
(equal? (list->string (string->list string
start
end))
(substring string start end)) ⇒ #t
(equal? (string->list (list->string list
start
end))
(list-copy list start end)) ⇒ #t
(list->vector
im-list
[start
[end]])
Returns a newly created vector initialized to the elements of im-list between start and end.
(list->vector '(dah dah didah) 1 2)⇒ #(dah)(list->vector '(do be do be doo . dah) 2 5)⇒ #(do be doo)
These procedures are exported from SRFI libraries that are included
in R7RS Large.
If an implementation does not support a certain SRFI, then the
corresponding (srfi 274) sublibrary is not required.
Not all procedures that convert from list representations are included. Procedures that operate on assocation lists and lists that are treated as sets are excluded, because those lists are usually unordered.
(list->stream
im-list
[start
[end]])
(list->ideque
im-list
[start
[end]])
(list->generator
im-list
[start
[end]])
(list->⟨type⟩vector
im-list
[start
[end]])
A portable R7RS is available in the SRFI repository It has been tested to work in Chibi Scheme 0.11.0. Implementers are encouraged to align the behavior of the list conversion procedures in all specified libraries.
Thanks to those in Working Group 2 for discussing the semantics of these procedures. Topics related to this SRFI were discussed on the R7RS Large issue tracker (#341, #206) and in meetings on April 30th, 2026 and May 19th, 2026.
© 2026 Peter McGoron.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.