Functional programming in C :-)

Mike Tilson mike at hcradm.UUCP
Thu Aug 15 12:23:55 AEST 1985


Recently there has been a lot of talk about side-effects and expressions
in C.  Several people have commented that a full expression language
is a good thing.  Others have compared C to LISP and APL.  The following
program shows what you can really do with C if you try. :-)  Note that
everything is done as expression evaluation, and there are enough
parentheses to satisfy the LISP lover. :-)  There are 38 lines of
actual executable code, in the form of *one* C expression which computes
a sequence of prime numbers.

(Note: an earlier version of this was submitted to the Obfuscated C
contest.  I was going to let it die, but it seemed very apropos to
the recent C discussion.)

/ Michael Tilson
/ {utzoo,decvax}!hcr!hcradm!mike

=============== cut here =================
/*
 * Functional programming in C.  :-)
 *
 * Compute prime numbers using a version of the famous benchmark.
 * The primes are computed multiple times, with the numbers being
 * printed.  Finally, the count of primes is printed and returned
 * as the exit value of main.
 *
 * There are no semicolons in this program except for declarations
 * and the one return statement.  It is all done by expression
 * evaluation.  :-)
 *
 * This program has been tested on Vax UNIX System V.2.  It passes lint
 * with no messages, using the default options.  This usage of setjmp
 * conforms to the UNIX documentation, and is more powerful than
 * that supported by the draft ANSI C standard.
 *
 * Michael Tilson
 */

/* set up the control structure, and also fool lint into being happy */
#include <setjmp.h>
jmp_buf label0, label1, label2;
int (*jump)() = (int (*)()) longjmp;
void (*label)() = (void (*)()) setjmp;
extern int printf();
void (*print)() = (void (*)()) printf;

#define TRUE	1
#define FALSE	0
#define SIZE	100
#define N	5
char flags[SIZE + 1];

main() {
int i, prime, k, count, iter;

return(
(*print)("%d iterations\n", N),
iter=1,
(((*label)(label0),iter<=N)
?(
	count = 0,
	i = 0,
	(((*label)(label1),i<=SIZE)
	?	flags[i]=TRUE,
		i++,
		(*jump)(label1,0)
	:empty()),
	i = 0,
	(((*label)(label1),i<=SIZE)
	?(
	        (flags[i]
		?(
			prime = i+i+3,
			(*print)("\n%d",prime),
			k = i + prime,
			(((*label)(label2),k<=SIZE)
			?(
				flags[k]=FALSE,
				k += prime,
				(*jump)(label2,0)
			)
			:empty()),
			count++
		):empty()),
		i++,
		(*jump)(label1,0)
	):empty()),
	iter++,
	(*jump)(label0,0)
):empty()),
(*print)("\n%d primes.\n", count),
count
);
}

empty() {
}



More information about the Comp.lang.c mailing list