-
Notifications
You must be signed in to change notification settings - Fork 32
R7RSconversion
This preliminary list is based upon the language changes noted on pages 77-79 of the ninth draft R7RS.
h1. Incompatibilities with R5RS
Larceny's case sensitivity, as implemented to support R6RS, appears to be compatible with the draft R7RS, except #!fold-case
and #!no-fold-case
are treated as comments.
The include-ci
library declaration needs to be 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
).
h1. Other language changes since R5RS
R7RS libraries will be implemented on top of Larceny's support for R6RS libraries, and Larceny's ERR5RS mode will be replaced by an R7RS-compatible top level. This is the biggest and most important item, but the lexical syntax should be updated first.
R7RS exceptions are mostly compatible with Larceny's R6RS-compatible exceptions, but the error
procedure is different.
Unless the R7RS is somehow different from SRFI 9, this is trivial.
The lexical syntax is different, and most of the procedures have different names. At least one procedure has the same name but takes its arguments in a different order.
If 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 Will doesn't yet know whether there are any outright conflicts. Part of the API will be different.
Watch out for "an error that satisfies file-error?
is signalled".
Whether textual and binary ports are disjoint is implementation-dependent. In Larceny, they'll be disjoint (for interoperability with R6RS).
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
. The peek-u8
and u8-ready?
procedures could pose a problem.
With luck, these will be mostly compatible with Larceny's existing string and bytevector ports.
The R7RS write
procedure will write R7RS-specific syntax. Interoperability with R6RS-specific syntax is likely to pose a problem.
Already provided.
Syntax definitions are allowed wherever variable definitions are allowed, but the scope rules are probably different from R6RS.
Already provided.
Unknown.
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.
Likely to change in final draft of R7RS.
As in R6RS except for NaNs.
Already provided.
Already provided, but the behavior of eqv?
is probably different.
Already provided.
Incompatible with R6RS.
Routine.
Already provided except for exact-integer?
and square
.
Already provided.
FIXME: error in ninth draft of R7RS, list of changes.
Already provided or routine, but some are incompatible with R6RS procedures.
Probably routine, but may be incompatible with some R6RS procedures.
Probably routine or already provided.
Probably routine or already provided, but the digit-value
procedure must be added.
Already provided.
The big problem here is interoperability with R6RS.
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 , but doesn't define .
- R6RS says any Zs, Zl, or Zp counts as whitespace.
- R6RS allows , , and as a .
- R7RS allows only three line endings, but meaning of 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 * .
- 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 to follow in .
- R6RS allows #', #`, #, #,@ abbreviations.
- R7RS allows # <uinteger 10> = and # <uinteger 10> # syntaxes.
FIXME: error in ninth draft of R7RS, still shows exponent markers s, f, d, l.
Already provided.
May be incompatible with R6RS.
The emergency-exit
procedure bypasses dynamic-wind protection.
Should be routine.
Should be routine, but may conflict with R6RS.
Could be a problem.
Redefinition of procedures (but not syntax keywords) has retroactive effect. Should be routine.
h1. Incompatibilities with R6RS
Should be routine.
As with SRFI libraries, conflicts with R6RS names are likely.
Okay.
Might as well continue to use R6RS condition system.
Reduces pressure to update Larceny's support for Unicode.
R6RS procedures absent from R7RS: real-valued?
, rational-valued?
, integer-valued?
, div
, mod
, div-and-mod
, div0
, mod0
, div0-and-mod0
.
Will thought the R6RS allowed this as well.
We'll use R7RS semantics, but may want to figure out how to make the semantics of these procedures mode-sensitive.
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, we'll have to support both syntaxes.
Okay.
Major issues:
h1. Interoperability between R6RS and R7RS
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 execution 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)
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)
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.