For those who are involved, the process for R7RS has begun again. The R6RS standard didn’t leave many happy, so of course there is already heated debate starting on this standard.
One area that was readily agreed on is that Scheme needs to be split into 2 languages, a small language for academic purposes, a larger language for commercial/industrial programming.
There have been several threads going on about the different features that should be included, or excluded, from the small scheme. I thought about what was needed to be essential to a dialect for it to be considered scheme. As I was pondering this, a message from David Horn appeared on the r6rs-discuss mailing list that attempts to do what I was thinking of. I’ve reprinted it here for my own convenience, with formatting changes.
Essential Scheme is the minimal subset of the language expected to be supported by any Scheme system. It represents the fundamental and simple core of the language. It is lightweight at the semantic and implementation level. It is useful for research, prototyping, language experimentation, and understanding existing teaching materials. Its specification is comparable in size to research paper accounts of Scheme (i.e. much smaller than even R3RS).
Core
<variable>
(quote <datum>)
‘<datum>
<constant>
(<operator> <operand1> …)
(lambda <formals> <body>)
[includes dot patterns, body is sequence of one or more expressions.]
(if <test> <consequent> <alternate>)
(set! <variable> <expression>)
Derived
(cond <clause1> <clause2> …)
(let <bindings> <body>)
(letrec <bindings> <body>)
(begin <expression1> <expression2> …)
Programs
(define <variable> <expression>) …
Procedures
Booleans
(not obj)
(boolean? obj)
Equivalence predicates
(eqv? obj1 obj2)
(eq? obj1 obj2)
(equal? obj1 obj2)
Pairs and Lists
(pair? obj)
(cons obj1 obj2)
(car pair)
(cdr pair) ; and caar…cddddr
(null? obj
(list obj …)
(length list)
(append list1 list2)
Symbols
(symbol? obj)
(symbol->string symbol)
(string->symbol string)
Numbers
(number? obj) ;; Full tower is optional
(complex? obj)
(real? obj)
(rational? obj)
(integer? obj)
(zero? z)
(positive? x)
(negative? x)
(odd? n)
(even? n)
(exact? z)
(inexact? z)
(= z1 z2)
(< x1 x2)
(> x1 x2)
(< = x1 x2)
(>= x1 x2)
(max x1 x2)
(min x1 x2)
(+ z1 z2)
(* z1 z2)
(- z1 z2)
(/ z1 z2)
(abs z)
(quotient n1 n2)
(remainder n1 n2)
Characters
(char? obj)
(char=? char1 char2)
(char< ? char1 char2)
(char>? char1 char2)
(char< =? char1 char2)
(char>=? char1 char2)
(char->integer char)
(integer->char n)
Strings
(string? obj)
(string-length string)
(string-ref string k)
(string=? string1 string2)
(string< ? string1 string2)
(string>? string1 string2)
(string< =? string1 string2)
(string>=? string1 string2)
(substring string start end)
(string-append string1 string2)
(string->list string)
(list->string chars)
Vectors
(vector? obj)
(make-vector k)
(vector obj …)
(vector-length vector)
(vector-ref vector k)
(vector-set! vector k obj)
(vector->list vector)
(list->vector list)
Control features
(procedure? obj)
(apply proc args)
(map proc list)
(for-each proc list)
(call-with-current-continuation proc)
I’m not sure I agree with everything on the list, such as complex numbers being required for Scheme. Also, there doesn’t seem to be any provision for macros, so I would at least add defmacro. I won’t try to debate the merits of hygienic macros vs. lisp macros here, but I feel that defmacro would be easier to implement and to be more versatile, as things that are unrestricted generally are. Besides, hygienic macros can be implemented via defmacro.