gjc@paradigm.com (11/02/90)
You know what would improve the state of the art of lisp implementations a bit? If somebody wrote a LISP front-end to GCC. Really, it should be easier than the C++ stuff that was done with GCC. Just handle the syntactic and lexical scoping issues (GCC already handles most of the control construct issues that come up), and *dont* *worry* about garbage collection. Pass lisp arguments just like arguments to C procedures. A definite must: Implement numeric declaration optimizations, fixnums and floats, for expression evaluation, argument passing and return values. Another must: Translate the names of arguments and local variable symbols as little as possible, make sure compiled code can be debugged effectively using GDB. As far as the GC goes, don't sweat it. I have some minor (in terms of understandability) extensions to the techniques used in SIOD that handle the C object vs. C object ambiguity extremely well in practice and while supporting the more modern lisp data structures. The result: A production-quality lisp that lives up to the standards of PDP-10 maclisp and more. A portable lisp with an understandable and nearly universally supported compiler. Maybe RMS will spend some of that MacArther money he won on a lisp front end for GCC. Or maybe somebody good enough will decide to stop screwing around with stuff like KCL and go for the brass ring. -gjc
barmar@think.com (Barry Margolin) (11/04/90)
In article <1353@paradigm.com> gjc@paradigm.com writes: >You know what would improve the state of the art of lisp implementations >a bit? If somebody wrote a LISP front-end to GCC. Well, it's not GCC-specific, but it seems like Chestnut's Lisp to C translator does most of what you say. It also does GC (and provides ways to control it) and generic arithmetic when declarations aren't provided. About the only problem is that they charge about $100,000 for it. -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
gumby@Cygnus.COM (David Vinayak Wallace) (11/05/90)
Date: 2 Nov 90 14:02:11 GMT From: gjc@paradigm.com You know what would improve the state of the art of lisp implementations a bit? If somebody wrote a LISP front-end to GCC. Jim Miller and I discussed this at the last Lisp conference, using GCC as the back end for GAMBIT. You're right in that it wouldn't be that hard, though there is a little more work than you implied. Looking over my notes: PVM (GAMBIT's representation) or s-codes are a little higher-level than rtl in that rtl doesn't understand things like closure variables (e.g. for CL it could compile flet only if you didn't use upward funargs) and a little low-level (ie rtl can represent loops, so that it can do various optimisations; PVM represents loops with branch instructions). To do a decent lisp with GCC would require the following modifications: The addition of an apply operator, since the calling conventions differ, and a modification to procedure code generation so that functions could have lisp entry points and optimised (post-arg- checking) entry points for calling by C code and perhaps for compiler-generated calls when the arity and type are known at compile time. The calling sequence would have to be fixed too, of course. The real problem is GC. You really want to tell the compiler about register conventions it should share with the GC. Unfortunately most processors now have register usage conventions which are followed by C compilers and which don't allow you to be able to depend on this. Also, several new machines have register windows which make it expensive for the GC to scan the machine state (register windows also make it extremely unpleasant to use any sort of closure as a funarg). GCC naturally uses register windows heavily on the machines which implement them. We're modifying GCC to allow certain kinds of conservative GC without scanning the machine registers or stack, but this isn't cheap either. If you removed the requirement that the compiler trivially intercall with existing programs then this would become a lot easier. Using GDB on generated code would be easy in any case, but you'd lose all the benefits of having lisp in your debugging environment! Perhaps the thing to do would be to link parts of GDB into your runtime. The reason the FSF isn't doing anything like this appear to be a two (but I don't speak for them): rms' priorities lie in different areas, and you can't really just write a compiler: you have to write a whole lisp implementation. Brian Fox wants to work on one; has anyone some money for him?
bothner@sevenlayer.cs.wisc.edu (Per Bothner) (11/13/90)
I've done some thinking about how to design a multi-language integrated language environment, including Lisp support. I've been working on a very high-level language, which supports first-class functions, run-time types, abstract sequence objects, and various other features. In other words, a language closer to the Lisp family than C++. In spite of that, most of the run-time system is written in C++, using a nihlib-like Object hierarchy. I also compile my language into C++ (though the compiler suffers from heavy bit-rot, since I'm waiting for some features to be added to g++). Some notes: My compilation model is based on persistent objects, or saving a workspace: A source "module" is loaded (parsed and evaluated), and then the resulting "workspace" is "dumped." I write it out as a C++ source file: The objects local to the workspace are emitted as static C++ data declarations. The methods/functions are compiled into source code. (I haven't worked on the compiler for a while. I understand g++-2.0 will emit run-time type descriptors. When available, I will remodel my "Class" class to use these descriptors. This will allow me to simplify the compiler, the run-time system, and the emitted C++ code.) All objects are pointers. There are no tag bits on the pointers. This allows compatibility with the C++ object model, which gives uniformity, and easier interaction with other tools. I pre-allocate "small fixints" (about the range -100..+1000) for speed and space, and these are guaranteed to be "eq". I use the DEC PRL package for infinite precision integer arithmetic. However, I don't use their signed-magnitude implementation of signed integers; instead I implemented a two's-complement package. This allows fixnums to be a sub-class of bignums, which is quite convenient: I can write a single implementation for (say) gcd, or I can choose to write two (one bignum, one fixnum) for speed. It also makes it easy to implementent the common lisp semantics for logical operators, shifts, etc. Symbols: Symbols are conventional. So far I just implement "keyword" symbols: No packages, "set", or property lisps, but adding these shuld be straight-forward. Since symbols must be interned, this causes a problem with separate compilation: I emit C++ data declarations for the various types of object; however each symbol with the same print-name must be globally unique. I solve this problem by emitting a symbol as an "extern" reference, and then using the linker to actually allocate the symbols. (Currently, I use a utility program prior to linking, but I would like to merge this code into ld.c at some point.) Functions: Functions are first-class, and closures are generated automatically. Functions can take variable number of parameters, defaults, and keyword parameters. I support full logic programming (logic variables, unification, backtracking, as well as constraints); however, the implementation is undergoing change. I'm experimenting with supporting shell-like features: A command is a function that takes one string input (stdin), some keywords (argv), and emits a string as output (stdout). This makes a nice model for a functional shell. A disk file is a string variable. An open input file is a character iterator. I've made some effort to make the syntax convenient and pleasant for interactive use. Garbage collecton. I have punted on garbage collection for now. In the long run, I'm hoping to use the implementation under development for Modula-3 by Eliot Moss and others, especially if it can be adopted for C++ (or a dialect thereof). Lisp: I have been thinking about putting a Lisp front-end on my system (and making the needed changes to the run-times). I've been toying with various Lisp dialects. One possibilty is to take gnu emacs, and re-write the definitions of Lisp_Object in terms of a C++ object hierarchy based on my existing system. I don't know yet how pervasive the changes would have to be, but since GNU code (including emacs) makes heavy use of accessor macros, I hope it would not be too bad. And the benefit would be an extensible, object-oriented emacs, in addition to providing a lot of useful library routines for my own language. Availability: Well, not really yet. There is very little documentation, the code is not robust (poor error recovery), I constantly re-write lange portions of it, there is lots of obsolete or no-longer-working code, and the compilers emit many warnings (mostly about const/non-const mismatches). The code has only been tested recently on a 68020 system running 4.3 bsd (Sony News), though in the past it ran on VAX ultrix. I believe it should port easily to any machine with gcc and g++. Berkeley a.out format would be a plus. There are some machine dependencies (including assembley code); the major ones are to support backtracking (which is not essential and will probably be replaced anyway). If there is interest, I could make a version available, to (brave) people who will to return improvements to me. By the way, I call my language "Q", for no good reason. Those who are interested could look at my dissertation: Efficiently Combining Logical Constraints with Functions, Stanford, 1988. It gives a flavor of an early version of Q, but the syntax has changed quite a bit, and I've had some second thoughts. -- --Per Bothner bothner@cs.wisc.edu Computer Sciences Dept, U. of Wisconsin-Madison