Newsgroups: comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!ix.netcom.com!netcom.com!NewsWatcher!user
From: hbaker@netcom.com (Henry Baker)
Subject: Re: Scheme->c
Message-ID: <hbaker-2201951329000001@192.0.2.1>
Sender: hbaker@netcom.com (Henry G. Baker)
Organization: nil
References: <3fl3vb$iqa@homer.cs.mcgill.ca> <JDONHAM.95Jan20183123@hadron.us.oracle.com>
Date: Sun, 22 Jan 1995 21:26:46 GMT
Lines: 51

In article <JDONHAM.95Jan20183123@hadron.us.oracle.com>,
jdonham@us.oracle.com (Jake Donham) wrote:

> "robab" == Bahman SISTANY <robab@marge.cs.mcgill.ca> murmurs:
> 
>     robab> i'm trying to write the *compose* function which is really
>     robab> easy to do in scheme, in c.
> 
> It's easy to write 'compose' in Scheme because Scheme allows you to
> pass around closures (a procedure body attached to an environment). To
> do this in C you need your own closure structure:
> 
> struct closure {
>   int (*f)(int), (*g)(int);     /* the environment */
>   int (*func)(int);             /* the procedure body */
> }
> 
> int compose_lambda(int val, int (*f)(int), int (*g)(int))
> {
>   return f(g(val));
> }
> 
> struct closure compose(int (*f)(int), int (*g)(int))
> {
>   struct closure out;
> 
>   out.f = f;
>   out.g = g;
>   out.func = compose_lambda;
> 
>   return out;
> }
> 
> A closure c is invoked like:
> 
>   return = c.func(val, c.f, c.g);
> 
> Of course, for this to be useful, all procedures must be closures, and
> you probably need a general environment mechanism. As the saying goes,
> if you want Scheme you know where to find it :).

There's a fairly simple translation from Scheme to C that utilizes
continuation-passing style.  It does bounded-storage tail recursion,
trivial continuation capture and precise garbage collection.  It is
described at the following URL:

ftp://ftp.netcom.com/pub/hb/hbaker/CheneyMTA.html

The Boyer Benchmark in C using these ideas is at:

ftp://ftp.netcom.com/pub/hb/hbaker/cboyer13.c
