[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Names and primitives in SRFI 56



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