Am Fr., 20. März 2020 um 03:48 Uhr schrieb John Cowan <xxxxxx@ccil.org>:


On Thu, Mar 19, 2020 at 6:16 AM Shiro Kawai <xxxxxx@gmail.com> wrote:

I'm implementing srfi-181 and portable tests for it, and noticed that  the description of get-position and set-position refers to r6rs port-position and set-port-position!, which haven't been defined in r7rs or other srfi so far (unless I overlooked one).

They were originally part of the pre-SRFI version of SRFI 186, but I removed them for conceptual integrity.   They will be in another R6RS extracted SRFI when I get a chance.

They could be in a coming srfi, but it may be nice to have a reference to a definite
specification (e.g. r6rs) even though it is implied by the fact that the spec is from
r6rs.
 
I've added that to my repo.
 
In r6rs, port-position returns an object of implementation-dependent type, not
necessarily an integer, for textual ports.
Correspondingly, get-position of make-custom-textual-*-port
doesn't specify the return type.  srfi-181 draft 2 limits get-position to return
an exact integer.  If we follow the semantics of r6rs port-position, we need to resolve
this.

I've also added this. 

(It is actually not clear to me that,  in r6rs, how the return value of get-position for
a textual port is related to the one returned by port-position.  For example, when
you're writing a textual port that reads from a vector of characters, how do you
implement get-position/set-position?)

In that case the positions might as well be vector indexes.  Textual positions can be any Scheme value that makes sense.

On Thu, Mar 19, 2020 at 6:25 AM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:

Limiting the position to be an integer is a bit, err, limiting. For many purposes, we would also like to record the current line and column numbers.

In addition, if the textual port is processing text in a stateful encoding such as ISO 2022, it's necessary for the position to carry the current state.  For full ISO 2022 support, you need at a bare minimum the position in the byte stream. plus four exact integers specifying the four codesets that ISO 2022 allows to be available at the same time, plus flags indicating which of these four sets are actually in use to interpret input bytes in the four ranges 01-1F, 21-7E, 80-9F, and A0-FF.  (The bytes 00, 20, 7F are always NUL, space, DEL respectively.)
 
I'd also like to suggest to add a state flag "fold-case?" to each textual (input) port.

That way madness lies. Larceny textual input ports, for example, have not only a fold-case flag but lexical syntax flags for R7RS, R6RS, Larceny, and deprecated Larceny.

Without it, one cannot implement the `read' procedure of `(scheme base)' in a portable way.

I don't know why that should be; can you explain?

The problem occurred to me when I wrote my syntax expander for R7RS.  First, I couldn't use R7RS's `read' procedure to implement `include-ci' because there is no way to portably tell the builtin reader to read, say, `#\Space' as `#\space'.  Thus, I had to write my own `read' procedure.  This, however, would need to attach some state to the supplied port to become a full replacement for the builtin `read': If `read' first processes the input `#!fold-case foo' and then the input `foo' from the same port, it has to return the symbol `FOO' on both invocations.  Thus, the state whether the next read will be case-folding or not has to be attached to the port.

Using a weak hash-table to memorize this state is a fragile solution.  As soon as there is a procedure like `duplicate-port', it would break.

The upshot is that Scheme textual ports should expose the current state of reader flags (they have to exist internally a well).  I would suggest using symbols to name the flags so that the interface can be easily extended (e.g. by Larceny).  The interface could look like this:

(port-flag port name) ; return the value of the flag `name' on the port `port'
(port-set-flag! port name value) ; set the value of the flag `name' on the port `port' to `value'.

If an implementation supports a reader directive like `#!fold-case' or `#!r6rs', their state has to be reflected by the above procedures.  Setting a flag may alter other flags.  For example, after `(port-set-flag! port 'fold-case #t)', the expression `(port-flag port 'no-fold-case)' will evaluate to `#f'.

This interface should be enabled for any textual port.  It is relevant for the reader but not for the specific implementation of the port (in the sense of this SRFI), so it probably should go into a different SRFI.  Nevertheless, it is no less important.
Marc



John Cowan          http://vrici.lojban.org/~cowan        xxxxxx@ccil.org
I come from under the hill, and under the hills and over the hills my paths
led. And through the air. I am he that walks unseen.  I am the clue-finder,
the web-cutter, the stinging fly. I was chosen for the lucky number.  --Bilbo