Path: utzoo!attcan!uunet!seismo!sundc!pitstop!sun!quintus!ok From: ok@quintus.uucp (Richard A. O'Keefe) Newsgroups: comp.lang.fortran Subject: Re: Fortran versus C for numerical analysis Message-ID: <414@quintus.UUCP> Date: 16 Sep 88 10:02:33 GMT References: <893@amelia.nas.nasa.gov> <3064@lanl.gov> <820@cernvax.UUCP> <406@quintus.UUCP> <3974@h.cc.purdue.edu> Sender: news@quintus.UUCP Reply-To: ok@quintus.UUCP (Richard A. O'Keefe) Organization: Quintus Computer Systems, Inc. Lines: 86 In article <3974@h.cc.purdue.edu> ags@h.cc.purdue.edu.UUCP (Dave Seaman) writes: >In article <406@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: > [ explaining that a particular expression is not ambiguous in C ] >What are you afraid of? What problem does it cause if the compiler decides >to respect the extra parentheses that you put in for no reason? After all, >even in C under the K&R standard, there is no guarantee that the compiler >will NOT treat the expression differently because of the parentheses. Quite true. But if I stick extra parens into a C expression, whatever code the compiler comes up with, it was entitled to generate _anyway_. Because C has a lot more operator precedence levels than Fortran, and because it is not immediately obvious that, say, *a[i] means *(a[i]) -- hence the utility of the tool called "cparen" -- and because of macros, C programmers tend to write a lot of parentheses "just to be safe". For example, a Fortran programmer might write a statement function MIDPT(X, Y) = (X + Y)/2 but a C programmer would write #define MIDPT(X,Y) (((X) + (Y))/2.0) -- the parens around X and Y are needed in case their principal operators bind more weakly than "+", e.g. MIDPT(a < b, a < c) -- the parens around the whole are needed in case it is used within the scope of an operator binding more tightly than "/". Note that a compiler was formerly licenced to optimise MIDPT(a+b,c+d)/4.0 just like (a+b+c+d)/8.0, but is now required to do {({a+b} + {c+d})/2.0}/4.0. It is a bit worrying to suddenly be told that the parentheses you were putting in just to play safe now carry semantic import, just because people who were used to Fortran didn't like the idea of having an explicit "don't do this any other way" mark. >If all you are interested in is emphasizing grouping for the benefit of the >human reader, you can do that quite effectively by the proper use of white >space. You don't need parentheses. In fact, white space works BETTER than >parentheses for this purpose. Compare: > > t = a*cos(x) + b*cos(y) + c*f(x-y) + d*f(x+y) >with > t=((a*cos(x))+(b*cos(y)))+((c*f(x-y))+(d*f(x+y))) > >-- which would you rather read? No, in fact what I'm concerned about is the human *writer*. Since I read code with the aid of a text editor, I would rather have the second form: I can be *sure* of the grouping. With the white-space version, I *still* have to read every character unaided, because the spacing might be wrong. Consider t = a-cos(x) / b-cos(y) / c-f(x-y) / d-f(x+y) [example of why "strong" parens are useful] It is conceded that *some* way of saying "do this *exactly* as I wrote it" is a Good Idea. The point is that that is a _different_ thing to say from "I am confused about the operator precedence and want to make sure", and the two deserve different notation. Fortran having historically (ab)used parentheses for the strong form, I wouldn't dream of suggesting that that should be changed. C having historically used parentheses for purely syntactic effect, I think it is at best bad manners to change _that_; a new notation should have been used. +(...) seemed ok to me. I seriously doubt that many Fortran programmers Out There understand enough about numerical analysis to work out where strong brackets are needed. It would be a big help in reading Fortran programs (especially when trying to convert them to another language) if one only knew which parentheses were present for numerical reasons and which were not. Comments would be enough. Here are a couple of examples from "Numerical Recipes": WT = 1./(SIG(I) ** 2) Why has this been written like that instead of as WT = SIG(I) ** (-2) is there something deep I am missing here, or was it just a matter of taste? SXOSS = SX/SS ... SIGA = SQRT((1. + SX*SX/(SS*ST2))/SS) Is it really important that this should be computed as (SX*SX)/(SS*ST2) or perhaps SX/(SS*ST2)*SX rather than (SX/ST2)*SXOSS, or was it just what the authors thought clearest? {In context, I'd be more worried about overflow/underflow than about roundoff, so I'd have thought (SX/ST2)*SXOSS would be preferred on numeric grounds.} I hope these examples make my point clear: I do not regard *either* the Fortran or the pre-ANSI C positions on parentheses as satisfactory. There are *two* constructs, and both languages should have *both*. It is precisely because I _agree_ that control over evaluation is important that I want to know which parentheses are which!