2012-06-08

Programming languages, their implementation strategies, and their communities

Programming languages can be divided into three groups based on their implementation strategies:

A) Multiple competing implementations, relatively small standard libraries, many third-party libraries available. C, C++, Cobol, Fortran, JavaScript use strategy A.

B) A single dominant implementation which comes with a fairly large library which everybody uses; typically there is no formal standardization. Substantial third-party libraries may or may not be available. Second-source implementations are continually playing catch-up with the dominant version. Ada, Java, Perl, Python, Ruby use strategy B. So do most DSLs, research languages, and personal toys. Haskell used to be strategy C but is now B due to the increasing dominance of GHC.

C) Multiple implementations, relatively small standard libraries, each implementation comes with lots of libraries. Substantial third-party librarys may or may not be available. The Lisp languages use strategy C; so do Forth, ML, and the Posix shell.

Common Lisp and the shell have fairly large standard libraries (for the shell, it's the Posix utilities that constitute the library); R5RS Scheme and even R6RS Scheme have fairly small ones. When the R7RS Scheme process is complete, the relative sizes in the Lisp world will be R5RS < R7RS-small < R6RS < Common Lisp < R7RS-large, but the standard libraries of R7RS-large will be optional for conformance rather than mandatory, so Common Lisp may still be larger in practice.

In a strategy C language, an implementation is more than just an implementation; it's a community, or even a movement. Strategy A languages don't draw this sort of loyalty for the most part; decisions between implementations are based only on cost, or else technical criteria such as speed, space, compilation speed, or availability in a particular environment. Strategy B languages have only one community per language, with a few splinter groups; that's what makes them such juggernauts today.

But to write your code for Chicken or Racket or Chibi Scheme involves more than a cold-blooded decision about the advantages of these particular environments. Technical factors may control the choice in some circumstances. But where they don't, people end up deciding based on essentially tribal factors, the same that make people fanatically loyal to vi or Emacs (or, in my case, "ex").

That's not necessarily a bad thing. But it would be a good thing, unqualified, if some of the library code available to Chicken programmers was also directly available, without fuss, to Racket or even Chibi Scheme programmers. Essentially everything new in R7RS-small is in pursuit of that goal one way or another. Likewise, the packages in R7RS-large (which is not yet fully specified) are meant to help at a higher level with that interoperability goal.