Subject: Re: MIT's 6.001 scheme for Windows machines
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 1998/08/07
Newsgroups: comp.lang.scheme
Message-ID: <6qen8n$2kvkt@fido.engr.sgi.com>
Georges KO  <gko@gko.net> wrote:
+---------------
| "Adam Duston, 773.702.6289" <adam@crsp.uchicago.edu> writes:
| > ...installed DrScheme and it is a wonderful program.
| 
| 	Does it do foreign functions?
+---------------

No, and yes... and yes (sort of).

1. No, there isn't the kind of formal run-time FFI you find in some
   other versions of Scheme, in the sense of something that lets you
   transparently & automatically coerce Scheme types back & forth into
   C or C++ native types, given a simple C-like declaration in Scheme.

2. Yes, there is a [separate] package called "xctocc" that (given such
   declarations) generates glue code to allow MzScheme (the Scheme
   implementation underneath the DrScheme environment) to call and
   be called by C++ classes (used, for example, to glue MrEd & DrScheme
   to the C++ based wxWindows GUI system). See:
   http://www.cs.rice.edu/CS/PLT/packages/doc/xctocc/index.htm

3. Yes, it's really quite easy (as it is also in SCM, Guile, SIOD, and most
   other Schemes) to write dynamically-loadable extensions (new primitives)
   for MzScheme in C. It's copiously documented how to do this in:
   http://www.cs.rice.edu/CS/PLT/packages/doc/insidemz/index.htm

   The only "problem" (if indeed it's a problem for you) is that the
   C code has to deal with native Scheme types (since in essence it
   becomes an extension of the interpreter). But in MzScheme there are
   lots of handy interface routines available to do the conversions
   (amply documented in the above URL). To pass integers, doubles,
   strings, and chars back & forth is practically trivial. (More complex
   types are, well, more complex.  ;-}  )

   For example, suppose MzScheme didn't have an "exit" call [it does],
   and you wanted to add one, but you wanted it to be in a shared lib
   (because not *all* of your Scheme programs needed to exit, maybe).
   Here's the *total* of what it takes (and most of it's type- and
   error-checking code):

	#include <stdlib.h>
	#include "/usr/local/lib/plt/collects/mzscheme/include/escheme.h"

	Scheme_Object *my_exit(int argc, Scheme_Object *argv[])
	{ long exit_value = 0;
	  if (arg == 0)
	    exit(0);	/* with no args, just exit cleanly */
	  else if (!SCHEME_NUMBERP(argv[0]))
	    scheme_wrong_type("exit", "integer", 0, argc, argv);
	  else if (!scheme_get_int_val(argv[0], &exit_value))
	    scheme_signal_error("exit: couldn't convert arg to int");
	  else
	    exit((int)exit_value);
	  /*NOTREACHED*/
	  return scheme_void;
	}

	Scheme_Object *scheme_reload(Scheme_Env *env) {return scheme_void;}

	/* called the first time (load-extension "thisfile.so") is done.
	 * Note that we specify "exit" to accept from 0 to 1 argument.
	 */
	Scheme_Object *scheme_initialize(Scheme_Env *env)
	  scheme_add_global("exit",
		            scheme_make_prim_w_arity(my_exit, "exit", 0, 1),
			    env);
	  /* In a bigger library, more
	   * initialization would go here ...
	   */
	  return scheme_void;
	}

   Compile & link it (following the directions in the URL), producing
   (say) "my_lib.so". At run-time, in your Scheme program say:

	(load-extension "my_lib.so")

   and then when you're ready to give (say) an error exit:

	(display "usage: my_prog args...")
	(newline)
	(exit 1)


-Rob

-----
Rob Warnock, 7L-551		rpw3@sgi.com   http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
2011 N. Shoreline Blvd.		FAX: 650-933-4392
Mountain View, CA  94043	PP-ASEL-IA