Partial application in C

Leo de Wit leo at philmds.UUCP
Sat Jun 18 16:45:34 AEST 1988


In article <22944 at oliveb.olivetti.com> chase at orc.olivetti.com () writes:
>(and now for something completely different)
>As a bit of an experiment based on a comment by Richard Stallman, I
>decided to implement partial application for C on a Sun, and I did it
>and it worked.  Perhaps you will find this interesting--comments are
>welcome.
>----------------
>The subroutine "make_p_app" takes a function and an "argument" (in
>this case, an int; I am well aware of the non-portability of this).
>The value returned is a pointer-to-function (actually some
>heap-allocated memory) which when called will prepend "argument" to
>the argument list in that call.  For example, you could use this to

If I understand it correctly the pointer points to a memory location
that you fill and jump to in run-time? Then you can expect some
problems: there are machines that don't allow you to execute data as
code (in fact that's safer I think; what will happen if some pointer
goes berzerk and modifies your precious code? The least error is an
illegal instruction or invalid opcode, but worse things could happen).
It also has a smell of self-modifying code about it (but maybe you like
that smell 8-). If you remember the discussion about executing data we
have had recently - don't remember the exact title - you would also be
aware of the fact that something like

static short code[] = {
    0x....,0x....
    ....
};

    /* ===== */

    (*(void (*)())code)(x,y,z);

is not portable, not (only) for the 'code' but also for the construct.
(But I used it myself on a MC68000 micro for a program that test how
many ticks it takes to execute a series of shorts!).  But let's
continue:

>the argument list in that call.  For example, you could use this to
>get a printf-like function to a file
>
>  gprintf = make_p_app(fd,stderr)
>
>or a function that always returns a new pointer to an integer
>
>  new_int = make_p_app(malloc,sizeof(int))
>
>These examples are only so-so---one could easily argue that these
>could just as easily be written as separate subroutines or subroutines
>that use static data (non-reentrant! boo! hiss!).  However, I think
>that situations will arise where this is more convenient or flexible.
   [Sun implementation of code left out]...

The only merit I see for such a scheme is for performance reasons;
however if you're talking performance your garbage collector should be
in hardware.  If performance is less crucial, you could do something
like:

typedef struct {
    void (*pa_func)();
    int  pa_parm;
} partapp;

    partapp new_int;

    new_int.pa_func = malloc; new_int.pa_parm = sizeof(int);
    /* ... or let a 'make_p_app()' initiate it; and then ... */

    exec_p_app(new_int,other,parameters,follow,here,...);

The exec_p_app could be created inline if you have a clever compiler;
it does something analogous to the code you created, only getting the
stack right is done on run-run time instead of compile-run time, if you
can follow me 8-). If it is inline it is even faster, requiring only
the rearrangement of the stack and the call to malloc(); if you're
lucky and/or you swap the pa_func and pa_parm members you posssibly
won't have to rearrange at all. If it is not it will probably be about
as fast as the code you proposed.  I can figure that out if you're
interested. If you are, could you mail me a copy of the relevant part
of the code (your example is a bit terse)?

>Stallman thinks that similar code could also be written for a VAX,
>though the chunk of code must include a mask copied from the partially
>applied function and jump to the instruction after the mask.  Anyone
>care to do this for other machines and post their results? (send to me
>and I'll summarize)
>----------------

Note that the solution is not only machine but also
compiler-dependent.  It depends for instance on the calling convention
used (forward/reverse order of arguments on stack, size of elements on
stack, stack frame etc).  But generally speaking implementing such a
solution would be a piece of cake; I'll bake you one 8-).

>Reclaiming the memory is not a problem for me because I've got a
>garbage collector (if you don't believe in garbage collection, then
>you will have to invent your own solution;  I'm pretty happy with
>garbage collection because it lets me worry about more interesting
>problems.  If there is substantial interest I can post the collector;
>it is in the public domain, but the public doesn't know it.).
>
>David Chase
>Olivetti Research Center, Menlo Park

I love garbage collection; why else would I read netnews 8-) ?
And I'm interested in the g.c.

	Leo.



More information about the Comp.lang.c mailing list