The relative merits of the two languages are compared in 11 categories. In an attempt to make a more quantitative comparison, each language is assigned a score from 0 to 10 in each category. These scores are then combined, with appropriate weighting factors, to produce a total score. Each score was assigned as independently as possible, before weighting factors were decided; and weighting factors were chosen without examining the scores. In this way, the final scores are made as objective as possible.
Below, "LISP" refers specifically to Macintosh Common Lisp, except where a more general meaning is indicated by context. Similarly, the Python implementation in question in Mac Python (1.5.2b1). Other implementations of either language may differ in some respects.
Python's development started in 1990, less than a decade ago. However, because it is an open-source project, it developed very quickly. Bugs have been very rare, and have always been found and fixed rapidly after a new release. In addition, because all changes go through a central organization (originally CWI in Amsterdam, and now CNRI in Reston, VA), the language has been kept consistent and runs identically on all platforms.
LISP scores 10/10 for maturity. Python is much younger, but because of the quality and consistency of the implementations, it deserves 7/10. (In comparison, Java would currently rank only about 3/10, despite the huge user base, because of many inefficient and buggy implementations.)
| English | "y equals m times x plus b" |
|---|---|
| Mathematics | y = m x + b |
| Python | y = m*x + b |
| LISP | (SETQ y (+ (* m x) b)) |
While LISP syntax is very easy for a computer to parse, it does not follow the standard rules used by English, mathematics, and virtually all modern (i.e. developed within the last 30 years) programming languages. As a result, LISP code is unreadable to someone not experienced in the language, and learning the required skill takes considerable time. Python, in contrast, is mostly readable even to someone who has never seen Python code before.
If LISP were as consistent in its syntax as it first appears, the problem would be more approachable. Unfortunately, this is not the case; there are over two dozen predefined "read-macros" which change the syntax that is actually used, and more such can be defined by the user. So even after one grasps the notion of prefix notation, one must also learn the common read macros and what they do. Page 2 of the ANSI Common Lisp book (Graham, 1996) gives this example:
(defun addn (n) #'(lambda (x) (+ x n)))which is not understandable until you learn about the #' macro on page 25. In Python, this same function would be
def addn(n): return lambda x,inc=n: x+incBoth versions return a lambda function, which is a fairly advanced concept to a beginning (or procedural) programmer. But the Python version does not use any special syntax.
If this example seems obscure, consider the very simple case of binding a variable to a new list. In LISP, this is
(SETQ A '(2 4 6 8))which is fairly readable -- but what's that apostrophe doing there? It's another read-macro, which expands to a special operator (QUOTE), which keeps LISP from trying to apply "2" as a function. (SETQ is also a special operator that violates standard evaluation rules.) In Python, you'd write
A = [2, 4, 6, 8]which is even more readable, and does not involve any special operators or pre-processing.
In fact, Python does not have anything like read-macros, and doesn't need them because of its algebraic syntax. As a result, it can be argued that Python syntax is more consistent than LISP; everything is either a (unary or binary) operator or a function, with no special cases or exceptions.
Because of LISP's unconventional and (in practice) inconsistent syntax makes it so difficult to learn, I'm giving it 2/10 for syntax. Of all the languages I've used (including C, C++, Pascal, and FORTRAN), Python's syntax is both easiest to learn and most elegant to use, so it gets 10/10. (By comparison, C would rate about a 5.) Note, however, that syntax is largely a matter of taste, and a steep learning curve may be more or less important depending on how the language is to be used. So this score is quite debatable.
Many modern languages (e.g., C++ and Java) still lack this capability. But Python is not one of those; functions are objects which can indeed be passed around, used as parameters, returned as values, operated upon, etc. It is one of the vital features that make both LISP and Python such powerful languages.
Another related capability is that of constructing and compiling entirely new functions at runtime, possibly from strings or other primitives. Both LISP and Python have his ability as well.
Both languages score 10/10 in functionality.
Python's developer community has been steadily growing, and now appears to number in the thousands. Traffic on the Python mailing list shows a roughly exponential rise since 1991, with no signs of levelling off. A number of organizations use Python, including NASA, IBM, SGI, LANL, and LLNL. Of course it is difficult to extrapolate to actual numbers, but it is clear that the Python developer community is growing.
LISP books were common in the 80s and early 90s. A quick search at Amazon.Com found only one book on ANSI Common Lisp published after 1995 (plus a few books on "Autolisp", the extension language used with the Autocad application). There have been three Python books in this period -- but those may be all the Python books which exist.
The main Python newsgroup (comp.lang.python) has outnumbered the number of messages in the comp.lang.lisp and comp.lang.lisp.mcl newsgroups combined by a factor of 3 or so during an arbitrary survey period (the latter half of January 1999). Of course, this could be because LISP users, with a wider variety of reference books on hand, don't need to post questions to the newsgroups; there is also an MCL mailing list which gets several messages a day.
Overall, it appears that the LISP community is large but shrinking, especially on the MacOS platform. On other platforms it is evolving into derivative languages (such as Scheme) and specialized extension languages, such as that of Autocad and emacs. The Python community is comparatively small but growing rapidly. Both communities are small compared to C++, which is very mature, or Java, which is backed by a great deal of money. Thinking about both current size and direction of growth, LISP rates a 5/10, and Python a 4/10.
Unlike the last category, this one is easy to score: Python is open-source (10/10), LISP (at least MCL) is not (0/10). Note, however, that we'll weight this category less than others in the final scoring.
The standard Python distribution includes over 150 modules for diverse tasks such as random number generation, networking, parsing HTML or XML, encryption and compression, matrix manipulation, color handling, parsing, and regular expressions. The Mac distribution contains 100 more for handling things like Apple Events, GUI elements, manipulating the Finder, Internet Config, printing, etc. In addition, a large number of contributed modules are available for such needs as numerical algebra, interfacing to OpenGL, plotting, relational database handling, generating PDF or Postscript, and computational chemistry. Because of Python's multiple namespace feature, these can be used in any combination without fear of conflicts.
LISP has a large library of built-in functions, but I could not find a central repository of library modules, even at an index of Lisp Resources or via Yahoo. The CMU Common Lisp Repository contains some Lisp code for "benchmarking, research, education, and fun", but nothing comparable to Python's extensive library of modules which are actually useful. The only large library of LISP code I could find was a set of Artificial Intelligence Packages (also at CMU).
For its extensive set of useful and powerful modules, Python earns 10/10. LISP seems to be lacking this platform of developed, plug-in code except in the field of AI. On the other hand, particular implementations like MCL do contain their own libraries for accessing the toolbox and other common operations. LISP scores 4/10 in this category.
Note: I've been told that good libraries of LISP code (besides AI) do exist if you know where to look. So this score may need to be changed soon.
Python was designed to support both methods of integration. Calling C code from Python is very easy via the Simple Wrapper Interface Generator. Embedding Python in other code is equally easy. In addition, a new integration approach called JPython seamlessly combines Java and Python. (These issues are further discussed in an essay by Guido van Rossum, and documented in Extending and Embedding the Python Interpreter.) 10/10 for Python in this category.
LISP can make use of code written in C. Some variants (like elisp) have been used as embedded languages as well, but ANSI Common Lisp proper is not easily embedded -- or at least, not on the Mac platform. However, since this is less important than extensibility, LISP loses only 2 points. Since Java is likely to be increasingly important in the future, 1 additional point is lost for no integration (in either direction) with Java.
MCL comes with detailed manuals, and a large number of books are available for ANSI Common Lisp in general. While somewhat scattered and not easily searchable, this represents a significant amount of well-written documentation, earning 7/10.
The Python Documentation is virtually all online in HTML form. It is well-indexed, cross-linked, and complete, even including a very good tutorial; it is searchable, both via the web and via a Sherlock plug-in. There is also an O'Reilly book on Python programming. But that's about it -- Python lacks the quantity of books available on Lisp programming, leaving one's bookshelf a bit bare. Moreover, some of the modules (especially contributed modules) are documented less well than others. So Python earns 8/10 in this category -- slightly higher than LISP mainly because searchable, cross-indexed documentation is considered more useful than books.
For our purposes, it is important that the language we use get along well with the MacOS environment. For example, we want to be able to generate pictures as PICT structures, rather than pixel maps; we should be able to print, etc. Both MCL and MacPython seem to have these common functions well in hand. However, both currently lack support for the latest MacOS features, such as the Navigation Manager and the Appearance Manager.
Another aspect of MacOS integration is the integrated development environment (IDE). MCL's IDE is outstanding; it has powerful editing features, good interactivity, window control, good search capability, etc. It is only lacking in a few newer features such as drag-and-drop and syntax highlighting. The MacPython IDE is less developed, but improving rapidly. It has many of the same features as MCL's, including an object inspector and the interactive window, but is somewhat lacking in multi-file search and a few other areas. However, since the IDE is itself written in Python and open-source, it is improving rapidly.
Finally, each environment must be examined with an eye towards the future. MacOS X Server is coming next month, and MacOS X should be released before the end of 1999. MacPython has tested as "carbon-ready" and should run immediately under MacOS X without needing the "blue box" emulation layer. In addition, since Python also runs under many flavors of Unix, it is reasonable to expect that a fully MacOS X native version of Python will appear shortly after that OS is released.
MCL appears much less poised to transition to future MacOS systems. At its last release, in December 1997, MacOS 8.1 was the latest version of the OS. Though it runs well in 8.5 -- indicating properly-written software -- it naturally does not use the latest features, and is probably not Carbon-compliant. Without an update, it seems likely that MCL will run under MacOS X only within a blue box. However, recent messages to the MCL mailing list indicate that Digitool is indeed thinking about MacOS X and will probably produce a compatible version.
Python's Mac support is imperfect, but rather good, and it seems quite ready for MacOS upgrades; it scores 8/10. MCL's Mac support was very good in 1997, but is getting a bit dated, and I still question whether it will keep up with the changes to the OS -- so it gets 7/10.
Each of the raw scores attained above is included in the table below. They are then adjusted by a weighting factor. This reflects the relative importance of the categories; for example, we want a language which is very expressive; but whether the language is open-source or commercial is of only minor importance.
| raw scores | * weight = | adjusted scores | |||
|---|---|---|---|---|---|
| Python | LISP | Python | LISP | ||
| Maturity | 7 | 10 | * 5 | 35 | 50 |
| Syntax | 10 | 2 | * 8 | 80 | 16 |
| Expressiveness | 9 | 8 | * 10 | 90 | 80 |
| Functionality | 10 | 10 | * 5 | 50 | 50 |
| Dev. Activity | 4 | 5 | * 8 | 32 | 40 |
| Open Source | 10 | 0 | * 3 | 30 | 0 |
| Available Modules | 10 | 4 | * 7 | 70 | 28 |
| Extensibility | 10 | 7 | * 8 | 80 | 56 |
| Documentation | 8 | 7 | * 6 | 48 | 42 |
| Mac Integration | 8 | 7 | * 4 | 32 | 28 |
| Current Code | 1 | 10 | * 5 | 9 | 45 |
| Total | 87 | 69 | 557 | 435 | |
These results suggest that switching to Python is probably the correct choice for our situation. Python equals or surpasses LISP in 8 out of 11 categories -- or 8 out of 10 if we ignore our current code base. I can see only two plausible ways this conclusion could be avoided:
At the same time, see whether Python and MCL can be integrated via the Inter-Language Unification system (ILU). If so, this will allow us to call existing LISP code from the new Python programs, enabling a smooth, piece-by-piece transition.