This is not an R7RS page; it's just John Cowan's notes on an idea that used to live on a scrap of paper.
Bottom Scheme is a tiny subset of R7RS-small. It is not really a Scheme at all, because it omits assignment, macros, modules, proper tail calls except in named let, multiple values, call/cc, dynamic-wind, mutable pairs and strings, I/O (except for read-char and write-char), and essentially all non-primitive procedures.
This list is organized according to the R7RS-small report.
No case-folding directives.
Only ; comments.
Parens, apostrophe, quoted strings, #t and #f, and number, vector, and bytevector constants. No backquoting, character constants, number bases, or labels.
Variables, constants, procedure calls, lambda without improper formals, if.
Only cond without =>, and, or, let, letrec, begin, and named let (with the restriction that the bound procedure can only be invoked in tail positions within the lexical scope of the let).
Full support for define-record-type.
Only eqv? (for which eq? is a synonym). Programmers are encouraged to provide their own definition of equal?.
All types are supported.
The only exact numbers are integers within a fixed range.
Inexact real numbers are IEEE doubles; inexact complex numbers are pairs of IEEE doubles in the rectangular representation.
/ is not supported, because all exact numbers are integers. Base and exactness prefixes are not supported. The notations -0.0, +inf.0, -inf.0, and +nan.0 are supported.
Predicates: number?, real?, exact?, inexact?. Arithmetic: +, -, *, / with two arguments only; / always returns an inexact value. Transcendental functions: exp, log (one argument), sin, cos, tan, asin, acos, atan (one argument), sqrt, expt always return complex numbers. Complex: make-rectangular, real-part, imag-part. Conversion: exact, inexact.
As an enhancement to R7RS-small, the non-generic arithmetic functions fx+, fx-, fx*, fl+, fl-, fl*, fl/, cx+, cx-, cx*, cx/ are provided.
Only #t and #f notations, not, boolean?.
Pairs are immutable. Only pair?, cons, car, cdr, null?
Only symbol?, symbol->string, string->symbol.
Not supported; use single-character strings instead.
Full support for string literals. Strings are immutable. All Unicode characters are supported except U+0000 (NUL). Only string?, string-length, string=?, string<?, string>?, substring, list->string.
Full support for vector literals. Only vector?, make-vector (one argument), vector-length, vector-ref, vector-set!.
Full support for bytevector literals. Only bytevector?, make-bytevector (one argument), bytevector-length, bytevector-u8-ref, bytevector-u8-set!.
Only procedure?, apply.
Only read-char (no arguments), eof-object, eof-object?, write-char (no arguments), display (mostly for debugging).
These notes assume a 64-bit system.
With the basic object 64 bits in size, NaN-boxing is a plausible technique. In this scheme, IEEE doubles are represented as immediates, and all other objects are stuffed into the signaling NaN space (high-order bit is 0, next 11 bits are 1, next bit is 1). This limits them to 52 bits in size, which is enough to hold 64-bit pointers in current architectures, since they are only 47 bits in size (excluding the kernel area). Because a pointer to a 64-bit value always has the low-order three bits zero, they can be used for the following tagging scheme: