This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Another idea on dynamic loading of scheme code


OK, I this is just an idea, have not tried it but I'm sure it's possible.


Think of a C program along these lines:

--------------------------------------------------
#include <libguile.h>

SCM s[ 1234 ];

void init()
{
	s[ 0 ] = scm_sysintern0( "first-symbol" );
	s[ 1 ] = scm_sysintern0( "some-other" );
	s[ 2 ] = scm_sysintern0( "thing" );
	s[ 3 ] = scm_sysintern0( "that-may" );
	s[ 4 ] = scm_sysintern0( "seem" );
	s[ 5 ] = scm_sysintern0( "important" );

/* more of the above */

    scm_sysintern( "thing-to-be-defined",
    scm_cons( s[ 3 ],
    scm_cons( s[ 1 ],
    SCM_EOL )));

/* more such unintelligible definitions */

}
--------------------------------------------------

This effectively just goes through the motions of
defining a whole bunch of symbols one after another as fast
as it can. You compile it, link it into an ELF shared object
and when you want it you use dlopen(); dlclose();
(the init() gets executed by dlopen()).

voila! your dynamic code is in there, does it's work and bails out,
leaving you with symbol definitions all over the place.

OK, the above code is pretty ugly to write but a translator
that converts a scheme file full of (define (blah)...)
statements into the above format would be easy to write.
Once the shared object is compiled, you can delete the C code and
pretend that it's really just loading up scheme.

On the good side -- it will be fast. Basically it just
does what a read() would do anyway but does it directly
with no parsing, scanning, whatever. The only speed limitation
is the speed of the hash table itself (maybe storing the
hash numbers would speed this up a tiny bit further but
that would require more direct access to the main hash table).

On the bad side -- the .so generated will be quite a bit
larger than the original scheme code, all the function
calls will make this worse than optimal w.r.t. size.
Emacs byte-compiled code is much smaller than its source.

On the good side -- the bloated size will only be on disc,
in memory you will only pay for the defined symbols themselves
which is the absolute minimum penalty that you can pay.
This is because, once used the DLL will be kicked out
again with dlclose().

On the difficult side -- if it is true that each module
stores its symbols in its own table already then some way
of specifying where the defines go to would be required.
(I haven't seen evidence of this in the read() code)
I'm sure someone could figure this out. The shared object
can execute any function in libguile to achieve the desired
result.

	- Tel

 PS: now that I think of it, could hobbit be reworked in a
minor way to turn scheme code into this sort of (define)
producing shared object? If it could then you could build
conditionals into the code to check the system type or
whatever else and define only the right things for the
current situation (you don't want too many smarts in your
libraries though, it starts to get a bit hairy).