-
Notifications
You must be signed in to change notification settings - Fork 32
R7RSconversion
This list is based upon the language changes noted on pages 77-80 of the R7RS small standard and errata.
Larceny's case sensitivity, as implemented to support R6RS, is compatible with the draft R7RS, except #!fold-case
and #!no-fold-case
are treated as comments. Larceny has converted to the R7RS semantics for those flags.
The include-ci
library declaration has been added (but only to R7RS-style libraries).
The underscore wildcard for syntax-rules
was implemented for R6RS, as were the procedures inexact
and exact
.
The remaining incompatibilities omit R5RS features Larceny will retain for backward compatibility or has already dropped (transcript-on
and transcript-off
).
R7RS libraries have been implemented on an equal basis with Larceny's support for R6RS libraries. Larceny's ERR5RS mode is retained because it's useful for Larceny development, but most R7RS programmers will use a new R7RS-compatible top level.
Implemented only for R7RS define-library
, and only at top level.
R7RS exceptions are mostly compatible with Larceny's R6RS-compatible exceptions, but the error
procedure is different. Some R7RS predicates were added to distinguish different kinds of exceptions.
Trivial. Larceny extends define-record-type
to allow ERR5RS and R6RS syntactic record syntax.
R7RS make-parameter
is not fully compatible with Larceny's v0.97 semantics. R7RS make-parameter
has been extended to support Larceny's historical semantics insofar as possible. The conflicting case is resolved by using R7RS semantics.
SRFI 45 enhancements were added.
The lexical syntax is different, and most of the procedures have different names. At least one procedure (bytevector-copy!
) has the same name but takes its arguments in a different order.
These are compatible with the R6RS, then Larceny has nothing more to do here.
R7RS ports aren't the same as R6RS ports, thank goodness, but there don't seem to be any outright conflicts.
Whether textual and binary ports are disjoint is implementation-dependent. In Larceny, they're disjoint (for interoperability with R6RS) but some textual operations might be allowed on binary ports.
The new open-binary-input-file
procedure conflicts with Larceny's existing procedure of the same name, because Larceny's procedure returns a textual port. In stdio.sch
, the definition of that procedure and five others is preceded by a FIXME comment that says those six procedures should go away as soon as possible.
New procedures: open-binary-input-file
, read-u8
, peek-u8
, u8-ready?
, read-bytevector
, read-bytevector!
, write-shared
, write-simple
, write-u8
, write-bytevector
.
These are mostly compatible with Larceny's existing string and bytevector ports.
The R7RS write
procedure writes R7RS-specific syntax unless the output port allows only R6RS syntax. Even then, R7RS syntax will be used when no R6RS syntax applies (e.g. for circular objects).
Already provided.
Syntax definitions are allowed wherever variable definitions are allowed, but the scope rules are slightly different from R6RS. Larceny will probably continue to use R6RS scope rules.
Not yet implemented. Might be tedious to implement.
Took some doing, but it's done.
Already provided.
The define-values
, let-values
, and let*-values
forms are already implemented.
The =>
is now allowed in the else clause.
In its own library.
Already provided.
As in R6RS.
Better than the R6RS: On procedure arguments, eqv?
may return true even when eq?
returns false.
Already provided.
Already provided.
Already provided.
Incompatible with R6RS, but this matters only for R6RS programs that violate R6RS semantics. The punishment mandated by R6RS will be administered only in R6RS batch mode. (And maybe not even then; if so, it's a bug so benign no one is likely to complain about it.)
Routine.
Already provided except for exact-integer?
and square
.
Already provided except for the -ci
versions, which were upgraded.
New procedures: make-list
, list-copy
, list-set!
, string-map
, string-for-each
, string->vector
, vector-append
, vector-copy
, vector-map
, vector-for-each
, vector->string
, vector-copy!
, string-copy
Already provided or routine, but some are incompatible with R6RS procedures. All incompatibilities were resolved by extending the R6RS procedure to use R7RS semantics.
Routine.
Routine or already provided.
Already provided except for digit-value
, which was added. Some Unicode bugs were fixed during the upgrade to Unicode 7.0.0.
Already provided.
Straightforward.
By default, Larceny allows both R7RS and R6RS lexical syntax except in R6RS batch mode.
Syntactic differences between R6RS and R7RS:
- R7RS doesn't support square brackets.
- R7RS uses #u8(...) instead of #vu8(...) for bytevectors.
- R7RS doesn't support #', #`, #, #,@ .
- R6RS doesn't treat vertical line as a delimiter, but R7RS does.
- R6RS treats # and square brackets as delimiters, but R7RS doesn't.
- R7RS says intraline whitespace is a
<space or tab>
, but doesn't define<space or tab>
. - R6RS says any Zs, Zl, or Zp counts as whitespace.
- R6RS allows
<next line>
,<carriage return> <next line>
, and<line separator>
as a<line ending>
. - R7RS allows only three line endings, but meaning of
<newline>
isn't specified. - R6RS comments include #!r6rs.
- R7RS allows
#!fold-case
and#!no-fold-case
directives, which must be followed by a delimiter or end of file. - R7RS identifiers can be of the form
<vertical line> <symbol element>* <vertical line>
. - R7RS identifiers may include U+200C and U+200D.
- R7RS allows identifiers with inline hex escapes only if the identifier is enclosed within vertical lines.
- R7RS allows many peculiar identifiers that R6RS does not allow.
- R6RS strings may contain the \v or \f mnemonic escapes.
- R6RS allows
<mantissa width>
to follow<decimal R>
in<ureal R>
. - R6RS allows #', #`, #, #,@ abbreviations.
- R7RS allows
# <uinteger 10> = <datum>
and# <uinteger 10> #
syntaxes. - R7RS allows
@
as a<special initial>
(see erratum 7).
Already provided.
Apparently compatible with R6RS.
The emergency-exit
procedure bypasses dynamic-wind protection.
Routine.
Routine.
Turned out to be routine.
Already provided.
Redefinition of procedures (but not syntax keywords) has retroactive effect. Should be routine.
Okay.
Routine.
Routine.
As with SRFI libraries, there are some conflicts with R6RS names. Where possible, Larceny extends conflicting procedures and syntaxes to make renaming unnecessary.
Okay.
Allowed but with more restrictions than in R6RS.
Might as well continue to use R6RS condition system.
Larceny supports full Unicode 7.0.0, including all four normalization forms.
Procedures whose semantics differs between R6RS and R7RS: real?
, rational?
, integer?
. (The R6RS semantics is available in R7RS via real-valued?
, rational-valued?
, and integer-valued?
.) Larceny continues to use R6RS semantics, as the R7RS semantics is muddled and possibly self-contradictory.
R6RS procedures absent from R7RS: div
, mod
, div-and-mod
, div0
, mod0
, div0-and-mod0
.
Will thought the R6RS allowed this as well.
Larceny uses R7RS semantics unless the program is running in R6RS batch mode.
Routine.
Two R6RS extensions weren't adopted by R7RS. Can probably just ignore this.
As specified by the R6RS, the R6RS mantissa width syntax had no meaningful semantics anyway.
Hooray.
For interoperability, Larceny supports both syntaxes. The #!r6rs
flag can be used to disable R7RS lexical syntax on input, and a parameter can tell Larceny not to use R7RS lexical syntax for newly opened output ports.
Okay.
Major issues:
The R6RS doesn't allow any extensions to the lexical syntax
other than #!
flags. The R7RS apparently doesn't mind.
The only sensible thing for Larceny to do here is to extend R7RS lexical syntax enough to support R6RS lexical syntax as well.
It looks as though the only serious conflicts are:
-
#u8(...)
versus#vu8(...)
- whether
#
is a delimiter
Larceny will recognize both bytevector syntaxes, and will treat
#
as a delimiter. (Whether #
counts as a delimiter
could be mode-dependent, but we'll wait to see whether that's
really necessary.)
The new write-simple
and write-shared
procedures
will use R7RS lexical syntax for bytevectors. The write
and display
procedures exported by (rnrs io)
and
(scheme base)
will consult the output port's syntax mode.
Larceny's native procedures will eventually be changed to use the R7RS lexical syntax, but there's no rush there.
If a program imports both R6RS and R7RS libraries, then some of the imported identifiers may have incompatible bindings.
Consider, for example, a program that imports both (rnrs) and (scheme base). Here's a partial list of identifiers that are likely to have conflicts:
assoc (R7RS more general)
bytevector-copy (R7RS more general)
bytevector-copy! (incompatible when 5 arguments are passed)
define-syntax (R6RS more general)
eqv? (R7RS likely to be more traditional)
error (see below)
for-each (R7RS more general)
let-syntax
letrec-syntax
map (R7RS more general)
member (R7RS more general)
string->utf8 (R7RS more general)
string-for-each (R7RS more general)
unless (R6RS implies R7RS requirements)
utf8->string (R7RS more general)
vector-for-each (R7RS more general)
vector-map (R7RS more general)
when (R6RS implies R7RS requirements)
Programs that import both (scheme base)
and (rnrs bytevectors)
will have to rename one version of bytevector-copy!
.
For unless
and when
, an R6RS-conforming definition
will satisfy the R7RS requirements.
For define-syntax
, Will thinks an R6RS-conforming definition
can satisfy the R7RS requirements.
For assoc
, bytevector-copy
, for-each
, map
,
and other procedures that are more general in the R7RS than in the
R6RS, an R7RS-conforming procedure will work wherever the R6RS
semantics is expected, with one problematic exception: the R6RS
allows programmers to write programs that depend on exceptions
raised by the R6RS versions but not by the R7RS versions.
That brain damage can be limited by providing only legacy support for R6RS programs. We'll make it easy for R7RS programs to import R6RS libraries, but we won't jump through hoops to make it easier for R6RS programs to import R7RS libraries.
Larceny's low-level version of those procedures will use the R7RS
semantics. The versions of those procedures exported by the
(rnrs base), (rnrs), and (scheme base) libraries will consult the
execution-mode
available at run time via system-features
.
If the execution mode is dargo or spanky (implying R6RS), those
procedures will delegate to R6RS-conforming versions that raise
the exceptions mandated by the R6RS. Otherwise they will simply
delegate to Larceny's low-level versions of those procedures.
The R6RS error
procedure treats its first argument as "who".
The R7RS error
procedure has no "who", and requires its first
argument to be a string.
Larceny's native error
procedure already deals with that
problem by using the execution mode, the arguments, and the
installed exception handlers to decide whether to behave as
specified by the R6RS or by the relevant SRFI.
Some variation of that should be good enough.
With the R6RS, let-syntax
and letrec-syntax
bodies
can be sequences of definitions, which are then treated as though
they had appeared within a begin
where the let-syntax
or letrec-syntax
had originally appeared.
Although the R7RS apparently doesn't permit this, it's unlikely
to do any harm.