On Sep 14, 2009, at 10:23 AM, John Cowan wrote: > This is a proposal for adding custom I/O ports to R7RS small Scheme. > I am publishing this document to invite wide comment. There is > nothing > official about it. I retain sole responsibility for it, including > all errors. > > Custom ports in R6RS are like those in most systems: basically a set > of > procedures which are invoked when standard port operations are > executed. > For example, if you create a custom character input port, you may then > call read on it, and the normal read algorithm will be invoked, but it > will read characters not from a file or a string, but rather from > one of > the procedures set up when the port was created, the one corresponding > to read-char. > > However, the R6RS interface to creating custom ports, like all > others I > have seen, is highly inflexible. The set of procedures varies > depending > on whether the port is input or output, binary or character-based. > If you get the order of procedures wrong, you lose. And if new basic > procedures or port types are added by an implementation, the existing > port constructors will require supplementation with new constructors. > > Therefore, I am proposing a pattern whereby a custom port is not a > record > of procedures, but a special case of what Common Lisp calls a > disembodied > property list: a map from symbols to procedures. (This does not > imply, of > course, that a custom port must be implemented using a list.) When > such > a port is created, it has a variety of default behaviors corresponding > to the standard port operations. The resulting port isn't good for > anything much. > > To make the port useful, you replace its behaviors: for example, you > can redefine read-char with an implementation-dependent procedure that > reads from a network port. You can replace not only the lowest-level > ones but higher-level ones: for example, you can redefine read to > do non-Scheme parsing if you want. Removing a behavior causes it to > revert to the default. Some symbols and their associated behaviors > are > input-related, some are output-related, some are neither. You can > also > change non-standardized behaviors which your Scheme implementation > provides. > > 5 identifiers are bound to procedures by this proposal: > > (port? object) answers true if its argument is a port. This is made > necessary by the fact that custom ports can be input ports, output > ports, both, or neither. A custom port returns #t to input-port? > if it > has a non-default behavior for any input-related symbol. Likewise, > it returns #t to output-port? if it has a non-default behavior for any > output-related symbol. > > (make-custom-port) returns a custom port with default behaviors. > > (custom-port-get custom-port symbol) returns the behavior of the > custom-port associated with the symbol. The standard symbols are the > names of standard procedures, and the procedures returned take the > same > number of arguments with the same semantics as those standard > procedures. > > (custom-port-set! custom-port symbol procedure) changes the behavior > associated with symbol in custom-port to procedure. > > (custom-port-remove! custom-port symbol) reverts the behavior > associated > with symbol in custom-port to the default. > > Here are the 6 standard input-related symbols and their default > behaviors. > > read Performs the normal read algorithm > read-char Returns an eof-object > peek-char Returns an eof-object > read-line Performs the normal read-line algorithm > read-u8 Returns an eof-object > peek-u8 Returns an eof-object > > Here are the 5 standard output-related symbols and their default > behaviors. > > write Performs the normal write algorithm > display Performs the normal display algorithm > newline Performs the normal newline algorithm > write-char Does nothing > write-u8 Does nothing > > Here are the remaining 2 standard symbols and their default behaviors. > > port-u8-position Does nothing > set-port-u8-position! Does nothing
I've read over this proposal, and I have some substantial issues with it: * I don't think Small Scheme needs any definition of ports which is more complex than that needed to read program text. Adding binary ports adds too much in the way of assumptions about the environment in which the small scheme implementation lives. * I don't like the property list method you're using for custom port objects. What is wrong with `port-set-read-procedure!', `port-set- write-procedure!', etc.? How does naming some procedures with two symbols instead of one help anything? * I don't like the assumption that ports are bivalent. This is a complex thing to get right. One can take a file which is properly encoded in UTF-8 and wind up introducing a decode error by mixing binary and character operations on the same port. Bivalent ports can be completely and usefully provided by a library on top of binary ports if users desire them. * I don't like the assumption that ports should naturally provide both input and output. This isn't true in general. It's better to separate out the types and have some way of creating an I/O port out of an input port and an output port. * I don't like the inclusion of `read-line' and `newline' procedures. Why is it useful to change the behavior of these procedures? This seems like an opportunity for error. * I don't like the hook for `read' and `write'. I don't even know why it's there. If I'm going to replace it with something else, isn't that something deserving of a different name? I think what the R6RS provided is an attempt to get all of these fiddly little details right. If anything goes into a smaller language, it needs to avoid these details as much as possible, in particular the details of how to work with encodings. Otherwise you're going to wind up with something that is too underspecified to work in general, or just missing important functionality. I think it'd be OK to add in the concept of a user-defined *binary* port, because experience shows that the details can be taken care of in a library if binary ports are provided. -- Brian Mastenbrook [email protected] http://brian.mastenbrook.net/ _______________________________________________ r6rs-discuss mailing list [email protected] http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss
