[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Five is not enough

   From: Paul Graham <paulgraham@yahoo.com>
   I also don't buy this story that all you have to implement
   are the "big five".  Just look at the Scheme report.  All
   the things that are not described as "library procedures"
   are stuff you have to implement as primitives: strings,
   vectors, math, i/o, etc.

   No real, usable language can be made out of 5 primitives.
   It is still a very interesting question, though, how small
   you can get the core to be.  


You are right. The five core Scheme forms (LAMBDA, SET!, IF, DEFINE & QUOTE)
don't make a complete language; they just make the core -- the skeleton that
gives the underlying structure to the language.

To get a useful language, you must then go and add the datatypes and primitive
operations that are important to your language's intended application domain.
People do this *all the time* in the Scheme world. For example, if you link in
a mess of X-windows C routines as the primitive operators, and add the
appropriate datastructures, then you get sawfish, the popular Unix window
manager. If you add paths and fonts and bounding boxes and transforms, then
you get FPS, "functional postscript," a rather nice language for describing
pictures that can be executed to produce regular PostScript. And so forth.

The nice thing is that if you learn and master this powerful core structure
once, then you can use it in all of these little purpose-directed languages --
you only need to learn the domain-specific datatypes & primitive operators in
each one. Maximal semantic & syntactic overlap => easy to incrementally

I *don't* think linked lists or bignums or floating-point numbers or, really,
any other datatype other than procedure is required to make a language a
Scheme. (But there are, of course, much more stringent requirements to
make a language "R5RS Scheme," a fairly precisely defined standard.) What
you need to have a Scheme is (1) s-exp syntax and (2) the five (or six or
seven, depending on how you count -- I did leave out CALL/CC and LETREC)
core forms.

Note that things like LET & COND & AND & OR & BEGIN *aren't* core. You
can *easily* provide them as macros that expand into the core forms.

These ideas were articulated at the very birth of the Scheme language, and
the Scheme community usually sorta just takes them for granted, but I
repeat them here for the benefit of folks who aren't immersed in the Scheme

BTW, I regard the "classic" list of core forms as being inadequate for
serious, large-scale work. You also need modules and exceptions and abstract
datatypes and records and macros and threads. I also think dynamically-bound
"fluid" values are very useful for packaging up what would, in other systems,
be process-global or thread-global state. But the real "flavor" of Scheme
comes from the core forms we've been discussing.