[Larceny-users] Ports' type changes unexpectedly

Derick Eddington derick.eddington at gmail.com
Thu Mar 19 18:21:41 EDT 2009


On Thu, 2009-03-19 at 09:21 -0400, William D Clinger wrote:
> Derick Eddington wrote:
> > Closing string input ports or string output ports changes them from
> > textual to binary and they are no longer considered input or output
> > ports.  Ikarus, PLT, and Ypsilon don't do this.  I'm not sure what R6RS
> > requires about this,
> 
> The R6RS library 8.2.6 specification of close-port says
> a closed port is still a port, but does not say a closed
> input port is still an input port, nor does it say a
> closed output port is still an output port.  In fact,
> it says the opposite, albeit not as explicitly as it
> should have.

I don't think it says or implies the opposite:

> The R6RS library 8.2.6 specification of transcoded-port
> says the closed binary port "cannot be used by the input
> and output operations described in this chapter."

But that applies only to binary ports closed in the special way
transcoded-port does, as the context of that quote makes clear.  I don't
see how it applies to any other closed ports.  Even if it could be
construed to apply, "cannot be used by the input and output operations"
doesn't mean the types of ports must change.

> The
> specifications of those operations, e.g. port-eof? and
> flush-output-port, say they accept an input-port or an
> output-port as their argument.  If a closed port were
> still an input-port or an output-port, then a closed
> port would be acceptable as an input to one of those
> procedures.

It would be an acceptable argument type, but this doesn't mean it would
be acceptable for performing I/O because close-port "[renders] the port
incapable of delivering or accepting data".

> Since the R6RS library document says a closed port is
> not acceptable to the port-eof? and flush-output-port
> procedures, a closed port cannot be an input port or an
> output port.

I really don't think it says that or can be construed to imply that.

port-eof? "returns #t if the lookahead-u8 procedure (if input-port is a
binary port) or the lookahead-char procedure (if input-port is a textual
port) would return the end-of-file object, and #f otherwise."  If a
closed port, which is still an input port and is still either binary or
textual, is given, I think it's clear that port-eof? returns #F (which
Ikarus does, PLT does not, and Ypsilon does not) because lookahead-u8 or
lookahead-char would not return the end-of-file object.

flush-output-port "flushes any buffered output from the buffer of
output-port to the underlying file, device, or object."  If a closed
port, which is still an output port, is given, I think it's clear it's
unspecified what happens.  If there's no longer buffered output or a
buffer, then there can't be "any buffered output" or "the buffer" so
there's nothing for the procedure to do.  If there's no longer an
underlying file, device, or object, then there can't be "the file,
device, or object" so there's nothing for the procedure to do.  If those
things still exist and the procedure attempts to flush, I think it's
clear an &i/o-write exception is raised, because it's for "write errors
that occurred during an I/O operation", because a closed output port is
"incapable of delivering ... data".

> That means the behavior of Ikarus, PLT, and Ypsilon is
> not consistent with R6RS library chapter 8.

I think both Larceny with shape-shifting port types and implementations
with port types which stay the same are conforming.

> > but this is unexpected and could cause serious confusion.
> 
> The R6RS mandates many behaviors that are unexpected and
> could cause serious confusion.  

I agree.  But this case is not mandated to be like that.

> In this case, however,
> Larceny's R6RS-conforming behavior is consistent with
> long-standing practice in R5 Scheme, 

I still think it has too much potential to be seriously confusing.  For
what benefit?  It's confusing because users get control flow based on
"not a certain port type" but they're convinced the offending object
must be a certain port type because they traced where it came from and
they haven't discovered, memorized, and remembered that Larceny changes
the type on them.  I'm glad I randomly noticed this instead of racking
my brain for hours about how the hell could it not be a certain port
type when a complex program breaks because of this.  I would much rather
have a program break when it tries to perform I/O on a closed port and
give me an exception saying "port is closed".

> and is less
> confusing than having input ports for which port-eof?
> would raise an exception or having output ports for which
> flush-output-port would raise an exception.  

I don't understand this argument because by changing the types of closed
ports to be an abstract androgynous type, the procedures with arguments
which are required to be input or output or textual or binary ports will
always raise an exception when given a closed port because the argument
type is invalid.  How is this less confusing?

> The confusion,
> it would seem, comes from the violation of R6RS semantics
> by Ikarus, PLT, and Ypsilon.

I don't think Ikarus is violating.  PLT and Ypsilon are w.r.t.
port-eof?.  The confusion will come when "not a certain port type"
behaviors mislead users.

[Aside: I do think the R6RS ports design is certainly broken in other
ways.]

Best,

-- 
: Derick
----------------------------------------------------------------




More information about the Larceny-users mailing list