Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!jato!granite!brian From: brian@granite.jpl.nasa.gov (Brian of ASTD-CP) Newsgroups: comp.lang.lisp Subject: I was a teenage C programmer Summary: why I use Lisp for many things now Message-ID: <1991Jan18.184354.19666@jato.jpl.nasa.gov> Date: 18 Jan 91 18:43:54 GMT Sender: news@jato.jpl.nasa.gov Reply-To: brian@granite.Jpl.Nasa.Gov (Brian of ASTD-CP) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 101 Nntp-Posting-Host: granite.jpl.nasa.gov Then I found Lisp (& Scheme & T) and everlasting happiness... Just my $0.02 worth on the "Lisp is living/dying" thread. After 12 years of using C for *all* my software (I do CS and astrophysics: operating systems, interactive graphics, computer-human interfaces, etc. etc.), I discovered Scheme by pure accident (I bought Abelson & Sussman's book on a lark and stumbled on Betz's XScheme PD compiler), and have used Common Lisp & T as well. Here's how I use these tools. * I use Common Lisp for experimental programming --- that is designing software; basically "figuring out what I want to do" and "figuring out how to do it". Result is an "exe- cutable design document." I use CL rather than Scheme or T just because it's a little easier for me to procure it on most platforms. Common Lisp is helpful for the following reasons (in priority order) -- The language of the programming environment is the same as the language of the program. Not true with Unix/csh and C. I have found that *anything* you want to do in a program you will ultimately want to do interactively in the programming environment, and vice versa. Interactive grep leads to the need to grep from a program, & so on. It's a big headache to do in C/UNIX/csh; basically you end with two versions of every interesting function, a C-callable one and a csh-callable one. This comes for free in almost all Lisp implementations. -- dynamic and recursive structures are really easy in all dialects of Lisp, and they're a big, recurrent headache in C. These structures are necessary for most interesting software (arrays are just not good enough). -- testing is easy because generic read / eval / print are built in. In C, you have to write special purpose read, eval, and print routines for every data type and every function. -- being able to create procedures at runtime with lambda is a big win and lets me do certain things that are impossible in C without implementing a "lambda calculator," which I had done several times in the past, each time a little differently for various, extrinsic reasons. -- programs can be stored in data files and interpreted at runtime. I call this "scripting", which may not be an accepted term for it (remember, I was a teenage C programmer). Most interesting application programs need scripting capability, and I've implemented it dozens of times in C, each time a little better and a little cleaner as I learned more. Lisp is, among other things, the ultimate, all-purpose, extensible, tailorable scripting language, and thus is the asymptote of my many years of C development. -- automatic memory management -- lots of mundane, ordinary, well-understood data types come for free: complex numbers, lists, strings, hash tables, etc. In C, I have to reinvent these things over and over again. * For portability, which is *very important* to me, when I actually "do it", after figuring out "what to do" and "how to do it", I probably use C, with the following provisos: -- If it's a small application (defined, by me, as one that doesn't need an embedded scripting language), I'll write the whole thing in C or contract it out to a C programmer using the CL code as design document. -- If it's a big application, which means it needs a scripting language. then I'll start with a simple-scheme interpreter (just the basics, Ma'am) written in super portable C. XScheme is my current favorite. I'll design an "application language," in which the application can be conveniently written, and implement the primitives of this new language in C and Scheme, but so they can all be called from Scheme. I implement performance-critical primitives, i.e. those that must conserve space or time, in C. I implement structure-critical primitives, i.e. those that are complex or otherwise challenging from a structural point of view, in Scheme. If I've designed the "application language" correctly, then the final application is implemented as a short script written in the application language. Usually, the script is just a sequence of commands in the application language, though occasionally loops and conditionals may show up. That's how I program nowadays. brian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Brian Beckman . . . . . . . . . . brian@granite.jpl.nasa.gov. . . . . . meta-disclaimer: every statement in this message is false . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .