Path: utzoo!attcan!uunet!decwrl!purdue!mentor.cc.purdue.edu!vyq From: vyq@mentor.cc.purdue.edu (William Burdick) Newsgroups: comp.lang.misc Subject: More LISP stuff Message-ID: Date: 27 Jun 90 17:37:26 GMT References: <10431@chaph.usc.edu> Sender: news@mentor.cc.purdue.edu Followup-To: comp.lang.misc Organization: /userf/vyq/.organization Lines: 163 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