home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.functional
- Path: 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
-
- 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!
-