Article View: comp.lang.functional
Article #936Re: Completely functional program in C
From: Fergus James HENDERSON
Date: Fri, 25 Dec 1992 18:02
Date: Fri, 25 Dec 1992 18:02
110 lines
3280 bytes
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!fjhReferences:
<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