Armin Rigo <arigo(a)tunes.org> wrote: However, the stream concept of all Prolog implementations I know seems very old-fashioned to me; doesn't any give the user a way to define his own streams (i.e. objects that would be usable in lieu of streams in the built-in predicates, but whose byte-level read and write operations are user-defined predicates) ? That would nicely solve this and other problems. Quintus Prolog has *serious* (but *SERIOUS*) support for just that.
I should know, I designed it. More than 10 years ago.
The main motivation was porting. The IBM mainframe operating systems MVS and CMS have record-oriented file systems which are different from each other and very different from UNIX. The Vax & Alpha operating system VMS has several kinds of file, and UNIX-like streams are not the normal kind of file. Mapping Prolog I/O -> C stdio -> native I/O was giving us performance costs you'd have nightmares about; we needed a reasonably adaptable interface so that you could write just a small amount of "glue" code for each host file system and then run at native speeds.
However, this was also used - to read and write encrypted files - to read and write compressed files - to do character code mapping - to implement string streams - to implement socket streams ...
And not just by Quintus. The I/O extension interface is fully documented in the Quintus manuals and is definitely intended for use by customers.
One difference between this and what Armin Rigo suggests is that the code you plugged in for your own stream types had to be written in C. In order to suit the host file system interfaces, we had to work in terms of packed mutable arrays of bytes (NOT a Prolog data type); the user functions had to be called from C; and there had to be no possibility of backtracking or failure. The point is that unless you want I/O to be so inefficient that you'd notice it even on a 10GHz machine, you really *REALLY* don't want to be doing byte-at-a-type operations, especially because quite a lot of operating systems don't *have* byte-at-a-time interfaces. You want to work in terms of a BLOCK at a time.
If the underlying system delivers a block at a time, and if you DON'T pass stream arguments around but always read from current input and write to current output, it is possible to implement get_{byte,code,char}/1 and put_{byte,code,char}/1 so that they work at close-to-C speeds, while *still* providing user extensibility. ============================================================================== Message: Address: Action: help majordomo(a)clip.dia.fi.upm.es Info. on useful commands subscribe ciao-users-request(a)clip.dia.fi.upm.es Subscribe to this list unsubscribe ciao-users-request(a)clip.dia.fi.upm.es Unsubscribe from this list <whatever> ciao-users(a)clip.dia.fi.upm.es Send message to list ----------------------------------------------------------------------------- Archived messages: http://www.clip.dia.fi.upm.es/Mail/ciao-users/ -----------------------------------------------------------------------------