[comp.lang.fortran] Fortran vs C for computations

t68@nikhefh.hep.nl (Jos Vermaseren) (09/05/88)

There is another much more annoying feature of C that restricts its floating
point handling to the 'playing only' level.
In the second edition of Kernighan and Ritchie it is explained that the
standard response of a floating point operation (multiplication, sqrt etc)
to an irregularity is returning special values.

So
	float x = -2.0;
	z = sqrt(x);

gives back some value. Amazingly enough many UNIX vendors like this philosophy,
so even the UNIX fortran compilers often prefer it this way.
If I have to put all kinds of ifs around each floating point operation I'll
never do computations in C.
The better thing would be to have a parameter that can be set by the user
that determines whether an overflow or sqrt of a negative number should be
fatal (with intelligent errormeassage please). Most fortran compilers have
this option.

J.Vermaseren
T68@nikhefh.hep.nl

davis@galaxy.ee.rochester.edu (Al Davis) (09/06/88)

J.Vermaseren says....
>        float x = -2.0;
>	        z = sqrt(x);
>		gives back some value.

>The better thing would be to have a parameter that can be set by the user
>that determines whether an overflow or sqrt of a negative number should be
>fatal (with intelligent errormeassage please). Most fortran compilers have
>this option.

I have never seen a fortran compiler that had this option.  They all abort
the program with a non-friendly message.  Any option that any fortran would
have would necessarily be non-portable.

C has a function "matherr" that defines how these errors are handled.  When
an error occurs, it calls matherr.  The vendor supplies a default handler,
that returns a value, and sets the global variable "errno", etc.  If you
don't like it, replace it with your own.  You have full control.  It is
portable, standard, and well documented.

On another subject, I suspect our postnews doesn't work correctly.  Will
someone far away please send me mail if you read this?

al davis.
davis@ee.rochester.edu

u-dmfloy%sunset.utah.edu@utah-cs.UUCP (Daniel M Floyd) (09/06/88)

In article <535@nikhefh.hep.nl> t68@nikhefh.hep.nl (Jos Vermaseren) writes:
...
>There is another much more annoying feature of C ...

C is not the only culprit. I'm sure you knew this.
>...
>The better thing would be to have a parameter that can be set by the user
>that determines whether an overflow or sqrt of a negative number should be
>fatal (with intelligent errormeassage please). Most fortran compilers have
>this option.

Here. Here. I'd like *all* compilers to allow the programmer (user) to
specify what to do with abnormal situations. Sometimes, I want
the application to have a fatal type. Other times, I simply cannot
halt the program under *any* condition. I'd like it to take the form of
defaulting to something reasonable but allowing something like

/* compiler option: sqrt(x)
/*	if -x do_this_routine
/*	if overflow fatal_error
/*	if underflow return_0 and flag error
...

Different compilers, different languges, different tastes, could
result in different syntax. The point you made, which I'm emphasizing
is that users want to have control over error conditions. I hope
the next generations of compilers will take this seriously.

ok@quintus.uucp (Richard A. O'Keefe) (09/06/88)

In article <535@nikhefh.hep.nl> t68@nikhefh.hep.nl (Jos Vermaseren) writes:
>
>In the second edition of Kernighan and Ritchie it is explained that the
>standard response of a floating point operation (multiplication, sqrt etc)
>to an irregularity is returning special values.
>
>So
>	float x = -2.0;
>	z = sqrt(x);
>
>gives back some value. Amazingly enough many UNIX vendors like this philosophy,
>so even the UNIX fortran compilers often prefer it this way.

(1) See "matherr" in the System V documentation.  If you define a function
    int matherr(struct exception *x) it will be called when math library
    functions detect a problem.

(2) Returning funny values is exactly what IEEE floating point arithmetic
    is all about.  Note that the IEEE 754 standard requires AS THE DEFAULT
    that x+z and the like should return infinities or NaNs in various
    circumstances, rather than signalling an exception, and that IEEE 754
    provides no standard way of enabling exceptions (though it suggests
    that there should be one).

jlg@lanl.gov (Jim Giles) (09/07/88)

From article <1443@valhalla.ee.rochester.edu>, by davis@galaxy.ee.rochester.edu (Al Davis):
> 
> I have never seen a fortran compiler that had this option.  They all abort
> the program with a non-friendly message.  Any option that any fortran would
> have would necessarily be non-portable.
> [... other stuff about how C is better ...]

Anything C can do portably with library routines, Fortran can also do
portably with library routines.  Just because you haven't seen a Fortran
compiler that does X, doesn't mean X can't be done with Fortran.

The same goes for macros.  Anything C can do with macros, Fortran can
do with macros.  The only difference is that C makes macros part of the
language definition instead of part of the text editing environment
(where it belongs).

J. Giles
Los Alamos

ok@quintus.UUCP (Richard A. O'Keefe) (09/07/88)

In article <3256@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>From article <1443@valhalla.ee.rochester.edu>, by davis@galaxy.ee.rochester.edu (Al Davis):
[[ in response to a statement that Fortran is better than C for numerical
   work because sqrt() can be trapped in Fortran but not in C,
   that it *can* be done in C, with matherr().
]]
>Anything C can do portably with library routines, Fortran can also do
>portably with library routines.

I would like to see a more convincing proof of this.

>Just because you haven't seen a Fortran
>compiler that does X, doesn't mean X can't be done with Fortran.

But the topic was not what *could* be done, but what *HAS* been done.
There are numerous Fortran processors which provide means of trapping
or ignoring floating-point exceptions.  Trouble is, they don't do it
the same way.
[I checked the IBM SAA FORTRAN Reference manual, but evidently MVS Fortran
and OS/2 Fortran do not have a common form of numeric exception handling.]


- (pre-ANSI) C has matherr() and signal(SIGFPE, ...), though the draft
  ANSI standard doesn't contain matherr().
- ADA [LRM 11.1, 4.5.7] doesn't require that an implementation detect
  or signal numeric errors, but it _does_ provide a standardised way of
  catching them if they are detected and signalled.
- COBOL has had the "ON OVERFLOW user-action" clause for catching
  fixed-point overflow for decades.
- PL/I has the ([NO]{OVERFLOW,UNDERFLOW,...}): condition prefixes and
  the ON {OVERFLOW,UNDERFLOW,...} statement.

How come _the_ language for floating-point calculations doesn't have
a portable way of catching or suppressing floating-point exceptions?

Bitwise operations and a WHILE loops are covered in a supplementary
MIL-STD for Fortran; is there also some supplementary standard which
supplements Fortran with this facility?

roy@phri.UUCP (Roy Smith) (09/07/88)

In article <3256@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
> C makes macros part of the language definition instead of part of the
> text editing environment (where it belongs).

	Not in my book.  I've got available to me both C's #define macros
and emacs macros (word abrev mode, and more complex stuff).  I suppose I
could make emacs expand "c = getc (fp);" into

c = (--(fp)->_cnt>=0? (int)(*(unsigned char*)(fp)->_ptr++):_filbuf(fp));

if I wanted to, but why would I want to?

	Hey, I agree, there are a lot of things you can do in Fortran just
as well as in C, if not better (complex arithmetic, for example), but if
you're going to knock C, at least pick on one of its real faults.  It has
enough of them; no need to invent more.
-- 
Roy Smith, System Administrator
Public Health Research Institute
{allegra,philabs,cmcl2,rutgers}!phri!roy -or- phri!roy@uunet.uu.net
"The connector is the network"

fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (09/07/88)

In article <3256@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>
>The same goes for macros.  Anything C can do with macros, Fortran can
>do with macros.  The only difference is that C makes macros part of the
>language definition instead of part of the text editing environment
>(where it belongs).
>

I couldn't pass up making a comment here.  It has been my experience
that using a preprocessor for Fortran macro expansion is a certain way
of ensuring nonportable code, since there is no standard preprocessor
for Fortran and all implementations are different.  Unless you are
willing to pull an ADA and require a standard programming environment
like the APSE to go with your language, every feature you want for
portability must be specified as part of the language standard, making
preprocessors/macros a required part of the language definition.

As to macros belonging in the language or the text editing
environment, I work in an environment where I have macros in both and
find I use them differently.  I strongly agree with the comment that
macros are usually used to overcome deficiencies in the language.  As
to preprocessors/include files, I have come to strongly depend on
them.  They are one of the least standard and most frustrating (to me)
lacking features in Fortran.  I, for one, like the ability to put all
of the common parameter statements and common block definitions into a
single file and use include directives to make sure that all of my
source files get the same version of the common block/parameters.

I am also a large fan of using #define and #ifdef in C for conditional
compilation.  When not overused, this is a major win for smoothing
over portability problems and I've missed it many times in trying to
make portable programs in Fortran.

I also use C macros as a way of achieving inline code expansion, sort
of as an efficency hack, but frequently as a way to make unrolled code
more readable.  This is a personal preference issue, and mine is for
readable code at the expense of using the preprocessor to obtain it.

Marty


+-+-+-+     I don't know who I am, why should you?     +-+-+-+
   |        fouts@lemming.nas.nasa.gov                    |
   |        ...!ames!orville!fouts                        |
   |        Never attribute to malice what can be         |
+-+-+-+     explained by incompetence.                 +-+-+-+

jlg@lanl.gov (Jim Giles) (09/08/88)

From article <3462@phri.UUCP>, by roy@phri.UUCP (Roy Smith):
> 
> 	Hey, I agree, there are a lot of things you can do in Fortran just
> as well as in C, if not better (complex arithmetic, for example), but if
> you're going to knock C, at least pick on one of its real faults.  It has
> enough of them; no need to invent more.

But my point was that C's macro facility doesn't add any _functionality_
to the language.  It is just a build-in text substitution mechanism.  I
have used macros in Fortran code for years.  I claim that anything that
can be done with C macros can also be done in Fortran - _with_macros_.
I didn't identify this as a fault of C - just that the C supporters
often (incorrectly) identify this as a fault in Fortran.

J. Giles
Los Alamos

jlg@lanl.gov (Jim Giles) (09/08/88)

From article <962@amelia.nas.nasa.gov>, by fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts):
> 
> I couldn't pass up making a comment here.  It has been my experience
> that using a preprocessor for Fortran macro expansion is a certain way
> of ensuring nonportable code, since there is no standard preprocessor
> [...]

Write the preprocessor in Fortran.  It is now as portable as the Fortran
environment is.  Besides, my macro expander _never_ produces non-standard
code - it only accepts it.  Output from my macro expander will compile on
any standard conforming Fortran environment.  Finally, my main point was
that C macros don't add functionality - only textual convenience.  My 
Fortran macros do the same.  C does not excel Fortran in this respect.

> I am also a large fan of using #define and #ifdef in C for conditional
> compilation.  When not overused, this is a major win for smoothing
> over portability problems and I've missed it many times in trying to
> make portable programs in Fortran.

#ifdef is an admission that your compiler isn't any good.  If the
conditional expression is a constant, a normal if statement should 
be optimized so that code is only generated for the active branch.  If
the conditional expression is not a constant, it couldn't be used as
part of an #ifdef either.  #define is either a _parameter_, an inline
function, or an inline procedure - the first is already in Fortran,
the others are in the proposed 8x extensions.  Besides, as I've already
pointed out, the functionality of #define can already be provided in a
Fortran environment - portably (in fact, the RATFOR preprocessor has its
source given in the original software tools document and includes a
macro facility nearly identical to C macros - including ifdefs).

J. Giles
Los Alamos

Note: RATFOR isn't the best macro facility for Fortran. But it is an
example of a completely portable public domain preprocessor for which
the source is readily available to any interested programmer.

jlg@lanl.gov (Jim Giles) (09/08/88)

From article <362@quintus.UUCP>, by ok@quintus.UUCP (Richard A. O'Keefe):
> In article <3256@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>>From article <1443@valhalla.ee.rochester.edu>, by davis@galaxy.ee.rochester.edu (Al Davis):
> [[ in response to a statement that Fortran is better than C for numerical
>    work because sqrt() can be trapped in Fortran but not in C,
>    that it *can* be done in C, with matherr().
> ]]
>>Anything C can do portably with library routines, Fortran can also do
>>portably with library routines.
> 
> I would like to see a more convincing proof of this.

Ok.  Take the C library.  Write bridge routines through which Fortran
programs can call all the procedures in the C library.  Fortran now has
a library with the same functionality as the C library.  QED  

Obviously - Anything C can do portably with library routines, Fortran
can also do portably with library routines.  This is because Fortran
and C can both use the _SAME_ library on any given machine.

> [... lots of stuff about exception handling ...]
> How come _the_ language for floating-point calculations doesn't have
> a portable way of catching or suppressing floating-point exceptions?

Because no two machines have the same exception handling capabilities!
In this respect, C, ADA, etc., are not _any_ more portable than Fortran.
In fact they are less so since they _require_ particular functionality
which the machine may not possess.  Some machines, for example, don't
have any trap available for underflow.  Some systems or hardware (both
outside the domain of language definition) put constraints on exception
handling.  Fortran doesn't include these because there is no portable
way to implement them.  (The people who ported UNIX to the Crays found
a number of unexpected problems of this sort.  Some of the assumptions
made in the C libraries were _not_ portable.)

Note that exception handling was contained in early drafts of the 
Fortran 8x proposal and failed for many of the same reasons I just
stated.

J. Giles
Los Alamos

fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (09/08/88)

In article <3290@lanl.gov> jlg@lanl.gov (Jim Giles) writes:

>Write the preprocessor in Fortran.  It is now as portable as the Fortran
>environment is.

But I don't want to write the preprocessor, I want to use the one that
comes standard with the language (;-)

>#ifdef is an admission that your compiler isn't any good.  If the
>conditional expression is a constant, a normal if statement should 
>be optimized so that code is only generated for the active branch.  If
>the conditional expression is not a constant, it couldn't be used as
>part of an #ifdef either.  #define is either a _parameter_, an inline
>function, or an inline procedure - the first is already in Fortran,
>the others are in the proposed 8x extensions.  Besides, as I've already
>pointed out, the functionality of #define can already be provided in a
>Fortran environment - portably (in fact, the RATFOR preprocessor has its
>source given in the original software tools document and includes a
>macro facility nearly identical to C macros - including ifdefs).
>

The point I was trying to make has to do with working around
differences in multiple environments.  Although for a single compiler
the ifdefs will produce  constants which can be compilerd out, the
constant will be different in different environments.  Consider this
bit of C code:

#ifdef CRAY2			/* Not all code is portable */

  {
    long t_addr;
    bcopy(from->h_addr, (caddr_t)&t_addr, from->h_length);
    to->sin_addr = (u_int) t_addr;
  }

#else

  bcopy(from->h_addr, (caddr_t) &to->sin_addr, from->h_length);

#endif CRAY2
 
CRI decided to implement a particular field in a particular structure
differently than the rest of the world.  On a Cray 2, the second
clause will not compile correctly, *not* because the compiler is
broken, but because something else is difficult to deal with.

Using the standard preprocess cpp, I have a predefine for each
compiler/OS environment, so I don't have to change my makefiles or
programs to get the correct code on a given machine.

There are a lot of examples of differences in libraries, operating
systems, etc, in which code like the above is useful.  This can be
overdone and make the code unreadable, but it can also be a major time
saver.

>Note: RATFOR isn't the best macro facility for Fortran. But it is an
>example of a completely portable public domain preprocessor for which
>the source is readily available to any interested programmer.

RATFOR is not completely portable.  It still doesn't run on the ETA-10
here, but people are working on it.  It has been a nontrivial exercise
to make it work on that machine, not do to anything wrong with the
ETA-10.

BTW, it is amusing that RATFOR was written as a workaround to
primitive Fortran control structures in an earlier Fortran, and it is
still around even with a cleaned up Fortran available. (;-)
+-+-+-+     I don't know who I am, why should you?     +-+-+-+
   |        fouts@lemming.nas.nasa.gov                    |
   |        ...!ames!orville!fouts                        |
   |        Never attribute to malice what can be         |
+-+-+-+     explained by incompetence.                 +-+-+-+

platt@emory.uucp (Dan Platt) (09/08/88)

>#ifdef is an admission that your compiler isn't any good.  If the
>conditional expression is a constant, a normal if statement should 
>be optimized so that code is only generated for the active branch.  If
>the conditional expression is not a constant, it couldn't be used as
>part of an #ifdef either. 


I object to this argument.  There are some functions provided in certain
environments that are not provided in other environments (specifically,
functions that deal with dates, times, extended function sets such as error
functions or Bessel functions) or which exist but have different forms on
each system.  The biggest problem concerns 'open' statements which seem
to be very system specific; I don't believe that an IF with a constant
expression would let that by, even if the final code generation included the
non-compatible code.  A pre-processed #ifdef would clean up that problem.
It would also provide a clean, convenient way to document the portability 
constraints of the program.  For example, in the PC world, some routines
may be more efficiently compiled if there is no Color card than if there is
(problems with raster syncs).  The easiest way to code this is to include
a function definition in C without the color card, and to use an assembler
routine version if the color card is there.  The inclusion in the module
would depend on the presence of the card.  (An even more sophisticated version
would check the flag at each entry, or load the correct overlay for the
routine at run-time).  One of the biggest problems I've been confronted with
lately is the portability problems of Fortran.  I find C much more portable,
and the new ANSI standards seem to be encouraging portability even more.
I haven't had the opportunity to use 8X (will soon though), so I cannot comment
on the features provided there.

Dan

ok@quintus.uucp (Richard A. O'Keefe) (09/08/88)

In article <3290@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>#ifdef is an admission that your compiler isn't any good.  If the
>conditional expression is a constant, a normal if statement should 
>be optimized so that code is only generated for the active branch.  If
>the conditional expression is not a constant, it couldn't be used as
>part of an #ifdef either.

Spot the hidden assumption?  Right: #ifdef is used more often to select
which header files to #include, which of several sets of declarations
to use, and so on.

For example, how would optimisation of IF statements help someone
who wants the functional equivalent of
	#if	REAL_IS_ENOUGH
		REAL FRED, THOM		
	#else
		DOUBLE PRECISION FRED, THOM
	#endif
(Yes, I know about Fortran 8x parametrised types.  That's not the question.)

ok@quintus.uucp (Richard A. O'Keefe) (09/08/88)

In article <3292@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>From article <362@quintus.UUCP>, by ok@quintus.UUCP (Richard A. O'Keefe):
>> In article <3256@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>>>Anything C can do portably with library routines, Fortran can also do
>>>portably with library routines.
>> 
>> I would like to see a more convincing proof of this.
>
>Ok.  Take the C library.  Write bridge routines through which Fortran
>programs can call all the procedures in the C library.  Fortran now has
>a library with the same functionality as the C library.  QED  
>
>Obviously - Anything C can do portably with library routines, Fortran
>can also do portably with library routines.  This is because Fortran
>and C can both use the _SAME_ library on any given machine.
>

Sorry, this proof won't go through.  It is only the case that Fortran
and C can use the same library if they use sufficiently compatible
calling sequences and memory management strategies.  There are quite a
few other potential problems.  For example, suppose the C library routines
require that the program execute a C initialisation routine ("crt0.o")
and Fortran requires a Fortran initialisation which is incompatible with
the C one?  This is not a theoretical case!  There are far too many UNIX
systems where mixing Fortran and C code *sometimes* works provided e.g.
that you don't do any Fortran I/O if the main program is C.

As an example of another kind of difficulty, consider the System V
"ftw" function:
	int ftw(char *path,
		int (*fn)(char *, struct stat *, int),
		int depth)
Because the function parameter can call ftw() itself, and because it
can call longjmp(), I believe that it is impossible to write a
bridging routine to permit Fortran to call this, unless you modify
the C library.

>> How come _the_ language for floating-point calculations doesn't have
>> a portable way of catching or suppressing floating-point exceptions?
>
>Because no two machines have the same exception handling capabilities!
>Fortran doesn't include [them] because there is no portable
>way to implement them.

If a machine doesn't provide a way of detecting and reporting floating-
point exceptions (that is, if it insists on its right to produce
incorrect answers without notice) why should I *care* about having
Fortran on it?  Or were the numerical analysts who contributed to the
development of the IEEE 754 standard wrong in thinking this was important?

jlg@lanl.gov (Jim Giles) (09/09/88)

From article <3169@emory.uucp>, by platt@emory.uucp (Dan Platt):
> I object to this argument.  There are some functions provided in certain
> environments that are not provided in other environments (specifically,
> functions that deal with dates, times, extended function sets such as error
> functions or Bessel functions) or which exist but have different forms on
> each system. [...

So what?  Functions called by dead code aren't really called after all.
What difference does it make if the _if_ statement or the _ifdef_ directive
is the visable syntax?  The _ifdef_ was only introduced because many 
compilers are _very_ bad at dead code elimination.

> ...]         The biggest problem concerns 'open' statements which seem
> to be very system specific; I don't believe that an IF with a constant
> expression would let that by, even if the final code generation included the
> non-compatible code. [...]

_OPEN_ statements which are 'system specific' are non-standard and don't
enter into this discussion.  In any case, a compiler which complains of
syntax errors in an OPEN statement which appears in the middle of a dead
code sequence should be fixed.  Furthermore, there are ways to provide
I/O extensions to Fortran without muching up the OPEN statement (I am just
finishing an I/O support library for Fortran on the Crays, I provide a
large number of extensions - including all the features proposed in
8x - without altering the OPEN statement syntax in any compiler-checkable
way).  

> [...]                  A pre-processed #ifdef would clean up that problem.

Then use a preprocessed #ifdef with your fortran code if your vendor
has supplied you with a drain-damaged compiler.  This gets back to my
original point - C does _not_ have a monopoly on preprocessors!  I've
preprocessed Fortran codes for years and never had a portability
problem arise because of it (in fact, preprocessing helps eliminate
such problems - as you have pointed out yourself).

J. Giles
Los Alamos

jlg@lanl.gov (Jim Giles) (09/09/88)

From article <368@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> 
> Sorry, this proof won't go through.  It is only the case that Fortran
> and C can use the same library if they use sufficiently compatible
> calling sequences and memory management strategies.  There are quite a
> few other potential problems.  For example, suppose the C library routines
> require that the program execute a C initialisation routine ("crt0.o")
> and Fortran requires a Fortran initialisation which is incompatible with
> the C one?  This is not a theoretical case!  There are far too many UNIX
> systems where mixing Fortran and C code *sometimes* works provided e.g.
> that you don't do any Fortran I/O if the main program is C.

You are mixing the hypothetical with specific cases.  What you're telling
me is that a particular BAD implementation of the Fortran/C libraries proves
that C libraries can always do more and better things than Fortran libraries.
This is not the case.  The _functionality_ of C libraries can _always_ be
duplicated or exceeded by Fortran libraries and vice versa!  That is why
libraries exist!  The library implementors of you hypothetical system
didn't _HAVE_ to write incompatible libraries, the same functionality
could have been provided differently.

Consider system calls, for example.  Neither C nor Fortran has the
ability to make system calls on any machine that I know of (if you
have an example - it's not portable since neither standard speaks of
such things).  Yet the support libraries for both are capable of
doing things like getting the time, reading/writing disk, and allocating
memory.  All these things require system calls!  Usually, at some low
level, some of the library routines are written in assembly.  The point
is that these low-level routines could be shared by both the C and
Fortran libraries.

> As an example of another kind of difficulty, consider the System V
> "ftw" function:
> 	int ftw(char *path,
> 		int (*fn)(char *, struct stat *, int),
> 		int depth)
> Because the function parameter can call ftw() itself, and because it
> can call longjmp(), I believe that it is impossible to write a
> bridging routine to permit Fortran to call this, unless you modify
> the C library.

Why not just write a Fortran callable longjump() routine in assembly?
The rest of the bridge for Fortran is probably in assembly anyway.
On some machines, the _whole_library_ is written in assembly (Crays
for example).  Again, obviously anything the C library can do, so can
the Fortran library - anything that's hard to duplicate in the one 
high-level language can be done in the other or in assembly.  No user
even know what language the library is written in!

>>Because no two machines have the same exception handling capabilities!
>>Fortran doesn't include [them] because there is no portable
>>way to implement them.
> 
> If a machine doesn't provide a way of detecting and reporting floating-
> point exceptions (that is, if it insists on its right to produce
> incorrect answers without notice) why should I *care* about having
> Fortran on it?  Or were the numerical analysts who contributed to the
> development of the IEEE 754 standard wrong in thinking this was important?

Some machines/systems report floating-point (and all other) exceptions
simply by killing the program responsible with a message.  No language
definition or committee can force the designers of such machines/systems
to do otherwise.  Note again, C is _not_ more or less portable than
Fortran in this respect.  Neither language definition says _anything_
about exceptions, interrupts, signals, or any other action the system
may take when an error condition arises.  The C library (not standardized
yet - not until ANSI finishes its work) makes certain assumptions that
are _not_ portable (the C library assumes that all systems behave like
UNIX and that all hardware behaves like VAXen).  The Fortran standard
makes no such assumptions and is therefore more portable than the C
standard will be.  (Note: some of the assumptions made by the C library
are incompatible with other desireable features.  As far as I know,
there is a permanent possibility of deadlock in the Cray C library
because the way signals are processed in UNICOS (Cray UNIX) is incompatible
with multitasking functionality.)

Now, this is not the last word.  I am not in favor of putting exception
handling into the Fortran standard.  I _am_ in favor of having a 
supplimentary standard for exception handling.  This supplimentary 
standard could be proposed as a extra-linguistic standard which could
apply to all ANSI languages (it would have to be a library standard).
Machines/systems which allow user exception handling could provide
a library according to this supplimentary standard which both C and
Fortran could use.  Machines/systems which don't allow user exception
handling would not have such a library, but could still have standard
conforming Fortran and C compilers.  Much useful work can be done
on such machines even if they do always halt the program when an
exception occurs.

J. Giles
Los Alamos

jlg@lanl.gov (Jim Giles) (09/09/88)

From article <367@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> 
> Spot the hidden assumption?  Right: #ifdef is used more often to select
> which header files to #include, which of several sets of declarations
> to use, and so on.

Gee, you're right.  I've never thought of that.  I've never used #ifdefs
for that reason.  Of course, it would be a perfectly acceptable extension
to Fortran to allow ordinary IF statements in this sort of context (with
only constant conditional expressions of course).  Still, I've never
seen a compiler which would take that - score one for you! 

But then, back to my original point.  Use #ifdef with your Fortran code.
C does _not_ have a monopoly on preprocessors.

J. Giles
Los Alamos

joe@modcomp.UUCP (09/09/88)

J.Vermaseren of T68@nikhefh.hep.nl writes [slightly edited]:

>There is another much more annoying feature of C that restricts its floating
>point handling to the 'playing only' level. In the second edition of K&R it
>is explained that the standard response of a floating point operation
>to an irregularity is returning special values.

C under Unix, at least, lets the user specify that floating point exceptions
are to generate a signal.  This, of course, doesn't help fortran users, nor
users of C on non-unix operating systems.
--
Joe Korty              "flames, flames, go away
uunet!modcomp!joe      come back again, some other day"

fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (09/09/88)

In article <3342@lanl.gov> jlg@lanl.gov (Jim Giles) writes:

>
>But then, back to my original point.  Use #ifdef with your Fortran code.
>C does _not_ have a monopoly on preprocessors.
>

True.  C only has one (cpp.) Fortran has lots of them -- very nearly
one from each vendor.  RATFOR is nearly portable, but it doesn't run
on several machine I am forced to use.  Every machine I use has cpp.
It its going to be portable, it has to be in the language standard.

Marty


+-+-+-+     I don't know who I am, why should you?     +-+-+-+
   |        fouts@lemming.nas.nasa.gov                    |
   |        ...!ames!orville!fouts                        |
   |        Never attribute to malice what can be         |
+-+-+-+     explained by incompetence.                 +-+-+-+

ok@quintus.uucp (Richard A. O'Keefe) (09/09/88)

In article <3341@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>From article <368@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
>> Sorry, this proof won't go through.  [counterexamples]
>
>You are mixing the hypothetical with specific cases.

But it's precisely the specific EXISTING cases which determine
what is CURRENTLY portable or not.  If it is fair enough to cite
nasty machines to support a claim that languages should not have
floating-point exception handling as a standard part, then it is
fair enough for me to cite existing Fortran and C libraries to
support a claim that what C and Fortran can (*now*) do "portably"
"with the aid libraries" is not the same.

I think that ADA shows the way: the language has a standard means
of catching exceptions *IF* they are signalled and a standard means
of suppressing them *IF* they can be suppressed.

The present situation, where I have access to about a dozen different
kinds of machines (all of which support both Fortran and C), and all
of which are capable of detecting and reporting floating-point exceptions,
but there is no single thing I can put in a Fortran program to exploit
this common capability, is *not* acceptable.

We could have something like
	CALL HANDLE(exception, handler, oldhandler, ierror)
where ierror would be set to a suitable value if the implementation was
not able to catch that kind of error.  For example,
	CALL HANDLE('OVERFLOW', MYOVHD, OLDHD, IERROR)
	IF (IERROR .NE. 0) STOP 'CAN''T CATCH OVERFLOWS'

Good heavens, if we were to accept the "some machines don't want to do it"
argument, we wouldn't have floating-point arithmetic, and then where would
Fortran be?

jlg@lanl.gov (Jim Giles) (09/10/88)

From article <373@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> 
> We could have something like
> 	CALL HANDLE(exception, handler, oldhandler, ierror)
> where ierror would be set to a suitable value if the implementation was
> not able to catch that kind of error.  For example,
> 	CALL HANDLE('OVERFLOW', MYOVHD, OLDHD, IERROR)
> 	IF (IERROR .NE. 0) STOP 'CAN''T CATCH OVERFLOWS'

How does this suggestion differ from the supplimentary standard idea I
proposed in my last article (which you criticized the first part and appear
to have ignored the rest)?  My point is that it shouldn't be part of the 
language definition for two reasons: 1) it means that any machine/system
that can't support it won't be able to have a standard conforming environ-
ment; 2) if it's part of the language definition, different languages
will undoubtedly define the mechanism in different - mutually incompatible
ways.  Indeed, something like what you suggest _is_ available on all the
large-scale Fortran environments I've ever worked on.  The problem isn't
that Fortran doesn't have it and C does (C doesn't - the C library sometimes
does - the ANSI C standard _may_ require it), the problem is that there
is no language-independent standard for this functionality.

> Good heavens, if we were to accept the "some machines don't want to do it"
> argument, we wouldn't have floating-point arithmetic, and then where would
> Fortran be?

Some machines _don't_ have floating-point!  Neither Fortran nor C can 
run on such machines without simulating.  Interrupts can't even be 
simulated on machines/systems that don't provide such access.  (I've
talked with hardware designers and it's not as easy as you seem to 
think.  Consider overflow for example.  You want to intercept the
exception and do something to fix-up the result.  On a vector machine,
how do you tell which vector element needs fixing?  All the hardware
mechanisms to give you that information are either slow of prohibitively
costly or both.  The problem may even be worse for parallel archetectures
where you may not even know which CPU genereated the exception!  It's
all very simple on a primitive machine like a VAX (but even VAXen are
pipelined these days) - on faster machines, the best solution may really
be to halt the offending process with a message and not to provide
run-time exception handling to the user.)

J. Giles
Los Alamos

seanf@sco.COM (Sean Fagan) (09/12/88)

In article <3169@emory.uucp> platt@emory.UUCP (Dan Platt) writes:
>>#ifdef is an admission that your compiler isn't any good.  If the
>>conditional expression is a constant, a normal if statement should 
>>be optimized so that code is only generated for the active branch.  If
>>the conditional expression is not a constant, it couldn't be used as
>>part of an #ifdef either. 
[sorry, don't have the original author's name.  Somebody from Los Alamos, I
think]

This is *wrong*.  Take, for example, GNU EMACS.  #if's and #ifdef's all over
the place.  Why?  Different machines (and OS's) have different include
files, different structure names, etc.  For example, terminal control on BSD
is quite different from terminal control on System V Release anything
(except 4, I guess); the structure names, include files, and structure
elements are different.  The compiler will *not* allow you to use an
undefined structure element (such as foo.bar);  this is correct.

However, thinking like that is part of FORTRAN's problem.  Sigh.


-- 
Sean Eric Fagan  | "Joy is in the ears that hear, not in the mouth that speaks"
seanf@sco.UUCP   |     -- Saltheart Foamfollower (S. R. Donaldson)
(408) 458-1422   | Any opinions expressed are my own, not my employers'.

seanf@sco.COM (Sean Fagan) (09/12/88)

In article <3338@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>So what?  Functions called by dead code aren't really called after all.
>What difference does it make if the _if_ statement or the _ifdef_ directive
>is the visable syntax?  The _ifdef_ was only introduced because many 
>compilers are _very_ bad at dead code elimination.

>_OPEN_ statements which are 'system specific' are non-standard and don't
>enter into this discussion.  In any case, a compiler which complains of
>syntax errors in an OPEN statement which appears in the middle of a dead
>code sequence should be fixed.  Furthermore, there are ways to provide
>I/O extensions to Fortran without muching up the OPEN statement (I am just
>finishing an I/O support library for Fortran on the Crays, I provide a
>large number of extensions - including all the features proposed in
>8x - without altering the OPEN statement syntax in any compiler-checkable
>way).  
[I deleted mucho stuff; sorry]

This is the whole point.  The preprocessor (which you call unnecessary),
permits me to write a program on BSD, port it to SYSV, thence to VMS, and
end up with *one* program which will compile with no changes (such as, oh,
for a trivial example, take GNU EMACS).  I would like to see *any* FORTRAN
program, doing non-trivial stuff (i.e., more than just simple I/O and number
crunching), behave the same way, WITHOUT A PREPROCESSOR.
Take, for example, one of the world's most perfect FORTRAN machines [my bias
coming through; sorry again 8-)]:  the CDC Cyber 170/760.  Also take the
(painfully slow) DEC VAX 8800.  Write a useful program in FORTRAN on the
VAX.  Try to compile it on the Cyber.  Oops!  The compiler complained of
massive syntax errors.  Why?  VMS allows $'s in names, long function names,
etc.  NOS doesn't.  With a preprocessor, your problems go away (almost).

I like C on Unix systems.  I like FORTRAN on NOS.  I wish, at times, that
NOS had a preprocessor, but it doesn't.


-- 
Sean Eric Fagan  | "Joy is in the ears that hear, not in the mouth that speaks"
seanf@sco.UUCP   |     -- Saltheart Foamfollower (S. R. Donaldson)
(408) 458-1422   | Any opinions expressed are my own, not my employers'.

ok@quintus.uucp (Richard A. O'Keefe) (09/12/88)

In article <3385@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>From article <373@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
>> 
>> We could have something like
>> 	CALL HANDLE(exception, handler, oldhandler, ierror)
>> where ierror would be set to a suitable value if the implementation was
>> not able to catch that kind of error.  For example,
>> 	CALL HANDLE('OVERFLOW', MYOVHD, OLDHD, IERROR)
>> 	IF (IERROR .NE. 0) STOP 'CAN''T CATCH OVERFLOWS'
>
>How does this suggestion differ from the supplimentary standard idea I
>proposed in my last article (which you criticized the first part and appear
>to have ignored the rest)?

Life is too short to criticise everything that warrants criticism.

Perhaps I misunderstood what a "supplementary standard" is supposed to
be.  What I was suggesting is that there should be a _standard_ way of
catching exceptions which is required of *EVERY* implementation, but
that this standard method is allowed to return a standard "Sorry boss,
no can do" result.  With such an interface, you write *one* version of
the program which selects between two cases: detection and handling are
possible or they are not.  I used 'STOP' in my example to keep it short;
another reasonable alternative would be to print a message warning that
the results might be complete and utter rubbish, and proceed with the
calculation.

I understood a "supplementary standard" to be something like a "module"
in standard COBOL, where a feature may be completely missing.

That simply isn't good enough.

If the feature is in a "supplementary standard", so that it may or may
not be present in an implementation, then you have to prepare two
versions of the source code of your program.  (At *least* two.)  That's
precisely the kind of problem which standards are supposed to prevent.
In my proposal, the feature must *always* be present, so only one version
of the source code is needed.

>My point is that it shouldn't be part of the 
>language definition for two reasons: 1) it means that any machine/system
>that can't support it won't be able to have a standard conforming environ-
>ment;

Apart from questions of storage, there can be no such machine.
It might be _expensive_ to support exception handling, but that's not
the same thing as impossible.  Computers exist to execute programs,
NOT the other way around.  Are we to require that no Fortran program
may use more than 640k of data?  Some machines/systems can't support
more than that!

>2) if it's part of the language definition, different languages
>will undoubtedly define the mechanism in different - mutually incompatible
>ways.

But "benign neglect" such as you propose is precisely what has got us
into this mess!  PL/I, COBOL, and ADA *already* provide standardised
ways of handling (and optionally suppressing) arithmetic exceptions.
The only difference that leaving exception handling out of FORTRAN
makes is that it makes FORTRAN incompatible with itself.

>Indeed, something like what you suggest _is_ available on all the
>large-scale Fortran environments I've ever worked on.

This claim greatly reduces the force of Giles' argument against it!

>The problem isn't
>that Fortran doesn't have it and C does (C doesn't - the C library sometimes
>does - the ANSI C standard _may_ require it), the problem is that there
>is no language-independent standard for this functionality.

(a) The distinction between C-the-language and C-the-library is bogus.
    Is matherr missing from some implementations of C?  So is floating-
    point arithmetic.  Is floating-point arithmetic in the draft ANSI
    standard?  So is signal(). 

(b) There is no language-independent standard for input/output.
    Does that mean that input/output should not be part of a FORTRAN
    standard?  Until IEEE 754, there was no language-independent
    standard for floating-point arithmetic (and machines designed
    before that standard do not follow it).  Does that mean that
    floating-point arithmetic should not be in a FORTRAN standard?
    There is no language-independent standard for integer arithmetic!
    (Integers are obviously 36-bit 2s-complement, right?  Or is it
    32?  Or 16?  No, they're obviously sign + 39-bit magnitude...)
    PL/I FIXED data don't follow exactly the same rules as COBOL
    NUMERIC, and FORTRAN is different from both.  By Giles' rule,
    INTEGER arithmetic should be omitted from the FORTRAN standard,
    perhaps left to a "supplementary standard".  There is no
    language-indpendent standard for alternate returns, yet they
    are part of the 1978 FORTRAN standard.

>> Good heavens, if we were to accept the "some machines don't want to do it"
>> argument, we wouldn't have floating-point arithmetic, and then where would
>> Fortran be?
>
>Some machines _don't_ have floating-point!

I know that.  I'm using one.

>(I've
>talked with hardware designers and it's not as easy as you seem to 
>think.  Consider overflow for example.  You want to intercept the
>exception and do something to fix-up the result.

You are putting words in my mouth.  I DO NOT BELIEVE IN "FIXING-UP".
All I want to know is whether an exception occurred.  I'm not asking
for the incredibly hairy PL/I exception handling system with its
ON* pseudo-variables.  An ADA-style scheme where exceptions cause the
block then executing to be exited and the only information provided
is that such-and-such an exception occurred within the scope of
such-and-such a handler would be enough to ensure that garbage results
did not go undetected.

>On a vector machine,
>how do you tell which vector element needs fixing?

I don't particularly want to know.
If for some reason I want to know, a scheme like this:

	ON (OVERFLOW) IN
	    DO 10 I = 1, N
		A(I) = B(I)+C(I)
10	    CONTINUE
	HANDLER
	    DO 20 I = 1, N
		ON (OVERFLOW) IN
		    A(I) = B(I)+C(I)
		HANDLER
		    PRINT *, 'OVERFLOW AFFECTED A(',I,')'
		    A(I) = 0.0
		END HANDLER
20	    CONTINUE
	END HANDLER

would work.  Sure, the second loop won't be vectorised, but it will
only be executed when the exception has occurred.  Imprecise exceptions
in the first loop are fine.

Giles is arguing that the present vicious circle should be maintained:
    FORTRAN has no *standard* exception-handling scheme, so
    architects say "we don't have to provide for non-standard features", so
    computers are built where arithmetic is allowed to produce GARBAGE, so
    exception handling is hard to do on some machines, so
    FORTRAN has no *standard* exception-handling scheme.
It is time we told the architects that high-speed garbage is garbage.
It is important to know whether a computation has delivered correct
results.  It is not so important to know exactly where it went wrong:
we can write our programs to switch over to slower more careful code
if we really need to know.

EGNILGES@pucc.Princeton.EDU (Ed Nilges) (09/13/88)

In article <1225@scolex>, seanf@sco.COM (Sean Fagan) writes:
 
>In article <3169@emory.uucp> platt@emory.UUCP (Dan Platt) writes:
>>>#ifdef is an admission that your compiler isn't any good.  If the
>>>conditional expression is a constant, a normal if statement should
>>>be optimized so that code is only generated for the active branch.  If
>>>the conditional expression is not a constant, it couldn't be used as
>>>part of an #ifdef either.
>[sorry, don't have the original author's name.  Somebody from Los Alamos, I
>think]
>
>This is *wrong*.
 
 
It sure the hell is.  In reference (1), Brian Kernighan says, code what
you mean.  Macro facilities (even the still-primitive-after-all-these-
years facilities of C) allow the software engineer (as opposed to the
hacker) to declare an intent to control how the software shall exist
in various environments.  #ifdef & the macro processor in general allows
the C programmer to define a range of potential compilation and execution
environments.  For example, if I am writing a program to run both on
ASCII machines and the IBM 370, which is an EBCDIC machine, the following
should be source compatible (altho I have not tested it, and it assumes
that either ASCII or EBCDIC will be defined)
 
 
     #ifdef EBCDIC
          /* Boo */
          isalpha = ( inchar>='a' && inchar<='i'
                      ||
                      inchar>='j' && inchar<='r'
                      ||
                      inchar>='s' && inchar<='z'
                      ||
                      inchar>='A' && inchar<='I'
                      ||
                      inchar>='J' && inchar<='R'
                      ||
                      inchar>='S' && inchar<='Z' );
     #endif
     #ifdef ASCII
          /* Yay */
          isalpha = ( inchar>='a' && inchar<='z'
                      ||
                      inchar>='A' && inchar<='Z' )
     #endif
 
 
Indeed, the whole technique of conditional assembly, used heavily within
IBM to generate systems across a variety of environments, is so little
used in HLLs that a name for it does not roll easily off the tongue.  This
will be the case until CS departments realize that wisecracks about
machines you don't like won't get you off the hook when you have to port
your code.  When will C have a decent conditional compiler?

jlg@lanl.gov (Jim Giles) (09/13/88)

From article <379@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> 
> You are putting words in my mouth.  I DO NOT BELIEVE IN "FIXING-UP".
> All I want to know is whether an exception occurred. [...]

No, that's obviously _not_ 'all you want to know'.  If that was all you
wanted, you don't need _any_ mention of exceptions anywhere in any
standard except to say that exceptions _always_ should halt the code.
There are only two types of machine/system in productive use, those
that allow run-time exception handling within user code, and those
that don't.  The universal action taken by those that don't is to 
halt the offending process with a message. This does not allow 'garbage
results to go undetected' - in fact it doesn't allow garbage results
to go at all!

The only reason to allow run-time user control after an exception is
to allow the user code to try some fix-up action.  Your demand for
run-time exception handling directly implies that you have some remedial
activity in mind.  Whether you choose to _call_ it a fix-up or not is
beside the point.

> Giles is arguing that the present vicious circle should be maintained:
>     FORTRAN has no *standard* exception-handling scheme, so
>     architects say "we don't have to provide for non-standard features", so
>     computers are built where arithmetic is allowed to produce GARBAGE, so
>     exception handling is hard to do on some machines, so
>     FORTRAN has no *standard* exception-handling scheme.

If you've got a Fortran which produces exceptions without reporting it, 
you've got a broken Fortran.  The issue here is whether the user code
should be allowed to regain control after an exception occurs.  The
answer is _not_ a simple 'yes'.  

> It is time we told the architects that high-speed garbage is garbage.

Archetects already know this.  That's why exceptions either halt the
offending code, or generate a signal which interrupts the offending code.
Systems that don't do the later may have a legitimate reason for not doing
so.  Language definitions which _require_ the system to do the later
are _not_ universally portable.  Insisting that all machines should do
the latter may deprive users of significantly improved performance of 
correct programs just to allow a _very_slight_ convenience for incorrect
programs (imagine that, correct programs forced to run slower simply in
order that some user can produce a different-than-default termination
message for his wrong code!).

A language-independent library standard could be developed to address these
points.  For those machines which don't allow user code to regain control
after an exception, the library could remain (and be a no-op).  This
would allow machine independent code to be developed (in more than one
language even!).  The alternative is to allow each language to specify
its own (different) method of handling this stuff.  Some standards (like
the ANSI C) won't allow the signalling mode to be optional, so the 
complete language may not be implementable on all machines (including
some that might be _very_ desireable for other reasons).  I opt for the
first choice.

J. Giles

jlg@lanl.gov (Jim Giles) (09/13/88)

From article <1226@scolex>, by seanf@sco.COM (Sean Fagan):
> 
> This is the whole point.  The preprocessor (which you call unnecessary),
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
> [...]

Wrong.  Read what I said.  I never called the preprocessor unnecessary.
I said the preprocessor was _not_ relevant to the choice of language
since _any_ language can be preprocessed.  I was also pointing out that
for many of the uses of #ifdefs, a smart compiler would do the same job.

People keep saying that Fortran has no preprocessor.  This is _not_
true.  Preprocessing is a textual substitution problem.  It can be done
on _any_ sufficiently powerful text editor.  Not only that, cpp can usually
be applied to any text file you have - including Fortran code.  A pre-
processor _is_ unnecessary in a language standard - in fact, standardizing
would only complicate the compiler writer's job without actually enhancing
the language at all.

J. Giles

ok@quintus.uucp (Richard A. O'Keefe) (09/13/88)

In article <3446@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>From article <379@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
>> 
>> You are putting words in my mouth.  I DO NOT BELIEVE IN "FIXING-UP".
>> All I want to know is whether an exception occurred. [...]
>
>No, that's obviously _not_ 'all you want to know'.  If that was all you
>wanted, you don't need _any_ mention of exceptions anywhere in any
>standard except to say that exceptions _always_ should halt the code.

Note that I have been quoted out of context.
Giles was saying that requiring exception handling in the standard would
not be a good idea because generating precise exceptions on some machines
(such as vector-processing ones) would be very costly.  His text seemed
to imply that this was necessary in order that the program could "fix up"
the mistake.

The point of my statement was that I do not want a PL/I-like scheme
where a faulting statement can be pinpointed and "corrected".

Let me try to be maximally clear.  What I want in an exception handling
facility is
	- notification *to the program* that an error (fairly broadly
	  identified) has occured *somewhere* within a particular region
	  of the code, that region potentially being quite large, and
	  precise location within the region not being important

	- the possibility of the program *substituting* a *different*
	  calculation in place of the faulted one.  (Think "recovery
	  blocks".)

>The only reason to allow run-time user control after an exception is
>to allow the user code to try some fix-up action.  Your demand for
>run-time exception handling directly implies that you have some remedial
>activity in mind.  Whether you choose to _call_ it a fix-up or not is
>beside the point.

Well, the "remedial activity" might be deleting scratch files (very
common), logging the failure, and then exiting.  I wouldn't have thought
of calling this "a fix-up", but what do I know?

>If you've got a Fortran which produces exceptions without reporting it, 
>you've got a broken Fortran.

Well, it's a couple of years since I saw a Fortran standard, but as I
recall it, the response of a Fortran processor to errors is "undefined".
Giles might call a Fortran processor which doesn't report errors broken,
I might call it broken, but neither of us can call it non-standard.

For example, although programs generated by the VMS Fortran compiler
normally report integer overflow exceptions, programs generated by
"f77" (and even Sequent's "fortran") do not.  So adding *positive*
integers is allowed to *quietly* give you *negative* results.

>Language definitions which _require_ the system to do the later
>are _not_ universally portable.

***NOTHING*** is universally portable.
I pointed out in some detail that integer arithmetic is not "universally
portable".  Giles has not yet refuted this.
The proposition "a language definition should not require the system to
do anything which would not be universally portable" entails the
proposition "the very worst computer architect has more right to decide
what a language should look like than the people who want to use the
language".  An architect could tomorrow come up with a machine where
subroutine calling is outrageously expensive, and a company could market
the machine next week, and the "universal portability" rule would force
us to delete subroutines from our language standards.

>Insisting that all machines should do
>the latter may deprive users of significantly improved performance of 
>correct programs just to allow a _very_slight_ convenience for incorrect
>programs (imagine that, correct programs forced to run slower simply in
>order that some user can produce a different-than-default termination
>message for his wrong code!).

I am afraid that this really annoys me.
Let's see what assumptions we can find in it.
(1) The only use of exception handling is to produce termination
    messages.
(2) The only consumer of termination information from a program is
    the user (that is, programs are never invoked by other programs).
(3) There are non-trivial correct programs.
(4) Programs which meet their specifications can never get exceptions
    due to data not covered in the specifications (the sentence quite
    explicitly says that the cause of exceptions is "wrong >code<").
(5) No Fortran program ever does anything to its environment which
    should be undone before termination (no scratch files, no numerically
    controlled tools, no screen blanking, ...)
(6) The only people who matter are the people who want top performance;
    people who are trying to write _reliable_ systems don't count.
(7) End-users don't matter (the sentence quite clearly assumes that
    producing a "different-than-default termination message" is not
    important).

As a professional programmer I know that (1), (2), (4), and (5) are
factually false, cannot agree with (6) or (7), and would dearly like
to believe (3) but don't.  I will go so far as to say that if the
only use of exception handling _were_ to produce termination messages
that the end-user could understand, that would be sufficient warrant
for requiring it.

I also point out once more that my proposal would allow an implementation
to say "no, I can't do this", which means that it would have *ZERO*
performance impact when a program did not request exception handling.

>A language-independent library standard could be developed to address these
>points.

Let's see it!  Don't forget, there's ADA, APL, BASIC, C++, COBOL, FORTRAN,
LISP, ML, MODULA-2, PASCAL, PL/I, SIMULA, Smalltalk-80, ...

>The alternative is to allow each language to specify
>its own (different) method of handling this stuff.

THIS HAS ALREADY HAPPENED!  Putting an exception handling facility in
a Fortran standard won't make things worse!  (The kind of thing I want
could easily be compatible with ADA.)

If someone really wants super-high performance and is willing to put up
with non-standard or non-existence exception handling to get it, let
them use a non-standard language.  It is already the case that people
using "supercomputers" have been using non-standard Fortrans.  Why should
using a Fortran which has a non-standard exception system be any worse?
Let's face it, if you are after absolute top performance, you are likely
to introduce machine-specific stuff into your program anyway.

There are at least two kinds of programs:
(s) programs for wizards (yourself, other people in your group, certainly
    noone who lacks access to the source code or wouldn't understand it).
(o) programs for mortals (especially programs written for sale to people
    who do not get the source code).
I get the impression that Giles is thinking in terms of (s), while I am
thinking in terms of (o).  If someone is writing a computational fluid
dynamics program for use within his own research group, exception handling
is not so important (but still good).  But someone who is writing a
linear programming package for use on PCs by students all over the country
[thank goodness I am _not_ doing that!] had better try to make it as
robust as possible.

ok@quintus.uucp (Richard A. O'Keefe) (09/13/88)

In article <3448@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>People keep saying that Fortran has no preprocessor.  This is _not_
>true.  Preprocessing is a textual substitution problem.  It can be done
>on _any_ sufficiently powerful text editor.  Not only that, cpp can usually
>be applied to any text file you have - including Fortran code.  A pre-
>processor _is_ unnecessary in a language standard - in fact, standardizing
>would only complicate the compiler writer's job without actually enhancing
>the language at all.

(1) cpp need not exist on every system.
    It need not even exist on a system which has a C compiler.
    [For example, the DEC-10 C compiler did not have a separate cpp.]

(2) cpp may be applied to any text file.  True.
    cpp may be USEFULLY applied to Fortran code.  FALSE.

    For example, consider the Fortran statement
	+0000000001111111111...77777777778+
	+12345C7890123456789...01234567890+
	|      X = 'THIS IS ...ONG00123000|
	|     & FORTRAN STRI...'  00124000|
    cpp doesn't know about Fortran continuation rules or sequence numbers.

(3) If I develop a program on machine X and then later try to compile it
    on machine Y I need the *SAME* preprocessor on both machines.  Giles
    is right that it doesn't have to be in the _language_ standard, but
    there _does_ have to be a preprocessor standard.  Does anyone wonder
    why I treasure my copy of the public-domain Ratfor sources, or of the
    public-domain M4?  Does anyone wonder why I _haven't_ bothered to get
    my own copy of cpp?

jlg@lanl.gov (Jim Giles) (09/14/88)

From article <391@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> (3) If I develop a program on machine X and then later try to compile it
>     on machine Y I need the *SAME* preprocessor on both machines.  Giles
>     is right that it doesn't have to be in the _language_ standard, but
>     there _does_ have to be a preprocessor standard.  Does anyone wonder
>     why I treasure my copy of the public-domain Ratfor sources, or of the
>     public-domain M4?  Does anyone wonder why I _haven't_ bothered to get
>     my own copy of cpp?

Gee, because cpp is not _universally_ applicable to Fortran this means
Fortran _can't_ be preprocessed at all.  I gave cpp as an example, not
_only_ possibility.  I still stand by my original statement: Fortran 
_can_ be preprocessed!  I do it all the time.

Also: this statement (3) contains the assumption that preprocessing
_must_ be done on the same machine as compiling.  I haven't done that
for a long time.  I do code development for Crays.  I do text editing
and marco expanding for this Cray code on my Sun workstation.  You 
don't need the *SAME* preprocessor on any machine other than the one
you write code on (not the one you write code _for_, just the one that
you edit the source on).  You're assuming that the whole programming
environment changes every time you have a new _target_ machine.  The
advantage of workstations and PC's is that each developer can keep
his coding environment with him even if the target archetectures change
weekly.  And, PC's are finally getting powerful enough to make this
a personal ability of each developer (he isn't tied to the equipment
provided by his employer).

J. Giles
Los Alamos

jlg@lanl.gov (Jim Giles) (09/14/88)

From article <390@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> 	- the possibility of the program *substituting* a *different*
> 	  calculation in place of the faulted one.  (Think "recovery
> 	  blocks".)

This assumes that the original code (which generated the fault) hasn't
changed the data while it was executing.  Most real applications don't
have that kind of memory.  Numerical codes (like off-the-shelf FFTs)
usually update their data in place.  By the time you get back to re-execute
the code with your *different* calculation, the data has been changed.

Now, recovery blocks work completely differently.  A explicit 'snap-dump'
is take at intervals and, if the code has an exception, you explicitly
go back to the context of the most recent dump.  This can be done without
the user having exception handling code.  If nothing else, it can be
done by hand.

> Well, the "remedial activity" might be deleting scratch files (very
> common), logging the failure, and then exiting.  I wouldn't have thought
> of calling this "a fix-up", but what do I know?

Deleting scratch files (and other such destructive habits) are _VERY_
bad ideas.  The cause of the exception might be contained in that scratch
file.  By deleting it, you have destroyed valuable evidence to the
user in finding the cause of the fault.  Having worked as a programming
instructor at university, I know first hand the painful lessons learned
from arbitrarily 'cleaning-up' the files when an exception occurs.

Logging the failure is done by the system, so is exiting.  What you want
here is something other than the default method of logging and exiting.

> Well, it's a couple of years since I saw a Fortran standard, but as I
> recall it, the response of a Fortran processor to errors is "undefined".
> Giles might call a Fortran processor which doesn't report errors broken,
> I might call it broken, but neither of us can call it non-standard.

Since this is a C VS. Fortran discussion, I guess that you're saying
C doesn't have this fault.  (Quick - why is x<<32 different from x<<16<<16
on a VAX in C - it's undefined, that's why!)  Yes, I call a Fortran 
which doesn't report overflow (or whatever) 'broken'.  I call C with
the above parenthetical problem 'broken' too.  

>>Insisting that all machines should do
>>the latter may deprive users of significantly improved performance of 
>>correct programs just to allow a _very_slight_ convenience for incorrect
>>programs (imagine that, correct programs forced to run slower simply in
>>order that some user can produce a different-than-default termination
>>message for his wrong code!).
> 
> I am afraid that this really annoys me.
> Let's see what assumptions we can find in it.
> (1) The only use of exception handling is to produce termination
>     messages.
I didn't make this assumption, it just happens to be one of the common
uses of exception handling (in fact - one of the _most_ common).
> (2) The only consumer of termination information from a program is
>     the user (that is, programs are never invoked by other programs).
Of course, controllers can catch the default termination message that the
system puts out - the executable need not be able to catch its own errors
for this capability.
> (3) There are non-trivial correct programs.
I don't know what this means.  If you're implying that a code which
deliberately generates (and recovers from) an exceptional condition
is 'correct', you have a strange concept of what correctness is.
> (4) Programs which meet their specifications can never get exceptions
>     due to data not covered in the specifications (the sentence quite
>     explicitly says that the cause of exceptions is "wrong >code<").
Exactly so.  I do claim that exceptions are errors.  That was the designed
purpose of exceptions.  For example, passing a negative argument to a
floating-point (not COMPLEX) LOG function is an *ERROR*.  Any code which
does so deliberately is not 'correct', even if it does what the user
intended.
> (5) No Fortran program ever does anything to its environment which
>     should be undone before termination (no scratch files, no numerically
>     controlled tools, no screen blanking, ...)
The assumption _you're_ making here is that all this termination clean-up
isn't going to obscure the cause of the fault.  It often does.  It's a
bad idea: a) to have any files, tools, or screen modes which can't be
undone manually; and b) to do any of such things automatically in an 
error state.
> (6) The only people who matter are the people who want top performance;
>     people who are trying to write _reliable_ systems don't count.
Reliable systems are ones which don't produce _wrong_ answers.  What
you seem to want are systems which continue to run after errors have
occured (and you _assume_ that your exception handler works correctly).
What you want is not necessary for reliability.  What you want _may_
improve robustness (or, maybe not - who wrote your exception handler?).
Robustness is something that can be traded-off against performance.
You are the one that is claiming that only one type of person matters:
those who crave your brand of robustness.  I never said that designers
should not consider your type of exception handling - I said that there
might be legitimate reasons for excluding it in some designs.
> (7) End-users don't matter (the sentence quite clearly assumes that
>     producing a "different-than-default termination message" is not
>     important).
It may, or may not, be important.  The degree of importance should be
traded off against other considerations (like performance).  _YOU_ are
the one who wants the standard to _require_ a particular type of 
exception handling.  I maintain that the language standard should only
require those things which are necessary to the proper use of the
language.  Reliable code _can_ be written _without_ user controlled 
exception handling.  This is _not_ the province of language standards.

> [...]                   I will go so far as to say that if the
> only use of exception handling _were_ to produce termination messages
> that the end-user could understand, that would be sufficient warrant
> for requiring it.

In a system with lot's of naive users and no particular performance
requirements, I'll agree.  In a system where the users are professionals
and their understanding of their programs and system is quite good,
I would argue that performance should take the upper hand.  Languages
which are only designed to work in _one_ of these environments and not
the other are not adequate for Numerical work (where there is _much_
of both kinds of work).  So, I still claim that the language is _not_
the place to standardize this stuff.
> 
> I also point out once more that my proposal would allow an implementation
> to say "no, I can't do this", which means that it would have *ZERO*
> performance impact when a program did not request exception handling.

No, your proposal would allow the language designers to say what _they_
wanted the implementation to do.  If _they_ say that the option "no,
I can't do this" is illegal in their language, then that's that!  My
proposal is that exception handling should not be in the language, but
in a seperate library.  In my proposal, there _is_ the choice available
to the implementor to say "no, I can't do that".  The implementor can
say that, and _still_ be standard conforming (for those languages which
aren't already damaged by including other requirements). 

>>A language-independent library standard could be developed to address these
>>points.
> 
> Let's see it!  Don't forget, there's ADA, APL, BASIC, C++, COBOL, FORTRAN,
> LISP, ML, MODULA-2, PASCAL, PL/I, SIMULA, Smalltalk-80, ...

I said 'language-independent' not 'universal'.  It is clearly desireable
for Fortran, Pascal, C, and Modula-2 (and any other procedural languages
you happen to have) to be able to call each other in the same program.
In such a context, the exception handler could be written in one of the
above - or in assembly - and be usable for all the others.  I claim that
this is a _much_ better solution than letting each language committee
decide on their own.  And, if my solution is standardized, it would
be portable as well.
> 
>>The alternative is to allow each language to specify
>>its own (different) method of handling this stuff.
> 
> THIS HAS ALREADY HAPPENED!  [...]

That doesn't make it a good idea!!  By your logic, language designers
should never even _try_ to learn from the mistakes of others.

> There are at least two kinds of programs:
> (s) programs for wizards (yourself, other people in your group, certainly
>     noone who lacks access to the source code or wouldn't understand it).
> (o) programs for mortals (especially programs written for sale to people
>     who do not get the source code).
> I get the impression that Giles is thinking in terms of (s), while I am
> thinking in terms of (o).  [...]

No, I'm thinking in terms of _BOTH_.  I know, flexibility is a novel
idea.  YOU'RE the one who claims that language standards should exclude
one of these two groups.  I say, make the language cater to both groups,
and if group (o) needs additional features, define them independently
from the language.

J. Giles
Los Alamos

smryan@garth.UUCP (Steven Ryan) (09/14/88)

It's Tweedle-dee and Tweedle-dum time.

I think both Fortran and C suck turnips.

(Just wanted to contribute a view orthogonal to all other planes.)

ok@quintus.uucp (Richard A. O'Keefe) (09/14/88)

In article <3448@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>People keep saying that Fortran has no preprocessor.  This is _not_
>true.  Preprocessing is a textual substitution problem.  It can be done
>on _any_ sufficiently powerful text editor.  Not only that, cpp can usually
>be applied to any text file you have - including Fortran code.

In article <391@quintus.UUCP>, I wrote
    several reasons why cpp cannot in fact be used on >Fortran< code
    (though it isn't too shabby for Ratfor).

In article <3494@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>Gee, because cpp is not _universally_ applicable to Fortran this means
>Fortran _can't_ be preprocessed at all.  I gave cpp as an example, not
>_only_ possibility.  I still stand by my original statement: Fortran 
>_can_ be preprocessed!  I do it all the time.

I did not say that "Fortran cannot be preprocessed at all".
My posting attacked quite specifically Giles' claim that
"cpp can be applied to ... Fortran code".

For example, the UNIX f77 compiler will call cpp for you, but this
is not always useful.  Here is a toy example:

tr ">" "\011" <<EOF >zabbo.F
#define HAIRY(A,B,C) (A+B+C+A+B+C+A+B+C+A+B+C+A+B+C)
>REAL FUNCTION VECSUM(FLTVEC)
>REAL FLTVEC(3)
>VECSUM = HAIRY(FLTVEC(1), FLTVEC(2), FLTVEC(3))
>END
EOF
f77 -c zabbo.F

That works.  But
sed -e 's/>/      /' <<EOF >zabbo.F
~~~as before~~~

produces error messages from the f77 compiler:
Error on line 4 of zabbo.F: unbalanced parentheses, statement skipped
Error on line 4 of zabbo.F: Execution error unclassifiable statement

Wizards will at once realize what the problem is.  If you want to use
cpp as your preprocessor with f77, you *cannot* use standard Fortran
layout.  No discredit to cpp, it is meant for C after all.

I have seen the guts of several statistics packages which were written
in Fortran, and they were totally dependent on preprocessing for their
portability.  Only snag was, *first* you had to port the preprocessor.

>Also: this statement (3) contains the assumption that preprocessing
>_must_ be done on the same machine as compiling.

I'll concede this one, though I'd point out that I did avoid assuming
that you compile on the machine you run on.

Giles has in mind the situation where he is using a fairly powerful
workstation and pushing code to other machines.  This is nice PWB-type
stuff.  I have in mind situations where I write a program on my machine
and give the source code to other people, where it may be quite
impossible for me to do the preprocessing on my machine.  For example,
writing a C program under 4.2BSD with due care and attention given to
portability, and constant checking of the SVID to ensure that the
program _ought_ to port to V.2, but where I cannot do the preprocessing
on the 4.2BSD machine because I haven't got the necessary header files.

Can we agree on the following statement about preprocessing:
    You need the same preprocessor on each preprocessing-host, and

    the preprocessor on a particular preprocessing-host has to know
    enough about each compiler and target computer which that
    preprocessing-host is used with.

(E.g. if I do my preprocessing on a Sun, my compilation on a Sun, a Vax,
and a Sequent, and my execution on a Sun, Vax, Cray, Fujitsu, and Cyber,
then my preprocessor has to know about 3 compilation environments and
5 execution environments.)

I am not arguing that preprocessing needs to be part of the Fortran
language standard, but I do claim that a preprocessor for Fortran should
be designed for Fortran, not C, and should either be at least as
standardised as pre-ANSI C or should be provided to users in source form.

peter@ficc.uu.net (Peter da Silva) (09/15/88)

In article <3494@lanl.gov>, jlg@lanl.gov (Jim Giles) writes:
> Gee, because cpp is not _universally_ applicable to Fortran this means
> Fortran _can't_ be preprocessed at all.  I gave cpp as an example, not
> _only_ possibility.  I still stand by my original statement: Fortran 
> _can_ be preprocessed!  I do it all the time.

Let's spell this out.

There is no standard program available with all Fortran compilers that
does preprocessing of the program (conditional compilation, etc). This
means you can't write and distribute a Fortran version of Emacs, say,
with all the different environments conditionally compiled in. Why not?
because you can't depend on the guy at the other end having it.

And suppose you're not distributing the source. You develop teh thing in
your "personal environment". What happens 2 years down the road when someone
else wants to modify it... woops, we can't find your preprocessor.
-- 
Peter da Silva  `-_-'  Ferranti International Controls Corporation.
"Have you hugged  U  your wolf today?"            peter@ficc.uu.net

jlg@lanl.gov (Jim Giles) (09/16/88)

From article <1510@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva):
> Let's spell this out.
> 
> There is no standard program available with all Fortran compilers that
> does preprocessing of the program (conditional compilation, etc). This
> means you can't write and distribute a Fortran version of Emacs, say,
> with all the different environments conditionally compiled in. Why not?
> because you can't depend on the guy at the other end having it.

Let's spell this out.  

Since the preprocessor can be written in _standard_Fortran_77, it doesn't
matter that it's not distributed with the compiler.  I can distribute
the preprocessor _with_ the code.  Preprocessors are _very_ simple to
write - I've written them before - I'll probably write them again.
The only thing the 'guy at the other end' needs to have is a standard
conforming compiler.  If he hasn't got _that_ he won't be able to 
run my code anyway.  The _same_ complaint can be directed against
C - if the target machine hasn't got a correctly working C compiler,
you can't port!

The main reason _not_ to put the preprocessor into Fortran itself
is that they might do something like C did - leave out many useful
features and include some which are incompatible with the ones I
want.  I have to write my own preprocessors for C too. 8-(

J. Giles

gl8f@bessel.acc.Virginia.EDU (Greg Lindahl) (09/16/88)

In article <1510@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>
> [stuff deleted]
>
> There is no standard program available with all Fortran compilers that
> does preprocessing of the program (conditional compilation, etc).

One large image processing package (AIPS) is written in FORTRAN and is
portable across all kinds of environments -- VAX/VMS, Unix V and 4.X,
Crays (COS and Unicos), etc. It was done without preprocessing at all, 
except for certain operating systems (UNIX) which have particurally
brain-damaged FORTRAN compilers (no INCLUDE statement). (I'm not claiming
that INCLUDE is standard, merely that is was useful to the AIPS programmers.)
They achieved portability by isolating operating system dependent code
into routines which were rewritten for each operating system. This isn't
the most elegant approach, but it works without preprocessing.

Greg Lindahl                              internet:  gl8f@virginia.edu
U Va Dept. of Astronomy                   bitnet:    gl8f@virginia.bitnet

wes@obie.UUCP (Barnacle Wes) (09/16/88)

In article <535@nikhefh.hep.nl> t68@nikhefh.hep.nl (Jos Vermaseren) writes:
> 	float x = -2.0;
> 	z = sqrt(x);
> 
> gives back some value. Amazingly enough many UNIX vendors like this
> philosophy, so even the UNIX fortran compilers often prefer it this way.

In article <356@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes:
% (1) See "matherr" in the System V documentation.  If you define a function
%     int matherr(struct exception *x) it will be called when math library
%     functions detect a problem.

As a matter of fact, the V.2 documentation for matherr(3m) addresses the
sqrt "problem" directly:

#include <math.h>
int matherr(x)
register struct exception *x;
{
    switch (x->type) {
    case DOMAIN:
        /* change sqrt to return sqrt(-arg1), not 0 */
    	if (!strcmp(x->name, "sqrt")) {
    	    x->retval = sqrt(-(x->arg1));
            return 0;
    	}
    /* other cases follow here... */
    }
    return 0;	/* all other errors execute default procedure */
}
-- 
                     {hpda, uwmcsd1}!sp7040!obie!wes

         "How do you make the boat go when there's no wind?"
                                 -- Me --

brian@radio.uucp (Brian Glendenning) (09/18/88)

In article <559@hudson.acc.virginia.edu>, gl8f@bessel (Greg Lindahl) writes:
>In article <1510@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>>
>> [stuff deleted]
>>
>> There is no standard program available with all Fortran compilers that
>> does preprocessing of the program (conditional compilation, etc).
>
>One large image processing package (AIPS) is written in FORTRAN and is
>portable across all kinds of environments -- VAX/VMS, Unix V and 4.X,
>Crays (COS and Unicos), etc.

It is true that AIPS is only preprocessed to do fairly trivial things (put in
common block declarations, change ENCODE statements to in-core writes etc).
Howerver to use aips as an example of FORTRAN portability isn't really fair
since the lower level calls are often not in fortran (largely C for unix
systems), and on those machines where it is fortran, it is in a very extended
fortran.

This is nothing against AIPS. It is a multi-tasking image processing "operating
system" with it's own file system etc. Fortran isn't the best language to
implement low level OS structure.
-- 
	  Brian Glendenning - Radio astronomy, University of Toronto
brian@radio.astro.toronto.edu uunet!utai!radio!brian  glendenn@utorphys.bitnet

ins_aejs@jhunix.HCF.JHU.EDU (Edward Sullivan) (09/20/88)

In article <3448@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
 >Preprocessing is a textual substitution problem.
 >...cpp can usually be applied to any text file you have -
 >including Fortran code.
then, in reply:
In article <391@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes: 
> (1) cpp need not exist on every system.
>...
> (2) cpp may be applied to any text file.  True.
>     cpp may be USEFULLY applied to Fortran code.  FALSE.
 to say that cpp need not exist on every system does not address
the point that cpp can be applied as a preprocessor for Fortran
programs.

 To say that cpp cannot be usefully applied to Fortran programs
is simply incorrect. I've done it myself. No quibbling about
whether you can call a program that uses #include a Fortran
program. I say its a Fortran program, f77 says its a Fortran program,
and using #includes for common blocks and parameter statements
helped eliminate those nasty errors resulting from defining the same
common block differently in different routines. So there.

ok@quintus.uucp (Richard A. O'Keefe) (09/21/88)

In article <7029@jhunix.HCF.JHU.EDU> ins_aejs@jhunix.HCF.JHU.EDU (Edward Sullivan) writes:
> To say that cpp cannot be usefully applied to Fortran programs
>is simply incorrect. I've done it myself. No quibbling about
>whether you can call a program that uses #include a Fortran
>program.

Ambiguity here:
    it IS possible to write "a" Fortran program which can be used with
    cpp	(which Giles is now affirming, and which surely no-one denies)

    it is NOT possible to apply cpp usefully to "a" standard Fortran
    program which already exists (which I have been denying).

I thought the example I posted, which showed that a perfectly sensible
application of cpp to a perfectly ordinary Fortran text (apart from the
#define) yielded *garbage* (well, the Fortran compiler thought it was)
was a sufficient proof of my claim that cpp is not GENERALLY applicable
to Fortran texts.

It certainly isn't applicable to texts which already exist, because it
doesn't know that the following three statements are the same in F77:
	HERE = THERE
	HERE = THE R E
	HERE = TH
     1	       ERE
and if there were a macro #define THERE, it would _not_ be expanded in
the last two cases.  A reasonable application of cpp might be to try to
replace calls to a function CDCFNC(X,Y) by calls to VAXFNC(X,Y), but
for this reason, it cannot be expected to work in all cases.  For real
fun, consider
	#define C 3.0E8
	C     THIS ONE IS *NOT* THE SPEED OF LIGHT, BUT GUESS WHAT
Unfortunately, no cpp that I have used can be used *directly* to write
macros which expand into multiple Fortran statements:
	#define MACRO	\
		X = 1	\
		Y = 2	\
		CALL FRED
	      MACRO
	      MACRO
	      END
expands to
	      X = 1 Y = 2 CALL FRED
	      X = 1 Y = 2 CALL FRED
	      END
as you may discover by trying it yourself.  I have had some success with
putting semicolons in the macros, e.g.
	#define MACRO	\
		X = 1;	\
		Y = 2;	\
		CALL FRED
and putting the result through a sed(1) filter which turns the semicolons
into a new-line and a tab.

The bottom line is that if you want to use cpp (which is the *C*
pre-processor after all) on Fortran texts, you have to make your
Fortran texts conform to the lexical rules of C, as far as you can,
and you may have to postprocess the output to make it acceptable to
a Fortran processor (even, as I showed in an earlier posting, to a
Fortran processor on the same UNIX system).

A much better plan, if you want to write Fortran code with the aid
of cpp, is, as I said in an earlier posting, to write your source
code in Ratfor, which is much more lexically compatible with C and
is _designed_ to be used with cpp, and use the Ratfor processor as
the back-end to convert cpp's output to Fortran.

ok@quintus.uucp (Richard A. O'Keefe) (09/21/88)

In article <459@quintus.UUCP> ok@quintus.UUCP I wrote:
> ... Ratfor ... is _designed_ to be used with cpp ...
It isn't true.  Please forget I said it.

jlg@lanl.gov (Jim Giles) (09/22/88)

From article <459@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
>     it is NOT possible to apply cpp usefully to "a" standard Fortran
>     program which already exists (which I have been denying).

I have several standard Fortran programs which already exist to which
cpp can be usefully applied.  What you are trying to claim is that is is
possible to find a standard conforming Fortran program (presumably more
than one) which causes cpp to generate bad results.  No one has ever
denied that.  But even thos can be rewritten to avoid cpp's problems.
Failing that - write a preprocessor in standard conforming Fortran.
Then ship your preprocessor to any site that you ship your other source
to.

J. Giles
Los Alamos

ok@quintus.uucp (Richard A. O'Keefe) (09/23/88)

In article <3962@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>From article <459@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
>>     it is NOT possible to apply cpp usefully to "a" standard Fortran
>>     program which already exists (which I have been denying).
>
>I have several standard Fortran programs which already exist to which
>cpp can be usefully applied.  What you are trying to claim is that is is
>possible to find a standard conforming Fortran program (presumably more
>than one) which causes cpp to generate bad results.  No one has ever
>denied that.

That's not what I was TRYING to claim, it is precisely what I DID claim.
The claim that "cpp can be applied to A Fortran program" is normally to
be understood as meaning "to every Fortran program", which I denied.
Giles' original claim was that preprocessing capabilities were not needed
as part of a Fortran standard because it is a text editing task which can
be done by a wide range of tools, specifically including cpp.  My claim
is that many, perhaps even most, Fortran programs not written with cpp (or
a very similar tool) in mind cannot usefully be used with cpp.  Obviously,
there is at least one program where it will work:
	END

If you want to preprocess COBOL, you're better off if your preprocessor
understands COBOL lexical structure, and produces output which respects
COBOL's layout requirements.
If you want to preprocess FORTRAN, you're better off if your preprocessor
understands FORTRAN lexical structure, and produces output which respects
FORTRAN's layout requirements.
cpp applied to Fortran is like a dog walking on its hind legs.

jlg@lanl.gov (Jim Giles) (09/24/88)

From article <465@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> That's not what I was TRYING to claim, it is precisely what I DID claim.
> The claim that "cpp can be applied to A Fortran program" is normally to
> be understood as meaning "to every Fortran program", which I denied.

When I _mean_ 'every', I _say_ 'every'.  When I say 'a', I mean 'a';
that is, 'there exist Fortran programs (at least one) to which cpp can
be applied'.  Since that's the way I use the language, I quite naturally 
assume that everyone else does too (most do).  'A Fortran program' is 
_not_ normally understood to be 'every Fortran program'.  If it were, 
I would have difficulty discussing individual programs.

J. Giles
Los Alamos

ok@quintus.uucp (Richard A. O'Keefe) (09/25/88)

In article <4092@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>When I _mean_ 'every', I _say_ 'every'.  When I say 'a', I mean 'a';

The use of articles in English is considerably more complicated than
we commonly realise.  For example:
	The native pigeon is protected.
Just one pigeon?  No, all of them.
	A mistake like this should be corrected.
Which mistake?  Any mistake like that.
	f77 compiles a Fortran program.
Just one specific program?  No, lots of them.  It is expected to compile
*every* legal Fortran program.  In a case like this, if you mean that
>'there exist Fortran programs (at least one) to which <f77> can
>be applied'
you write
	f77 compiles some Fortran programs.

	A preprocessor for Fortran given a legal input file should not
	produce incorrect output.
Which preprocessor?  Every preprocessor.
Which input files should not yield incorrect output?  Every legal one.

And in the context of a claim that a Fortran preprocessor is not needed
because cpp can be applied to "a" Fortran program, the universal reading
is forced:  if there were many Fortran programs which could not be
processed by cpp, that would not be a valid argument against having a
Fortran preprocessor.

dan@ccnysci.UUCP (Dan Schlitt) (10/15/88)

Unless my memory has completely gone, the C preprocessor knows nothing
about the C language syntax.  Proposals that would have required that it do
so were discussed heatedly during the C standardization process.  The
prevailing opinion was that the preprocessor was simply a text
processor that understands preprocessor commands like
#include
#define
#ifdef
#endif
and so on and uses them to process the text fed to it.  That the way
in which the commands function may be skewed towards the way C is
constructed should not be a suprise.  But it will do its thing on any
old text file.  Every night it does its thing on my calendar files and
I am very satisfied with the results.

Fortran folk may be astonished to learn that the preprocessor won't do
all of the C macro definitions that some people would like to do.  It
is a tool with limitations.  So don't tell me that it won't do some
fortran macro that you would like it to and conclude that it is a
useless tool for fortran.

For one, I am glad to have cpp available for all the good things that
it will do for me.  I would miss it badly if it went away.  I would
even use it with fortran.

ok@quintus.uucp (Richard A. O'Keefe) (10/16/88)

In article <925@ccnysci.UUCP> dan@ccnysci.UUCP (Dan Schlitt) writes:
>Unless my memory has completely gone, the C preprocessor knows nothing
>about the C language syntax.

It doesn't know about the _syntax_, but it for sure knows the _lexical_
rules!  As a particular example of why you need to take great care when
applying it to Fortran, "COS OF X" is a perfectly good Fortran identifier,
but you cannot
	#define COS OF X (something)
because identifiers may not contain spaces in C.  A worse problem is that
the C preprocessor doesn't understand Fortran continuation or comments.

>The prevailing opinion was that the preprocessor was simply a text processor...
No, the dpANS defines the action of the preprocessor in terms of TOKENS.
Tokens formed according to the lexical rules of C.

>So don't tell me that it won't do some
>fortran macro that you would like it to and conclude that it is a
>useless tool for fortran.

I don't think anyone here has said that it is _useless_ for Fortran.
The point is that because the dpANS C preprocessor is defined in terms
of *C* *tokens*, if you want to use it with a Fortran source you have
to ensure that your source follows the lexical rules of _both_ Fortran
and C, and you have to take special pains to ensure that the output
obeys the lexical rules of Fortran.  It is very easy to generate output
lines which are too long, for example.  A good way of combining C
preprocessing with Fortran is to use Ratfor (a public domain version
was posted to comp.sources.unix).