[comp.lang.fortran] <None>

tp@mccall.com (07/27/90)

In article <58237@lanl.gov>, jlg@lanl.gov (Jim Giles) writes:
> From article <2009@key.COM>, by sjc@key.COM (Steve Correll):
>> [...]
>> 	X .GT. Y .OR. L(Z)
>> 
>> where L is a logical function which defines its dummy argument. The standard
>> says that if X is greater than Y, then Z becomes undefined. Not very user-
>> friendly, but Fortran programmers have traditionally been tough as nails.
> 
> Since this started as a comparison to C, let's remember that C is just
> as bad here.  You can't predict a-priori whether the function L() will
> be executed in either language.  In pretty much any language, it's a
> bad idea to have functions with side-effects in a context like this.

Not true. In the expression "x > y || l(z)", l will only be called if x is
not greater than y. The definition of the || (or) and && (and) operators
explicitly state that evaluation is left to right, and the right hand side
will only be evaluated if necessary to determine the value of the
expression. For example, in C one can safely say 

   if( a >= 0 && x[a] == 0)...

i.e. check the range of a subscript and use it if it is valid, in the same
conditional. The corresponding FORTRAN

   if(a.ge.1.and.x(a).eq.0)...

is NOT safe, because the subscript may be used before its validity is
checked, since FORTRAN does not specify the order of evaluation, nor
guarantee that all parts won't be evaluated. (Note that C arrays have a
lower bound of 0, whereas FORTRAN defaults to 1.) I'm not advocating
functions with side-effects being used this way (it tends to hide the
function call and make the program harder to understand), but it does work
reliably in C. The above example is more signficant, because it is a more
common need. The equivalent fortran requires at least 2 statements to
perform the check. If the if is an if-then, it will also require a scratch
logical variable or a nested if-then, i.e.:

    if(a.ge.1)flag = x(a).eq.0
    if(flag)then
       ...
    endif

or

    if(a.ge.1)then
       if(x(a).eq.0)then
          ...
       endif
    endif

In this case the C code is much cleaner, since it does what the average
user would expect, whereas it is not obvious to the novice user why the
FORTRAN example won't work (this precise usage is a VERY common novice
programming error). 
-- 
Terry Poot <tp@mccall.com>                The McCall Pattern Company
(uucp: ...!rutgers!ksuvax1!mccall!tp)     615 McCall Road
(800)255-2762, in KS (913)776-4041        Manhattan, KS 66502, USA

jlg@lanl.gov (Jim Giles) (07/28/90)

From article <3250.26b00265@mccall.com>, by tp@mccall.com:
> In article <58237@lanl.gov>, jlg@lanl.gov (Jim Giles) writes:
>>> [...]
>>> 	X .GT. Y .OR. L(Z)
>> [...]
>> Since this started as a comparison to C, let's remember that C is just
>> as bad here.  You can't predict a-priori whether the function L() will
>> be executed in either language.  In pretty much any language, it's a
>> bad idea to have functions with side-effects in a context like this.
> 
> Not true. In the expression "x > y || l(z)", l will only be called if x is
> not greater than y. The definition of the || (or) and && (and) operators
> explicitly state that evaluation is left to right, and the right hand side
> will only be evaluated if necessary to determine the value of the
> expression.  [...]

Please _read_ people's postings before responding.  When I say "you
can't predict a-priori whether the function L() will be executed in
either language", that's what I mean.  If I could predict whether
"X>Y" or not _before_ (ie. "a-priori") I do the if-test, I wouldn't
bother to test it!

> [... lots of garbage about C's 'advantages' because it short-circuits
>  logical expressions ...]

There are two good reasons _not_ to short-circuit logical operators:

1) Mathematically, 'and' and 'or' ('/\' and '\/') are both commutative.
   They are also both associative.  It is important to preserve these
   properties in a procgamming language.  It allows maximum parallel
   evaluation of conditionals.  It allows the use of mathematical
   principles in program verification.

2) Short-circuiting is a _separate_ operation from logical 'and' or
   'or'.  Your programming language _should_ implement separate features
   in distinct ways.

The only argument _in_favor_ of having logical operators short-circuit
is that you think a terse notation is better than an explicitly written-
out notation.  Unfortunately, both C and Fortran allow logical operators
to short-circuit.  This just means that program verification is slightly
harder and code doesn't parallelize well (actually, Fortran _allows_
you not to short-circuit, but it's not portable that way).

J. Giles

siegel@stsci.EDU (Howard Siegel) (08/02/90)

In <3250.26b00265@mccall.com>, tp@mccall.com writes:
>i.e. check the range of a subscript and use it if it is valid, in the same
>conditional. The corresponding FORTRAN
>
>   if(a.ge.1.and.x(a).eq.0)...
>
>is NOT safe, because the subscript may be used before its validity is
>checked, since FORTRAN does not specify the order of evaluation, nor
>guarantee that all parts won't be evaluated.
> [...stuff deleted...]
>In this case the C code is much cleaner, since it does what the average
>user would expect, whereas it is not obvious to the novice user why the
>FORTRAN example won't work (this precise usage is a VERY common novice
>programming error). 

Oh So True!  It's not just a novice error in that an experienced FORTRAN
coder (!) may not be familiar enough with the formal definition of the
language.

We had a case like this that had been working correctly for over a year
before the sh*t hit the fan.  Since VMS 4.something days the FORTRAN
compiler had been observing left to right evaluation order and things
worked.  Things stopped working (actually all hell broke loose, we
started getting access violations) at about VMS V5.2.  Looking into
the machine code the compiler produced showed that the right side
of the expression was being evaluated first, before the left side
check for the proper conditions.

We know better now!

    ==-->> Standard disclaimers applied.  Your mileage will vary! <<--==

    Howard Siegel    (301) 338-4418
    TRW   c/o Space Telescope Science Institute   Baltimore, MD 21218
    Internet:  siegel@stsci.edu          SPAN:  STOSC::SIEGEL
    uucp:  {arizona,decvax,hao}!noao!stsci!siegel