Do we support any means of creating disjoint user-defined types, such as in SRFI-9, SRFI-99 or the R6RS record system?
WG1 voted srfi-9 before. New arguments against filter constructors were raised, so the ticket was re-opened.
Rationale: The most important thing about SRFI 9 is how pervasive it is (26 out of 30 implementations I track at http://tinyurl.com/scheme-s5 support it). Yes, it's messy. Yes, we should keep it.
Do we provide any binary input or output ports, and if so how do we construct them and operate on them? Can binary and textual operations be mixed on the different port types?
PortsCowan provides binary port operations along with other extensions.
R6RS provides an entirely new I/O system, as well as a separate R5RS-compatible I/O system.
The withdrawn SRFI-91 provides yet another I/O system supporting binary ports.
Note this item as well as #29 and #31 specify semi-orthogonal aspects of I/O systems which are typically specified together by individual proposals. If the same proposal doesn't win for all three, the aspects will be merged as needed.
WG1 voted weakly in favor of cowan before.
In R6RS auxiliary keywords (such as else in cond and case forms) are explicitly exported from the (rnrs base (6)) library. Do we want to bind and export these from the core library?
If else is bound in the default module, then it must be imported at the call site whenever using it in cond or it won't match hygienically.
If else is not bound in the default module, then it must not be bound or imported at the call site whenever using it in cond or it won't match hygienically.
Another option is to specify for cond and case that they match the else identifier literally, ignoring any hygiene. This breaks compatibility with R5RS and R6RS.
WG1 voted unbound previously. New issues were brought up on the list so the ticket was re-opened.
Rationale: The arguments for binding this convince me.
We need a naming convention for the core modules and standard libraries of the new module system.
The existing break down is based on John Cowan's earlier proposal of factorings in items #71, #72, #73, #74, #75, #76, #77, as well as an I/O module breakdown in PortsCowan. There have been various tickets proposing changing this, so we are re-opening the ticket.
Note: The (scheme io) module in the draft was never voted on and doesn't belong there.
Now that we have blobs, we have to decide what to call them. R6RS uses bytevector, SRFI-4 and SRFI-68 uses u8vector, while the original WG1 proposal used blob (which is therefore the default).
Rationale: I call them blobs because I see them as objects whose size is measured in bytes, not specialized vectors of 8-bit unsigned integers. It's easy to layer such an interpretation, along with many other interpretations, on top of blobs, but blobs should themselves remain simple for WG1.
In R5RS syntax such as #t#f is left unspecified - some readers may parse this as the true literal followed by false. R6RS requires identifiers, characters, booleans, number objects, and . to be terminated with a "delimiter" or by the end of input.
Rationale: Allowing #true to mean #t rue is just silly. If implementations want to accept #true, they should be able to do so.
In R5RS foo#f is a valid identifier, whereas R6RS requires # to act as a delimiter, so that this would parse as the identifier foo followed by the false literal.
Rationale: Backward compatibility rules here. Chicken depends heavily on identifiers with embedded #s.
This is a change also made by R6RS (and CL).
Rationale: R6RS is better defined, and we should accept it. The vagueness in R5RS helps nobody.
This is a change also made by R6RS.
Rationale: Treating procedures as locations distinguishable by eq? is a hack nobody ought to depend on.
This is a change also made by R6RS.
R5RS is slightly ambiguous, saying
BEFORE is called whenever execution enters the dynamic extent of the call to THUNK and AFTER is called whenever it exits that dynamic extent. Jeronimo Pellegrini scripsit: > According to Section 6.7.1, "Conversely, not all character ports are > binary ports -- for example, the /string ports/ discussed below". It > is not really clear to wether the document *requires* string ports not > to be binary or if it was just an example of a port that *could* be > character but not binary. I haven't thought about it, but I guess it *could* be the latter, if the environment provides a default encoding for string ports. Existing features of IEEE Scheme may be removed only if a strong case can be made that they are fundamentally flawed. Insofar as practical, the language should be backwards compatible with the IEEE standard, the R5RS standard, and an appropriate subset of the R6RS standard. Unfortunately, most programming languages give nondescript names such as DIV(IDE), QUOT(IENT), MOD(ULO), and REM(AINDER) to these operations. The language should make clear to programmers what division operations their programs are performing, especially when negative dividends and divisors can arise, but perhaps may not often arise during testing. [...] The R5RS gives the names quotient and remainder to the truncating division operator pair, and the name modulo to the remainder half of the flooring division operator pair. For all these three procedures in the R5RS, the dividend may be any integer, and the divisor may be any nonzero integer.
On the other hand, we may prefer relegating them to a backward-compatibility module.
Vote "yes" to keep, "no" to remove, and "module" to relegate to a module.
On reflection, every implementation will go on supporting them anyway, if just to keep old code working. Consistent with my "modules = optional" views, I see no reason to have a module here. There should be discouraging language in the report, though.
R6RS specifies the domain of finite? and nan? as the real numbers only. I propose that finite? return #t on a non-real value iff both the real part and the imaginary part are finite and not +nan.0, and that nan? return #t on a non-real value iff either the real or the imaginary part is +nan.0.
That is, what's proposed there. This is what people who do complex flonum programming need.
R5RS does not actually specify any procedures which return multiple values, and so the decision to separate multiple values to a module was reasonable. However, we also voted to make exact-integer-sqrt, which is in the base module, return multiple values, namely the root and the remainder. That would make the procedure useless unless multiple values are provided.
We can either make multiple values not a module, make exact-integer-sqrt return a list (or single integer) rather than multiple values, relegate exact-integer-sqrt to a new module, remove it altogether, or do nothing and leave the inconsistency.
Rationale: Multiple values are cheap to provide poorly for implementations that don't care, and can be provided well with some effort by implementations that do. No need to make them optional, therefore. Doing so also removes an extra dependency from WG2 packages that want to return multiple values.
Andy Wingo suggests: make the clauses in case and cond forms (without =>, naturally) be BODY instances, to allow them to have definitions. It is well defined AFAIK, and costs nothing.
The counter-argument is that it doesn't "look" like the sort of place definitions are allowed.
Rationale: There is nothing in Scheme like ((= x y) (define z ...) (+ z x y)) except at top level. Let's not go there.
Rationale: These are good things, and there is no reason to keep them separated out as if they were untouchables.
These trivial syntaxes add familiarity for new Scheme programmers coming from other languages, as will almost always be the case. LOOP is too big and named-LET too alien.
Rationale: Yes, I know we are not supposed to encourage mutability. But we have a lot of it already, particularly when dealing with ports.
Andy Wingo suggests the R6RS handling of escaped embedded newlines:"asdadf \ asdfadf"
in R6RS has the same meaning as "asdf asdfadf". It allows you to nicely indent strings that you need to line-break for width. I suggest that the production\ NEWLINE WHITESPACE*
within string literals be elided.
Note an alternate method for handling embedded strings with nice indentation is scribble syntax.
We voted on various string syntaxes previously but did not specifically propose this R6RS extension. We should have a rationale if we don't follow it.
Rationale: Cheap and useful.
R5RS makes a point of specifying that supporting more than two arguments is optional. (Everything not explicitly mentioned is optional, so this may have significance.) R6RS requires accepting 2 or more arguments. Currently Racket, Gambit, Guile, Chez, Ikarus, Larceny, Ypsilon, Mosh, and Scheme 9 support the feature, whereas Gauche, MIT, Chicken, Bigloo, Scheme48/scsh, Kawa, SISC, Chibi, STklos, and SSCM don't.
Rationale: I think the R5RS implementations should be bootstrapped into the future here. It also meets the consistency guideline in the charter.
From the Guile manual:
— Scheme Procedure: centered/ x y — Scheme Procedure: centered-quotient x y — Scheme Procedure: centered-remainder x y
These procedures accept two real numbers x and y, where the divisor y must be non-zero. centered-quotient returns the integer q and centered-remainder returns the real number r such that x = q*y + r and -|y/2| <= r < |y/2|. centered/ returns both q and r, and is more efficient than computing each separately.
Note that centered-quotient returns x/y rounded to the nearest integer. When x/y lies exactly half-way between two integers, the tie is broken according to the sign of y. If y > 0, ties are rounded toward positive infinity, otherwise they are rounded toward negative infinity. This is a consequence of the requirement that -|y/2| <= r < |y/2|.
Note that these operators are equivalent to the R6RS operators div0, mod0, and div0-and-mod0.
Taylor Campbell thinks these are useless. We should probably have use cases for _any_ division operator we include.
Rationale: I'm not convinced they are useful except maybe to do bignums with, in which case it's easy to define them.
Note: There are rationales for most of the division operators at Riastradh's original proposal.
The documentation for `begin' specifies that it is a sequential construct; but really it splices as well, and also of course it's a keyword for the module system currently. This is inaccurate of the spec to say that "begin is for sequencing".
Suggestion: adopt the language of R6RS section 11.4.7.
We should explain somewhere the four kinds of begins: (begin expr ...), (begin decl ...), top-level begin, and module-top-level begin. Note that R7RS like R5RS does not have (begin decl ... expr ...).
Vote yes to adopt the R6RS description, modified for differences in the language.
Rationale: I think this is a documentation issue only: the documentation Andy complained abuot is just for expression-begin.
This is possibly difficult to enforce, and can break existing R5RS programs written in very bad style.
Rationale: I don't see how it can break anything, because no R5RS program can count on map using a mutable-result implementation anyway. Vector-map and string-map are more likely to.
This is possibly difficult to enforce, and can break existing R5RS programs.
Rationale: "Difficult to enforce" is irrelevant; "is an error" means no Scheme programmer should rely on the results of it.
Add blob, blob-map, blob-for-each, and blob conversion functions to and from lists/vectors/strings.
... with extra arguments.
Rationale: We did not roll substring into string-copy with additional arguments; the only reason not to use subblob as a name is its risibility.
R6RS provides a #vu8(...) read-syntax for bytevectors. SRFI-4 uses #u8(...).
Rationale: I can't see anyone writing these by hand. They might add a little efficiency compared to a blob procedure (analogous to string, vector, and list).
Add a note saying that 1@2 and (make-polar 1 2) MAY evaluate to an inexact complex number.
Rationale: This is obviously an oversight: exact values passed to make-polar aren't going to come out exact from make-rectangular, and essentially all Schemes store complex numbers as rectangulars internally. (The Pure language supports both representations internally, but I can't see going there for standard -Scheme.)
The grammar in 7.1.1 allows || as an <identifier>. However, page 5 suggests the |...| form is only for convenience (e.g. |foo bar| is equivalent to foo\x20;bar). There's no way to normalise || to anything without the vertical bars that's a valid identifier. Was that intentional, or should the rule be<vertical bar> <symbol element>+ <vertical bar>
Vote remove to remove the |...| syntax altogether.
Rationale: Not sure why this is supposed to be the default. || is convenient on occasion, and allows string->symbol to accept any string.
Should we include close-port, as a generic version of close-input-port and close-output-port?
Rationale: I could see adding this to a Scheme that has input/output ports to close both sides of the port, but the WG1 standard doesn't have them. Just as a generic procedure, no.
The definitions of and and or may be slightly confusing. Reword them to be more clear. One possible hiccup is that the current language permits the return of different false values, while a clearer wording may preclude this.
R6RS provides a clearer definition that does not provide wiggle room for multiple false values. Should we use that?
Rationale: I know why Guile needs multiple false values (to handle Emacs Lisp as well as Scheme), but I'd rather see such a system saying it overrides the Standard in this respect.
The language of the standard could clarify that duplicate bindings are permitted in the clauses of a let*.
Rationale: Why not?
make-blob should either have an initial value argument, or rationale why it is inconsistent with make-vector and make-string.
Vote yes for an initial value argument.
Rationale: As noted, I don't see blobs as specialized vectors. Still, I suppose initialization to all zeros couldn't hurt. Okay.
There are cases when one does not want to output reader labels for shared structure, such as when you don't care (and want the output to be more legible), or when you know that the time or space requirements to construct the table will be too large.
We could offer a parameter to control this, or have a separate procedure (e.g. write/simple) which doesn't use the reader labels.
Finer grained control may also let use specify a predicate for which values are interesting (e.g. never use labels for strings), or only use labels for cycles, etc.
Rationale: I think a separate procedure is marginally better than a parameter.