Scheme doesn’t have a proper list type, in the same way that C doesn’t have a proper string type. In Scheme, a list is a chain of 2-tuples (“pairs”) terminated by the empty list, which is a special type that says “this is the end”. In C, a string is an array of characters terminated by the null character. You get the idea.

As a result, just like you can create C strings that are not null-terminated, you can also create Scheme lists that are not terminated with the empty list. These are called Improper Lists.

Since most Scheme code is designed to work with (empty list-terminated) proper lists, improper lists have always acted as little more than an annoyance to the programmer. Their inconsistent link structure makes them impossible to use with many common list algorithms (see SRFI-1 for more details); their unfortunate participation in Scheme syntax (specifically, the declaration of variadic procedures) requires that any Scheme reader/writer/compiler support two list syntaxes.

Today, improper lists have little utility. In the early days of hardware their main advantage was a space saving of one pair per list, since they store the last two elements as (y, z) instead of (y, *) -> (z, empty list) . Today with modern hardware it seems that increasing the complexity of the compiler, reader, writer, and list algorithms only to save a pair per list just isn’t worth it.

So Bee no longer supports improper lists. cons enforces that its second argument be a pair or the empty list, and lists are immutable anyway, so constructing improper lists is impossible.

Variadic functions can still be declared without problem because Scheme has other syntax for declaring variadic functions: (lambda argv body ) , where argv is a list that contains the arguments at runtime. Of course, this syntax is less sweet because it doesn’t let you declare functions that take at least n arguments. It can be re-sweetened by introducing some kind of macro that injects an assert that makes sure that the procedure is called with the correct number of arguments, a block that binds the first n elements of argv to the first n parameters, and finally the lambda body.

Good riddance.