[comp.lang.misc] More LISP stuff

vyq@mentor.cc.purdue.edu (William Burdick) (06/28/90)

This article compares two LANGUAGES (C and LISP) for some of their
relative merits in writing MUDs (and other large, general programs).
It does not compare the programs written in those languages, but the
languages themselves (and the standard libraries for those languages).
It has been proven over and over that you can write any program in any
language.  The point I stess is that the merit of a programming
language is not only in its apparent efficiency, but in its ease of
use and, more importantly, in how productive you can be when you use
that language.

Both C and LISP are good languages to use for almost anything.  They
do, however differ in their strong points.  C is fast, but lower level
than LISP (see my earlier article).  LISP is slower than C (even when
compiled), butit has a broader base of general library functions and
it is more 'introsective' than C -- functions and types are 'first
class objects' in LISP; you can operate on functions (like inspect
the code they contain, construct functions at run-time, etc.) and data
types (like compare data types, define or change data types at
run-time) in LISP.

The advantage of having a large body of general data types and
operations is well established in the software engineering community
and it is perhaps the main reason that object-oriented languages are
becoming more and more popular.  Common LISP is not object oriented
(CLOS, the Common LISP Object System is object-oriented, though), but
it shares some of the advantages with object-oriented languages that C
does not.

In article <10431@chaph.usc.edu> news@usc.edu writes:

[This person is named 'W,' according to his/her signature.  He/she did
not identify him/herself in any other way]

      1) If you want to operate on types in C, you must build your own
	 framework for doing so and this framework will not hold up for
	 types defined in the future.

   ahh... I guess that means we can't implement a lisp type system in
   C... geez..

   Probably ought to have rms pull typeof() out of gcc while we're on the
   subject.

Typeof in gcc is NOT a function, it is an operator which allows some
operations on types.  You cannot say 'if (typeof (s) == typeof (t))'
in gcc, nor can you say 'switch (typeof (s)),' but you can say
'f = (typeof (f))x' to use it as a cast, and you can say
'(typeof (q))a, b, c;' to declare variables a, b, and c, which are the
same type as q.  If you read the gcc info file, you'll see that typeof
expressions can be used anywhere a type name can be used and, of
course, you can't treat them as data.  As for implementing a LISP type
system in C, if you use LISP's type system in C, you aren't using C's
anymore, but you are allowing that LISP's is better for your uses and
you should think about using LISP instead of C.  You cannot write a
typeof function in C, which will return the type of an arbitrary
datum.

      2) interpreted.

   *sigh*  And I was having so much fun with lpc...

Of course you will want to compile functions after testing them.  But
as W seems to miss, while you are testing them, it is much easier to
test with an interpreter, where you can reload your functions while
the program is running.  That is, of course, why C interpreters are
starting to become popular (Objectworks by ParcPlace, for C++, is one
example).

      3) LISP interfaces easily with C.

   Actually, this is one of the more significant advantages of LISP over
   C. :)

Actually, it is.  You can write any picky little efficient functions
in C, if you want speed.  You can also write operating system specific
code in C (like socket code) and link it to LISP.

      4) parsing.

   I guess cuz LISP is so adept at dealing with stacking parsing tables
   or something...

The parsing advantage refers to the built in functionality for
parsing; character macros, the read function (which tokenizes and
parses text for you), etc.  Of course you can write these and many
other functions in C.

      6) functional decomposition.  The functional operators in LISP provide
	 for powerful metaprogramming constructs which simply aren't
	 possible in C, because all LISP functions are just lists.

   correction, you have to build such a meta system if you are using C,
   or beg/borrow/steal one...  It's not hard to make data-driven
   functions (e.g. looping operators) in C though.

There are no functional operators in C.  If you build a 'meta system,'
then the resulting code which uses that meta system is written in that
system, not in C.  Obviously, if you use a version of LISP written in
C, you are not programming in C.  If you use an ADA compiler written
in C, you are not programming in C.  The point here is that in order
to use functional operators (and we used them a lot in our MUD) when
you are writing in C, you have to build them from scratch; a waste of
time you could otherwise be spending on writing your MUD.  As for
looping operators (I'm assuming W means functions which loop over a
collection of data), those are just more of the functions you have to
write to support your data types which you had to define, when you
could have used the ones already provided in LISP.

      7) wide range of standard data types and operations.  Look through Guy
	 Steel's Common LISP book.

   Yeah, no way can you POSSIBLY implement dynamic variable bindings
   through three levels of private symbol tables in C :)

Of course, every programming language is just as powerful as every
other programming language; they are all turing equivalent.  The point
which W (and perhaps others) seems to miss is that the advantage is
in the large body of *general* data types and operations *already*
written for you.  You don't have to waste time on it.

	 [something about being able to reuse code written in LISP]

   Ok, a clear win for lisp.. you have to through away everything each
   time you write a program in c.

I have yet to see a C programmer use the same linked list code,
unaltered, in all his/her programs which use linked lists.  Code reuse
is possible in C, that's what libraries are for.  Nevertheless, most
programmers would rather rewrite all the tiny utilities over and over
again than go to the trouble of writing a library for them.

To write truly general routines for data structures such as linked
lists in C, you must be able to store any type in them: float, int,
char, double, long, structures, unions, etc., and those in any
combination.  Suppose I use a linked list package which is already
written in C and I use these lists to store the contents of my rooms.
If all objects which can be in a room are of the same type, no
problem.  Suppose that I have different types for different kinds of
objects, though.  For instance, I have one type for people, animals,
etc., one type for containers, and one type for objects which are not
containers or people (like tinymud objects), such as stones, books,
etc.  If I store a variety of these kinds of objects in the same list
and examine each element of the list, I can't tell which objects are
which type, because there is no typeof function which returns a type.
If I can't tell what type the elements are, I can't use them at all.

Of course, you can build C structures with type information in them
and examine that information, but then you are not using C's type
system, anymore.  The problem is that you have to build these kinds of
extra structures in C, in order to write a general program, like a
MUD.  In LISP, you don't.  It's a matter of software engineering --
you must decide how much extra stuff you want to write, in order to
implement the MUD, which doesn't have anything to do with the program
itself, but with the limitations of the language you are writing the
program in.

   W
--
TEAM CTHULHU IS:
Mitch Adler	mitch@apple.com
Bill Burdick	vyq@fugue.cc.purdue.edu 
Roy Riggs	vyq@fugue.cc.purdue.edu / rcr@mdbs.UUCP

lgm@cbnewsc.att.com (lawrence.g.mayka) (06/29/90)

A few clarifications and elaborations:

In article <VYQ.90Jun27123726@mentor.cc.purdue.edu> vyq@mentor.cc.purdue.edu (William Burdick) writes:
>The advantage of having a large body of general data types and
>operations is well established in the software engineering community
>and it is perhaps the main reason that object-oriented languages are
>becoming more and more popular.  Common LISP is not object oriented
>(CLOS, the Common LISP Object System is object-oriented, though), but
>it shares some of the advantages with object-oriented languages that C
>does not.

Before CLOS, industrial Common Lisp applications often used either
Flavors or Loops, CLOS' predecessors.  Genera, Symbolics' workstation
operating system and development environment, is written using Flavors.

Even without CLOS or Flavors or Loops, Common Lisp has garbage
collection, run-time behavior selection (to a fair extent), and
an extensible hierarchy of datatypes - the three distinguishing
marks of OOP, according to "Smalltalk-80: Bits of History, Words of
Advice" (page 10).

>Of course you will want to compile functions after testing them.  But
>as W seems to miss, while you are testing them, it is much easier to
>test with an interpreter, where you can reload your functions while
>the program is running.  That is, of course, why C interpreters are
>starting to become popular (Objectworks by ParcPlace, for C++, is one
>example).

Actually, we should distinguish between incremental loading and actual
interpretation.  Common Lisp can incrementally load either compiled or
interpreted functions into either a compiled or interpreted environment,
with transparent cross-calling.  ObjectWorks for C++ does not include
a C++ interpreter at all, as far as I know, but it is admired for its
incremental loading capability (a rarity in the C/C++ world).

>in C, you are not programming in C.  The point here is that in order
>to use functional operators (and we used them a lot in our MUD) when
>you are writing in C, you have to build them from scratch; a waste of
>time you could otherwise be spending on writing your MUD.  As for
>looping operators (I'm assuming W means functions which loop over a
>collection of data), those are just more of the functions you have to
>write to support your data types which you had to define, when you
>could have used the ones already provided in LISP.

Much of the convenience of functional and iterative operators is
lost, however, if one doesn't have lexical closures.  (C/C++ does
not, Common Lisp does.)


	Lawrence G. Mayka
	AT&T Bell Laboratories
	lgm@iexist.att.com

Standard disclaimer.