From: jinx@zurich.ai.mit.edu (Guillermo J. Rozas)
Newsgroups: comp.lang.scheme
Subject: Re: stand-alone executables
Date: 31 Aug 92 15:37:54 GMT
Reply-To: jinx@zurich.ai.mit.edu
Distribution: comp
Organization: M.I.T. Artificial Intelligence Lab.
In-reply-to: jimb@occs.cs.oberlin.edu's message of 25 Aug 92 10:33:28 GMT

In article <JIMB.92Aug25053328@occs.cs.oberlin.edu> jimb@occs.cs.oberlin.edu (Jim Blandy) writes:

|   In my experience, stand-alone executable files generated by scheme
|   compilers tend to be very large.  For example, compiling the program
|
|	   (display "Hello, World!")
|	   (newline)
|
|   using the Gambit scheme compiler on an HP9000/375 running BSD produces
|   a 400k executable file.  Last I checked, Chez scheme didn't do too
|   well either (although that was a while ago), and I seem to recall
|   Scheme->C producing a 500k executable file for a program which
|   computes and prints the factorial of a number.
|
|   This seems odd to me.  Gambit's interpreter, gsi, is 400k, which
|   suggests to me that Gambit's standalone generation system just throws
|   the whole interpreter in with your code.
|
|   This is a pretty small sample of scheme systems; is this behavior
|   common?  Are there many schemes out there which generate
|   reasonably-sized executables?  If not, why does everyone find it so
|   difficult to generate them?  Is it so challenging to do the sort of
|   linking C compilers do, and throw away the unnecessary library
|   routines?

It is not conceptually difficult.  Just painful in practice.
I'm most familiary (obviously) with MIT Scheme, so most of the
comments below apply to that implementation.  However, I don't think
that they are unique.

There are two major obstacles:

- Decomposability of the system:

The system (runtime support library) must be written in such a way
that it does not depend on the whole thing being around.  Even static
linkers would drag quite a bit of code given the way that a lot of
Lisp systems are written, where, for example, MAP can call ERROR, and
ERROR can call the debugger and the read-EVAL-print loop.

It is somewhat more painful (and goes against the grain of what Lisp
programmers have traditionally wanted) to write a system that can't
really depend on any other part of the system being there yet has the
hooks so that they will be used if they are.

- Lack of support from external tools:

There are little things that have to be compensated for because most
system linkers (e.g. ld) are really only adequate for static languages
such as C and Fortran are static languages with a "main" procedure
that must explictly invoke and initialize the rest.  For example:

Lisp programs often include (quoted) constant objects that must be
understood by the GC.  Either they live in the ordinary heap (and the
static code must then copy them on initialization and have some means
to reference them that can be tracked by the GC so that pointers can
be updated when relocated) or you use a GC that does not move (at
least this) stuff around.  Either way, it is a level of complication
that you might not have had otherwise.

Lisp programs are not procedure static declarations, but must be
executed (evaluated) in order to arrive at their "ground state".  In
other words, Lisp programs are not only a collection of procedure
definitions, but also some code that needs to be executed when the
code is "loaded" (think for example of map defined as
``(mapper-procedure car)'').  To solve this one, you can change your
style to have a "main" function and explicit initialization, or you
must pre-run the program before linking so that all initialization is
already done, or you have to do some extra work to make sure that your
main function will invoke the initializers for each of the modules you
are linking.

Overall, it is doable, but painful enough that Lisp implementors
(unfortunately) postpone implementation of such a capability.

|   I'd like to be able to invoke small scheme programs from the shell and
|   not have it take several seconds to load and occupy several megabytes
|   of swap space.
|   --

I agree this would be nice to have, however, I try to use the shell as
little as possible :-).
Newsgroups: comp.lang.scheme