On Thu, Sep 19, 2019 at 8:07 AM Lassi Kortela <xxxxxx@lassi.io> wrote:

R6RS has custom ports in the standard. Common Lisp has Gray streams as a
popular extension to the standard. Bytevector generators and
accumulators (SRFI 158) are a poor man's approximation.

On the contrary, I think they are far superior.  They are simple, they are built on closures, which every Scheme has, and they require no changes to any implementation.  I actually have a pre-SRFI to convert port operations to gens/accs:  <https://bitbucket.org/cowan/r7rs-wg1-infra/src/default/PortOperationsCowan.md>.  They don't provide random access, but neither do non-R6RS Schemes (at least not portably).

This is a good place to talk about Service Provider Interfaces (SPIs), which I promised to explain before.

Basically, SPIs are a formalization of the Facade pattern.  There is a client API  whose implementation defers to one or more implementations that provide the code to do the actual work.  The SPI is precisely the common API of these plugins, and it may or may not correspond closely to the client API.

In Java, there is a Java interface class for every such API, specifying exactly what any SPI needs to provide.  Because method names are automatically qualified by their class in Java, it makes no difference that the plugins have conflicting names.  The plugin can provide an object satisfying the SPI and then it will work with the client API (which has to provide a way to register and perhaps unregister plugins).

But what do we do in Scheme when there's a mismatch between what the SPI expects and what the plugin provides?  There is no formal definition of an SPI (or any API, for that matter): we cannot even introspect on libraries to see what they export.  Ports are particularly bad in this respect, because what operations exist may depend on what kind of port this is.  Directory ports in Gambit, for example, are like any other input ports, except that read returns the next directory entry (doesn't parse S-expressions at all) and read-char, read-string, read-line just don't work.  Furthermore, if the client API changes, all the plugins break horribly at run time instead of (as in Java) failing to compile.

What to do, what to do?  I wish I knew.



John Cowan          http://vrici.lojban.org/~cowan        xxxxxx@ccil.org
De plichten van een docent zijn divers, die van het gehoor ook.
      --Edsger Dijkstra