[gambit-list] How to create small standalone executable with

Taylor R Campbell campbell at mumble.net
Mon Aug 17 13:01:30 EDT 2009


   Date: Mon, 17 Aug 2009 11:04:26 -0400
   From: Marc Feeley <feeley at iro.umontreal.ca>

   Are you saying that Scheme48 does not adhere to that Lisp philosophy?   
   I thought Scheme48 supported "live debugging" and that it was the  
   default execution mode.  Does the debugger rely on eval?  What happens  
   when an exception is raised at run time?

The REPL (or `command processor', `development environment', &c.) is a
program just like any other.  The REPL uses EVAL, and knows about the
environments of (some of) Scheme48's internals, including the REPL's
environments (i.e. the environments in which the REPL's source code
were compiled) -- that is, the REPL is reified.  If you run your
programs under the REPL, it will establish condition handlers that
cause the debugger to be entered, and all the environments of your
program, and any libraries in Scheme48, will be available.  But the
REPL and the database of your program's global variables aren't
built-in to the compiler or to the virtual machine or to the run-time
system -- you get what you ask for.  If you make your program not to
run under the REPL (and don't establish condition handlers that will
enter the REPL), then you won't get the REPL.

The point isn't that Scheme48 fails to be adhere to any philosophy of
Lisp -- the point is that Scheme48 is a configurable system of parts,
not a monolith of global databases as many other Scheme systems are,
and as Common Lisp is mandated to be.  Fortunately, Scheme is not
mandated thus.  So for Scheme48, shrinking images is not a matter of
going to the extra effort of walking through the global databases and
destroying links that you don't want (`tree-shaking'); it's only a
matter of specifying what you do want, and then anything not required
by that will be omitted anyway.

   On my MacBook Pro I checked the size of the runtime system of
   Scheme48 and Gambit and there is in fact very little difference
   (scheme48.image=2.7MB and gsi=3.3MB).  Also, when executing (let
   loop () (loop)) the ps program reveals that Scheme48 has a RSS of
   6.4MB and Gambit has a RSS of 2.4MB.  So at execution time, for a
   small program, Scheme48 seems to take 2.5 times as much memory as
   Gambit.

If you evaluate (LET LOOP () (LOOP)) in the REPL, all of the REPL and
libraries will remain in the image.  If you build a new image that
only evaluates (LET LOOP () (LOOP)), it will be much smaller:

> ,build (lambda (arguments) (let loop () (loop))) foo.image

% ls -lh foo.image
-rw-r--r--  1 riastradh  riastradh   740K Aug 17 12:15 foo.image

The 740K consists mostly of the run-time system, which is initialized
in images created with the ,BUILD command -- starting the thread
scheduler, enabling interrupts in the virtual machine, establishing
the dynamic environment for the current input and output ports, &c.
This can be omitted, too:

> ,open write-images
> (write-image "bar.image" (lambda arguments (let loop () (loop))) "")

% ls -lh bar.image
-rw-r--r--  1 riastradh  riastradh    14K Aug 17 12:19 bar.image

(There is still a bit of extra gunk in this image due to the FFI.
Before Scheme48's current FFI, bar.image would have been even smaller;
e.g., in Scheme48 0.36, the above call yields a baz.image of only 148
bytes.)

How much heap space Scheme48 allocates is a run-time option which
doesn't change by default (unless the image is too large for the
default heap space).  And of course Scheme48 is based on a virtual
machine, all of which is loaded into memory; in this respect Gambit
has a theoretical advantage, because there is no (run-time) virtual
machine needed to interpret its compiled code.



More information about the Gambit-list mailing list