At Mon, 27 Sep 2004 22:03:48 -0700, Dale Jordan wrote:
>
> A number of Schemes (Scheme48 and Chicken, at least) support
> byte-vectors for doing aggregate binary io. This seems to satisfy most
> needs for doing something beyond simple scalar io, while still allowing
> the application to perform whatever interpretation is necessary.
>
> I suppose some might consider it onerous to require implementing such a
> data type for this SRFI, but I consider byte-vectors extraordinarily useful.
Would these be equivalent to SRFI-4 u8vectors and SRFI-47 au8 arrays
(which have the comment "Byte arrays can be implemented independently
and distinctly from strings")?
I did consider utilities to read/write directly to/from these data
types, but came across a few stumbling blocks. First, there are two
competing SRFIs. Second there is the question of interface - do you
provide separate procedures on each type:
(read-u8block! u8vec port) ; fill u8vec from port, SRFI-4 style
(read-u16-block! u16vec port)
...
or do generic dispatch on type:
(read-array! u8vec port) ; fill u8vec from port, SRFI-47 style
With generic dispatch the reference implementation becomes slow and
non-extensible. This would still be my preference, but it's enough
added complexity that I would rather it go in a separate SRFI.
Basically all I wanted for SRFI-56 was to make binary I/O *possible*
via 4 primitives and throw in some useful library procedures that
wouldn't really be controversial.
Regardless, this feature is orthogonal to the current debate which is
that *if* you allow binary operations (including potentially
operations on byte arrays), can you perform said operations on all
ports and if not how do you designate for a given port if it supports
binary vs character operations? I'm sorry for the delay, I really
haven't come up with any better ideas, so when I release an updated
version (RSN) the API will become (with hopefully better wording):
;; new port predicates, not necessarily disjoint
(binary-port? port)
(character-port? port)
;; new procedures such that the port generated is guaranteed to
;; return #t for BINARY-PORT?, whereas the R5RS equivalents always
;; return #t for CHARACTER-PORT?.
(open-binary-input-file file)
(open-binary-output-file file)
(call-with-input-binary-file file proc)
(call-with-output-binary-file file proc)
(with-input-from-binary-file file thunk)
(with-output-to-binary-file file thunk)
READ-CHAR, WRITE-CHAR, READ, WRITE, DISPLAY and all other R5RS I/O
procedures are guaranteed to be allowed on any port for which
CHARACTER-PORT? returns #t, assuming all other qualifications are met
(i.e. you're not trying to read from an OUTPUT-PORT?).
READ-BYTE, WRITE-BYTE, PEEK-BYTE and BYTE-READY? plus the library
procedures provided in SRFI-56 are guaranteed to be allowed on any
port for which BINARY-PORT? returns #t, assuming other qualifications
are met.
String ports are guaranteed to return #t for at least CHARACTER-PORT?.
Implementations are free and encouraged to make no distinction between
the port types, while program authors are encouraged to use the
*-binary-* equivalents for port creation when they don't intend to
perform any character-level operations, both for portability and as a
reminder of the purpose of the port. When both binary and character
operations are to be used, the R5RS procedures are preferred.
--
Alex