You are looking at historical revision 29492 of this page. It may differ significantly from its current revision.
- R7RS Tasks
- General structure
- Classification of changes
- Changes that are likely to be implemented in the core system
- Implementations in the r7rs egg that override core functionality
- 4.1.7. Inclusion
- 4.2.1. Conditionals
- 5.2. Import declarations
- 5.3.3. Multiple-value definitions
- 5.5. Record-type definitions
- 5.6.1. Library syntax
- 6.1. Equivalence predicates
- 6.4. Pairs and lists
- 6.7. Strings
- 6.8. Vectors
- 6.10. Control features
- 6.11. Exceptions
- 6.12. Environments and evaluation
- 6.13.1. Ports
- 6.13.3. Output
- 6.14. System interface
R7RS Tasks
(first draft, by felix)
comments by John Cowan marked with JC:
General structure
I currently assume that R7RS support will be provided by an egg and a minimal set of core enhancements for performance-sensitive functionality or features that would require extensive customization of existing code.
R7RS library names (lists) can be mapped to module names by concatenating the constituents of a library name, separated by "." (dot), for example:
(foo bar baz) -> foo.bar.baz
The egg needs to provide a compile-time layer for the expansions of library forms and import-resolution in addition to a full set of standard libraries. Using the r7rs egg (for example with require-extension) will automatically load and import all r7rs standard libraries into the toplevel environment. On the other hand R7RS modules defined with "define-library" will have initially only import, which will be needed to expand imports (strictly speaking, the initial module environment should be empty, but this is how the module system currently works).
There is probably no way around including the full numeric tower - providing a mode with a restricted set of numeric types would complicate the R7RS support quite considerably. The numbers egg is likely to need some enhancements (equal[=]? with handling of circular data, see below).
- JC: I don't understand why things would be complicated with Chicken's default fixnum/flonum support. There is no equal=? in R7RS, and equal? should not be affected.
- JC: What about making full Unicode support the default? R7RS does not require it, but it might be better so.
Full type-declarations for all exports should be provided, both for error checking and performance. It would also be worthwhile to identify small inlinable R7RS primitives and generate ".inline" files for all standard libraries, if candidates for global inlining exist.
Some R7RS primitives are partially or completely provided by SRFI-1 and SRFI-13, but I think it would be better to implement them directly, to make them as efficient as possible. The existing code is in many cases not tuned to the implementation and makes assumptions about Scheme code performance that may have been valid 30 years ago but aren't anymore nowadays.
Classification of changes
- (+)
- Trivial or straightforward changes
- (*)
- Changes that are difficult or work-intensive
- (X)
- Changes that break backwards-compatibility
- (?)
- Needs to be clarified
Changes that are likely to be implemented in the core system
2.1. Identifiers
- |...| needs support for \x...; escape syntax, which is not fully compatible to the existing \xXX format. A backwards-compatible change should be possible but will have ambiguous cases like |\x12;|. (X)
- #!fold-case, #!no-fold-case. Do these apply over files? (for example when used inside included files) (+)
- JC: They apply only to the file in which they appear, not to any included or including file, because they work at a lower level (that is, read implements them).
- PB: This is a problem, because our "case-sensitive" parameter is global, not bound to the port. Here's a test case that I came up with for this (it can go into tests/r7rs-tests.scm):
(SECTION 2 1) (test '(mooh qux blah foo BAR) #f (append (with-input-from-string "#!fold-case mooh QUX blah #!no-fold-case foo BAR" read-file))) ;; #!(no-)fold-case "affect the reading of subsequent data *from the same port*" (test '(foo bar downcased UPCASED) #f (append (with-input-from-string "#!fold-case foo BAR" read-file) (with-input-from-string "downcased UPCASED" read-file)))
From what I can see, this means a flag needs to be added to the *port*, so that repeated invocations of READ can communicate this to eachother.
4.2.2. Binding constructs
- letrec*. Change all internal uses of letrec to letrec* and add a correct implementation of letrec. This will produce a bootstrapping problem (the compilation of syntactic forms that expand into uses of letrec* will require a compiler with support for letrec*), which can be solved but needs to be done with care. (*)
4.2.5. Delayed evaluation
- delay-force. I don't know how this works, it may be useful to have this in the core-system, though. (?)
- JC: See SRFI 45. The R7RS delay, force, delay-force, and make-promise in R7RS correspond exactly to delay, force, lazy, and eager in that SRFI.
- make-promise: expose wrapper for ##sys#make-promise. (+)
4.3.2. Pattern language (syntax-rules)
- "Underscores also match arbitrary input elements but are not pattern variables ...": is this currently the case? (?)
PB: Not currently the case, underscore is treated like any other identifier. Patch posted to -hackers to change this.
- (<ellipsis> <template>). This is currently not available, IIRC. (? *)
PB: Indeed not available yet. Patch posted for that as well.
6.3. Booleans
- Add #true, #false. (+)
(BTW, I find these depressing. Is it really so difficult for newcomers to learn #t and #f?)
JC: The theory is that #t and #f are too easily mistaken for each other by a human reader. I don't find it so, but apparently others do.
ZB: I would also suggest #one and #ell to prevent further ambiguity. Repeat recursively for #ell as needed.
AS: ZB: Actually, programmers I know fairly universally avoid using single lowercase "l" as a variable name for precisely that reason.
6.6. Characters
- Additional named chars (#\alarm, ...) (+)
- PB: Implemented and pushed.
- Can someone explain to me what char-foldcase does? (?)
- JC: On an ASCII platform, char-foldcase and string-foldcase are the same as char-downcase and string-downcase respectively. For Unicode, char-foldcase implements Unicode case folding, specifically the table entries marked with "C" and "S", but not those marked with "F" or "T". string-foldcase, on the other hand, implements the table entries marked with "C" and "F", but not those marked with "S" or "T".
- Extend char=?, char<? et al. to accept arbitrarily many arguments. (+)
- Core or egg?
6.7. Strings
- \a escape syntax. (+)
- PB: Implemented and pushed
- \<Intraline whitespace>. (+)
- PB: Implemented and pushed
- \x...; syntax. The same issues as in |...| identifier names. (X)
- Extend string=?, string<? et al. to accept arbitrarily many arguments. (+)
- Core or egg?
6.8. Vectors
- Self-evaluating vectors.
- PB: Implemented and pushed
(My heart bleeds)
6.9. Bytevectors
- Self-evaluating u8vectors.
- PB: Implemented and pushed
6.13.3. Output
- write. Support for labels and circle-detection. This probably needs to be implemented in the core reader or will require ugly hooks that we probably want to avoid. (*)
Appendix B
- Without a canonical list of features and their exact meaning this is mostly useless. (?)
- JC: The ones that Chicken should provide are r7rs, ieee-float, and either posix or windows as the case may be. If the full numeric tower is provided, add exact-closed, exact-complex, and ratios. If Unicode is provided, add full-unicode. This should be integrated with the Chicken native (features) list.
Implementations in the r7rs egg that override core functionality
4.1.7. Inclusion
- Multi-argument include, include-ci (+)
4.2.1. Conditionals
- => in case constructs (+)
- PB: Implemented and pushed (thanks to Evan Hanson)
- cond-expand needs support for library. This may need to scan available modules (i.e. query the repository for installed extensions) (*)
- JC: Just so.
5.2. Import declarations
- import. A library name may not begin with a modifier-keyword like only, right? (? *)
- JC: Right. The important thing here is that in an R7RS library or program, import is Chicken's use.
5.3.3. Multiple-value definitions
By having letrec* semantics for internal definitions, this implementation of define-values by Alex Shinn is sufficient for handling toplevel and local multiple-value definitions (special handling in lambda-body expansion is not necessary anymore):
(define-syntax define-values (syntax-rules () ((_ (var ...) expr) (define-values-sub () (var ...) () expr)) ((_ . else) (syntax-error "malformed define-values" (define-values . else))) )) (define-syntax define-values-sub (syntax-rules () ((_ (tmp ...) (last-var) (var ...) expr) ;; place the last var at the start of the list (define-values-sub (tmp1 tmp ...) () (last-var var ...) expr)) ((_ (last-tmp tmp ...) () (last-var var ...) expr) (begin (define var #f) ... ;(undefined) (define last-var (receive (tmp ... last-tmp) expr (set! var tmp) ... last-tmp)))) ((_ (tmp ...) (v v2 ...) (var ...) expr) (define-values-sub (tmp ... tmp1) (v2 ...) (var ... v) expr)) ))
5.5. Record-type definitions
- define-record-type. Is generative (*)
5.6.1. Library syntax
- The export declaration will require renaming, which is currently not available in the module system. Requires a bit fo work. (*)
6.1. Equivalence predicates
- eqv? may have some corner cases for funny IEEE values (nan, etc.). (?)
- equal? must handle circular data. Change this in core? Probably, since this needs to be fast. Applies to equal=? as well. (? *)
- For equal=? the numbers egg will need to be extended, handling circularities is AFAIK not supported yet.
- JC: Say what? There is no equal=? in R7RS.
6.4. Pairs and lists
- make-list. See SRFI-1. (+)
- 3-argument member and assoc. See SRFI-1. (+)
6.7. Strings
- string->list with start/end arguments. (+)
- string-copy, string-copy! and string-fill! with start/end arguments. See SRFI-13. Provide specializations for case when limits are not given. (+)
6.8. Vectors
- vector->list, list->vector and string->vector with start/end arguments. Provide specializations. (+)
- vector-copy! and vector-fill! with start/end arguments. (+)
6.10. Control features
- string-map and string-for-each are not compatible with SRFI-13 version. (+)
6.11. Exceptions
- with-exception-handler. I think this is not compatible to the current version. (? *)
- Clarify exact semantics of raise. (? *)
- Implementing guard correctly will need some thought, due to the wild jumping between dynamic environments. (*)
6.12. Environments and evaluation
- environment. Not sure how to do this. (? *)
- JC: The point of these environments is that they can be passed to eval; they are parallel to the environments returned by scheme-report-environment, null-environment, and interaction-environment.
- Clarify immutability of environments. Can we just ignore this requirement? (?)
- JC: In practice, yes.
6.13.1. Ports
- get-output-string. Does it clear the buffer, as it does in SRFI-whatever? (?)
- No, it doesn't, as in SRFI 6.
6.13.3. Output
- write-string with start/end arguments. (+)
6.14. System interface
- 2-argument load. (?)
- JC: The second argument is passed along to eval.
- exit with boolean arguments. (+)
- What the heck should be used as jiffy? On which platforms? (?)
- JC: Seconds or milliseconds as you see fit.