🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.functional
Article #936

Re: Completely functional program in C

#936
From: Fergus James HENDERSON
Date: Fri, 25 Dec 1992 18:02
110 lines
3280 bytes
goodrich@lynx.larc.nasa.gov (Mike Goodrich) writes:

>Greetings,
>	The following is an example of a functional program in C I wrote after
>reading MaClannan's book on FP. I would like to invite comments from the FP
>community.

I would not describe this program as particularly "functional".
It does have a lot of tail recursion, but there is not much else that
could be called functional.

[...]
>main(argc, argv)
>	int             argc;
>	char          **argv;
>{
>	unsigned char   buff[REC_SIZE];
>
>	if (argc < 2) {
>		printf("\nUsage: hexdmp <filename>\n");
>		exit(0);
>	}
>	DumpFile(fopen(argv[1], "rb"), buff);
>}

- exit(0) is not very functional
- failing to return a value from main() is not very functional
  (not to mention that it's not very good C either ;-)
- passing uninitialized parameters (buff) is not very functional

>void
>PutTextLine(NumRead, buff)
>	short           NumRead;
>	unsigned char  *buff;
>{
>	switch (NumRead) {
>	case 0:
>		return;
>	default:
>		if (*buff < ' ' || *buff > '~') {	/* printable ? */
>			printf(".");
>		} else {
>			printf("%c", *buff);
>		}
>		PutTextLine(NumRead - 1, buff + 1);
>	}
>}

Why the switch statements? What's wrong with using if statements?

Also, purely functional programs should have declarative I/O.
Since this is impossible, the next best thing is to confine all your
I/O to the very top-level of your program, or alternately to pass
pretend state-of-the-world arguments to and from a library of declarative
I/O functions (OK, admittedly that's a bit silly in this context, but
then it's a pretty silly context ;-)

>
>void
>PutHexLine(NumRead, buff)
>	short           NumRead;
>	unsigned char  *buff;
>{
>	switch (NumRead) {
>	case 0:
>		printf("\t");
>		return;
>	default:
>		printf("%02x ", *buff);
>		PutHexLine(NumRead - 1, buff + 1);
>	}
>}
>
>void
>DoLine(NumRead, buff, count, fp)
>	short           NumRead, count;
>	unsigned char  *buff;
>	FILE           *fp;
>{
>	switch (NumRead) {
>	case 0:
>		return;
>	default:
>		printf("\n<%d>\t", count * REC_SIZE);
>		PutHexLine(NumRead, buff);
>		PutTextLine(NumRead, buff);
>		DoLine(fread(buff, 1, REC_SIZE, fp), buff, count + 1, fp);
>	}
>}
>
>void 
>DumpFile(fp, buff)
>	FILE *fp;
>	unsigned char  *buff;
>{
>	if (fp == NULL) {
>		printf("Error: cannot open input file\n");
>		exit(-1);
>	}
>	DoLine(fread(buff, 1, REC_SIZE, fp), buff, 0, fp);
>}

fread() is not a very functional function, since the buff array is 
effectively passed by reference rather than by value.

-- 
Fergus Henderson             fjh@munta.cs.mu.OZ.AU      
This .signature virus is a self-referential statement that is true - but 
you will only be able to consistently believe it if you copy it to your own
.signature file!
Technical Details
Message-ID: <9236105.4381@mulga.cs.mu.OZ.AU>
Path: arc1-ca.pugleaf.net!sparky!uunet!munnari.oz.au!cs.mu.OZ.AU!munta.cs.mu.OZ.AU!fjh
References: <1hakebINNdsa@rave.larc.nasa.gov>

Show Full Headers
Complete Article Headers
Newsgroups: comp.lang.functional
Path: arc1-ca.pugleaf.net!sparky!uunet!munnari.oz.au!cs.mu.OZ.AU!munta.cs.mu.OZ.AU!fjh
From: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Subject: Re: Completely functional program in C
Message-ID: <9236105.4381@mulga.cs.mu.OZ.AU>
Sender: news@cs.mu.OZ.AU
Organization: Computer Science, University of Melbourne, Australia
References: <1hakebINNdsa@rave.larc.nasa.gov>
Date: Fri, 25 Dec 1992 18:02:01 GMT
Lines: 110