Discussion:
[Larceny-users] Ports' type changes unexpectedly
Derick Eddington
2009-03-19 05:25:09 UTC
Permalink
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, but this is unexpected and could cause serious
confusion.

I made a portable test program to check ports' state as they change from
initial to EOF to closed. It's attached, and below is its current
failing output. I only tested string input and output ports, but the
program is made to easily add more tests for all the different ways of
making various types of ports.


[***@eep:~/t10]-> larceny -r6rs -program ports-state-tests.sps

--------------------------------------------------
Initial: string-input-port := (open-string-input-port "blah")
--------------------------------------------------

(port? string-input-port) => #t ; correct

(textual-port? string-input-port) => #t ; correct

(binary-port? string-input-port) => #f ; correct

(input-port? string-input-port) => #t ; correct

(output-port? string-input-port) => #f ; correct

(port-eof? string-input-port) => #f ; correct

--------------------------------------------------
EOF: string-input-port
--------------------------------------------------

(port? string-input-port) => #t ; correct

(textual-port? string-input-port) => #t ; correct

(binary-port? string-input-port) => #f ; correct

(input-port? string-input-port) => #t ; correct

(output-port? string-input-port) => #f ; correct

(port-eof? string-input-port) => #t ; correct

(port-transcoder string-input-port) => 64 ; correct

(port-has-port-position? string-input-port) => #t ; correct

(port-has-set-port-position!? string-input-port) => #t ; correct

--------------------------------------------------
Closed: string-input-port
--------------------------------------------------

(port? string-input-port) => #t ; correct

(textual-port? string-input-port) => #f ; *** failed ***
; expected result: #t

(binary-port? string-input-port) => #t ; *** failed ***
; expected result: #f

(input-port? string-input-port) => #f ; *** failed ***
; expected result: #t

(output-port? string-input-port) => #f ; correct

(port-transcoder string-input-port) => 64 ; correct

(port-has-port-position? string-input-port) => #t ; correct

(port-has-set-port-position!? string-input-port) => #t ; correct

--------------------------------------------------
Initial: string-output-port := (let-values (((sop get) (open-string-output-port))) sop)
--------------------------------------------------

(port? string-output-port) => #t ; correct

(textual-port? string-output-port) => #t ; correct

(binary-port? string-output-port) => #f ; correct

(input-port? string-output-port) => #f ; correct

(output-port? string-output-port) => #t ; correct

--------------------------------------------------
Closed: string-output-port
--------------------------------------------------

(port? string-output-port) => #t ; correct

(textual-port? string-output-port) => #f ; *** failed ***
; expected result: #t

(binary-port? string-output-port) => #t ; *** failed ***
; expected result: #f

(input-port? string-output-port) => #f ; correct

(output-port? string-output-port) => #f ; *** failed ***
; expected result: #t

(port-transcoder string-output-port) => 64 ; correct

(port-has-port-position? string-output-port) => #t ; correct

(port-has-set-port-position!? string-output-port) => #t ; correct

; *** checks *** : 30 correct, 6 failed. First failed example:

(textual-port? string-input-port) => #f ; *** failed ***
; expected result: #t
[***@eep:~/t10]->
--
: Derick
----------------------------------------------------------------
William D Clinger
2009-03-19 13:21:23 UTC
Permalink
Post by Derick Eddington
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.

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." 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.

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.

That means the behavior of Ikarus, PLT, and Ypsilon is
not consistent with R6RS library chapter 8.
Post by Derick Eddington
but this is unexpected and could cause serious confusion.
The R6RS mandates many behaviors that are unexpected and
could cause serious confusion. In this case, however,
Larceny's R6RS-conforming behavior is consistent with
long-standing practice in R5 Scheme, 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. The confusion,
it would seem, comes from the violation of R6RS semantics
by Ikarus, PLT, and Ypsilon.

The fact that Larceny's binary-port? predicate returns
true for a closed port is a bug, which we will fix. As
explained above, the R6RS library document requires
binary-port? to return false when its argument is a
closed port.

Will
Derick Eddington
2009-03-19 22:21:41 UTC
Permalink
Post by William D Clinger
Post by Derick Eddington
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.
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.
Post by William D Clinger
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".
Post by William D Clinger
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".
Post by William D Clinger
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.
Post by William D Clinger
Post by Derick Eddington
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.
Post by William D Clinger
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".
Post by William D Clinger
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?
Post by William D Clinger
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
----------------------------------------------------------------
Derick Eddington
2009-03-19 22:35:30 UTC
Permalink
Post by Derick Eddington
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".
Actually, I don't think an &i/o-write exception is appropriate because
it's for write errors which occur *during* an I/O operation, and a
closed port cannot begin an I/O operation. I think an &assertion
exception is appropriate. But I can't hold implementations of R6RS to
that.
--
: Derick
----------------------------------------------------------------
William D Clinger
2009-03-19 13:35:00 UTC
Permalink
Post by William D Clinger
The fact that Larceny's binary-port? predicate returns
true for a closed port is a bug, which we will fix.
A more careful search of R6RS library chapter 8 shows that
the R6RS allows binary-port? to return true on closed ports,
so long as closed ports are neither input ports nor output
ports (which Larceny implements correctly).

Although the R6RS does not require binary-port? to return
false on closed ports, I believe it is confusing for
binary-port? to return true on closed ports, so I still
consider that to be a bug and still intend to fix it.

Will
William D Clinger
2009-03-19 23:36:38 UTC
Permalink
Post by Derick Eddington
Post by William D Clinger
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.
No, I think the context of that quote makes it clear that,
even though the binary port has been closed in a special
way that might lead you to think it can still be used, it
is really just like all other closed ports in being unusable
by input and output operations.
Post by Derick Eddington
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.
Scheme is not a typed language. Certain properties of an
object are immutable, but others may be mutable. Whether
something is a port, for example, is immutable, so it is
reasonable to think of that property as a type property.

Whether a port is open, on the other hand, is a mutable
property of a port. Closing a port has major side effects.

The question here is whether the property of being an
input, output, binary, or textual port is mutable or
immutable. The R6RS documents are certainly not as
clear about this as they should be, but I believe that,
considered in context, R6RS library 8.2.6 is saying that
the binary port that is closed by transcoded-port is like
other closed ports in that it can no longer be used for
input or output operations.

My opinion is not authoritative, but I did indeed write
the specification of transcoded-port (during the second
of two hurried rewrites of the R6RS library section 8.2
that I was asked to do on very short notice, even though
I wasn't on the io subcommittee).

Furthermore David Bartley and I designed and specified
the io system of RRRS, which survives in the R5RS and in
(rnrs io simple). I see nothing in the R6RS documents
to indicate that the property of being an input or output
port has become immutable, after all these years of being
mutable in the RRRS through IEEE/ANSI and R5RS standards.

In particular, the disjoint types listed in R6RS 11.1 are
exactly the same as the ones listed in IEEE Standard 1178
section 3.4, Disjointness of Types. A search for the word
"type" in R6RS library chapter 8 shows that the word is
almost always used in connection with condition types, and
there is absolutely no suggestion that the property of
being an input port (etc) has become an immutable property
of a port. As the author of the last paragraph of R6RS
library 8.2, I'm pretty sure it was never intended to
suggest that any of those properties were immutable.
Post by Derick Eddington
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.
There may some way of reading the R6RS documents that would
allow an implementation to regard a closed port as an input
port, but I doubt it. There is certainly no language that
would require a closed port to remain an input or output
port.

In Larceny, calling port-eof? on a closed input port raises
Post by Derick Eddington
(define p (current-input-port))
(close-port p)
(port-eof? (current-input-port))
#f
Post by Derick Eddington
(port-eof? p)
Error: unhandled condition:
Compound condition has these components:
#<record &assertion>
#<record &message>
message : "assertion failed"
#<record &irritants>
irritants : ((io/input-port? p))

As is typical of Larceny, the error message is poor, but the
reason for the exception is that (as R6RS library chapter 8
says) you aren't allowed to perform input or output opeations
on a closed port. That semantics has been enforced in Larceny
for the past decade, and in Larceny's predecessor, MacScheme,
for another 15 years before that. To my knowledge, none of
the thousands of users of those systems ever suggested that
a closed port should remain an input or output port.
Post by Derick Eddington
I still think it has too much potential to be seriously confusing.
For what benefit? It's confusing because...
It's confusing because you are thinking of type as an immutable
property of objects, which is okay so long as you use the word
"type" only when referring to immutable properties of objects.

Once you begin to use the word "type" to refer to mutable
properties, however, you will become confused. The moral of
the story is that you shouldn't use the word "type" to refer
to properties of mutable objects unless the standards tell you
those properties are immutable---which is certainly not the
case here.

Just look at how often you're using the word "type" to refer
to properties that the R6RS documents are moderately careful
not to refer to as a "type". You do that seven times in
Post by Derick Eddington
... 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".
Post by William D Clinger
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?
Once you learn not to refer to potentially mutable properties
as types, it will become much less confusing for you because
the properties will correspond exactly to what the R6RS says
about which arguments are accepted by the input and output
procedures.

If you persist in thinking of "input port" as an immutable
type, however, then you will have to invent some myth to
reconcile your thinking with the fact that closed ports are
not accepted by input operations that, according to the R6RS
library document, are required to accept input ports as
arguments.

Myths lead to confusion. It's better to think clearly.

Will
Derick Eddington
2009-03-20 02:34:32 UTC
Permalink
Thank you for the informative response. I now understand the rationale
behind your argument, and I think it does make sense. But, as you said,
the R6RS certainly doesn't make this issue clear enough. In fact, it's
guilty of referring to potentially mutable properties as types: R6RS 6.2
"Procedure entries" says "Other type restrictions are expressed through
parameter-naming conventions that are described in specific chapters."
which would give me the idea that parameters named "input-port" are
referring to types. This must be what you mean by "moderately careful"
not to refer to them as types.
--
: Derick
----------------------------------------------------------------
Post by William D Clinger
Post by Derick Eddington
Post by William D Clinger
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.
No, I think the context of that quote makes it clear that,
even though the binary port has been closed in a special
way that might lead you to think it can still be used, it
is really just like all other closed ports in being unusable
by input and output operations.
Post by Derick Eddington
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.
Scheme is not a typed language. Certain properties of an
object are immutable, but others may be mutable. Whether
something is a port, for example, is immutable, so it is
reasonable to think of that property as a type property.
Whether a port is open, on the other hand, is a mutable
property of a port. Closing a port has major side effects.
The question here is whether the property of being an
input, output, binary, or textual port is mutable or
immutable. The R6RS documents are certainly not as
clear about this as they should be, but I believe that,
considered in context, R6RS library 8.2.6 is saying that
the binary port that is closed by transcoded-port is like
other closed ports in that it can no longer be used for
input or output operations.
My opinion is not authoritative, but I did indeed write
the specification of transcoded-port (during the second
of two hurried rewrites of the R6RS library section 8.2
that I was asked to do on very short notice, even though
I wasn't on the io subcommittee).
Furthermore David Bartley and I designed and specified
the io system of RRRS, which survives in the R5RS and in
(rnrs io simple). I see nothing in the R6RS documents
to indicate that the property of being an input or output
port has become immutable, after all these years of being
mutable in the RRRS through IEEE/ANSI and R5RS standards.
In particular, the disjoint types listed in R6RS 11.1 are
exactly the same as the ones listed in IEEE Standard 1178
section 3.4, Disjointness of Types. A search for the word
"type" in R6RS library chapter 8 shows that the word is
almost always used in connection with condition types, and
there is absolutely no suggestion that the property of
being an input port (etc) has become an immutable property
of a port. As the author of the last paragraph of R6RS
library 8.2, I'm pretty sure it was never intended to
suggest that any of those properties were immutable.
Post by Derick Eddington
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.
There may some way of reading the R6RS documents that would
allow an implementation to regard a closed port as an input
port, but I doubt it. There is certainly no language that
would require a closed port to remain an input or output
port.
In Larceny, calling port-eof? on a closed input port raises
Post by Derick Eddington
(define p (current-input-port))
(close-port p)
(port-eof? (current-input-port))
#f
Post by Derick Eddington
(port-eof? p)
#<record &assertion>
#<record &message>
message : "assertion failed"
#<record &irritants>
irritants : ((io/input-port? p))
As is typical of Larceny, the error message is poor, but the
reason for the exception is that (as R6RS library chapter 8
says) you aren't allowed to perform input or output opeations
on a closed port. That semantics has been enforced in Larceny
for the past decade, and in Larceny's predecessor, MacScheme,
for another 15 years before that. To my knowledge, none of
the thousands of users of those systems ever suggested that
a closed port should remain an input or output port.
Post by Derick Eddington
I still think it has too much potential to be seriously confusing.
For what benefit? It's confusing because...
It's confusing because you are thinking of type as an immutable
property of objects, which is okay so long as you use the word
"type" only when referring to immutable properties of objects.
Once you begin to use the word "type" to refer to mutable
properties, however, you will become confused. The moral of
the story is that you shouldn't use the word "type" to refer
to properties of mutable objects unless the standards tell you
those properties are immutable---which is certainly not the
case here.
Just look at how often you're using the word "type" to refer
to properties that the R6RS documents are moderately careful
not to refer to as a "type". You do that seven times in
Post by Derick Eddington
... 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".
Post by William D Clinger
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?
Once you learn not to refer to potentially mutable properties
as types, it will become much less confusing for you because
the properties will correspond exactly to what the R6RS says
about which arguments are accepted by the input and output
procedures.
If you persist in thinking of "input port" as an immutable
type, however, then you will have to invent some myth to
reconcile your thinking with the fact that closed ports are
not accepted by input operations that, according to the R6RS
library document, are required to accept input ports as
arguments.
Myths lead to confusion. It's better to think clearly.
Will
David Rush
2009-03-20 09:27:50 UTC
Permalink
I actually agree with WIll 100%, but since I'm currently studying and
implementing some advanced type systems...
Scheme is not a typed language.  Certain properties of an
object are immutable, but others may be mutable.
I can feel the breeze from your hands waving :)

Types are constraints relating to the values in a formal system. They
provide a level of correctness guarantee that is directly related to
the subject matter of the underlying constraint system. In principle
(as in Scheme), there is no obligation to check constraints any time
sooner than the application of a function to it's arguments.

So all of those lovely predicates in Scheme do produce a type-system
of sorts, but the checking of the constraints is not performed in a
static environment. In fact, Scheme's type-checking is "reflected"
back to the programmer, modulo system primitives.

Looked at this way, having the set of constraints satisfied by a port
after a close operation change is completely unsurprising. The Scheme
"type system" is actually *richer* than in statically-typed languages,
because you can express type constraints that are sensitive to data
flow.

(perhaps I exaggerate slightly :)

david
--
GPG Public key at http://cyber-rush.org/drr/gpg-public-key.txt
Derick Eddington
2009-03-20 18:50:15 UTC
Permalink
Post by David Rush
I actually agree with WIll 100%, but since I'm currently studying and
implementing some advanced type systems...
Post by William D Clinger
Scheme is not a typed language. Certain properties of an
object are immutable, but others may be mutable.
I can feel the breeze from your hands waving :)
Types are constraints relating to the values in a formal system. They
provide a level of correctness guarantee that is directly related to
the subject matter of the underlying constraint system. In principle
(as in Scheme), there is no obligation to check constraints any time
sooner than the application of a function to it's arguments.
So all of those lovely predicates in Scheme do produce a type-system
of sorts, but the checking of the constraints is not performed in a
static environment. In fact, Scheme's type-checking is "reflected"
back to the programmer, modulo system primitives.
Looked at this way, having the set of constraints satisfied by a port
after a close operation change is completely unsurprising. The Scheme
"type system" is actually *richer* than in statically-typed languages,
because you can express type constraints that are sensitive to data
flow.
I've come to appreciate more and more the defining of everything in
terms of predicates which can do anything because it allows making
designs which nicely fit mental concepts and can smoothly evolve. But
you still have to understand the design of the concepts, of course.
--
: Derick
----------------------------------------------------------------
William D Clinger
2009-03-20 03:48:50 UTC
Permalink
Post by Derick Eddington
Thank you for the informative response. I now understand the rationale
behind your argument, and I think it does make sense. But, as you said,
the R6RS certainly doesn't make this issue clear enough. In fact, it's
guilty of referring to potentially mutable properties as types: R6RS 6.2
"Procedure entries" says "Other type restrictions are expressed through
parameter-naming conventions that are described in specific chapters."
which would give me the idea that parameters named "input-port" are
referring to types. This must be what you mean by "moderately careful"
not to refer to them as types.
Exactly!

In the R5RS, the only "type" in section 1.3.3 that isn't
immutable is list, which is accompanied by a parenthetical
reference to section 6.3.2, which explains that "an object
can be a list one moment and not the next".

In R6RS 6.2, *all* of the listed types are immutable. The
main defect in the sentence you quoted is that it neglects
to mention that the parameter-naming conventions are also
used to restrict arguments on the basis of mutable properties
(such as "list") as well as immutable.

But the R6RS certainly uses the word "type" more often and
more casually that I would have liked.

To give you some more historical context, the R6RS narrowly
avoided a semantics in which binary ports could mutate into
textual ports [1,2,3]. I invented the transcoded-port hack
so implementations wouldn't be required to support that
particular mutation.

Will

[1] http://lists.r6rs.org/pipermail/r6rs-discuss/2006-October/000559.html
[2] http://lists.r6rs.org/pipermail/r6rs-discuss/2006-November/000564.html
[3] http://www.r6rs.org/formal-comments/comment-88.txt
Continue reading on narkive:
Loading...