[comp.lang.fortran] Should I convert FORTRAN code to C?

rlr@utastro.UUCP (Randy Ricklefs) (06/06/88)

We will soon start porting software from a number of different sources to a
micro-processor-based UNIX system.  Most of the code is in various dialects
of FORTRAN.  The question that arises is whether to convert all this stuff
to a more modern language, particularly c.  This suggests several questions
which I hope the NET readers will help answer (without starting a 100-years
war on languages ... please! :-) ):

1) Are people actually initiating new projects in FORTRAN, or are they
	maintaining and porting old FORTRAN code?
2) Does the answer to 1) change if we restrict discussion to PC's & Macs?
3) Is c a suitable replacement for FORTRAN in terms of mathematical capabil-
	ities and portablility?
4) Are there reliable FORTRAN to c translators available under MS-DOS or UNIX
	that will allow moving over to c without re-coding the world?

Thanks in advance for the help!

Randy

-- 

                       Randy Ricklefs
       uucp:  {ut-sally, ut-ngp, noao, charm}!utastro!rlr
  arpa:  rlr@utastro.UTEXAS.ARPA    phone:  (512) 471-1342

jlg@beta.UUCP (Jim Giles) (06/07/88)

In article <2742@utastro.UUCP>, rlr@utastro.UUCP (Randy Ricklefs) writes:
> We will soon start porting software from a number of different sources to a
> micro-processor-based UNIX system.  Most of the code is in various dialects
> of FORTRAN.  The question that arises is whether to convert all this stuff
> to a more modern language, particularly c.  This suggests several questions
> which I hope the NET readers will help answer (without starting a 100-years
> war on languages ... please! :-) ):

C is not all that much more 'modern'.  It was developed more recently.
Fortran is a higher-level language than C (as admitted even by Ritchie).

> 1) Are people actually initiating new projects in FORTRAN, or are they
> 	maintaining and porting old FORTRAN code?

Most code (new and old) in major scientifc computing environments is
Fortran, even when C is available.  Whether this is because Fortran is
actually superior, or just programmer inertia is a qeustion that spurs
that 100-years war you complained about.

> 2) Does the answer to 1) change if we restrict discussion to PC's & Macs?

I write Fortran code for PC's.  I don't write C code for PC's.  I prefer
to write Modula-2 code for PC's.  I like writing SmallTalk code for PC's,
but the executables are too slow.  I know some people who write Fortran
exclusively - on PC's as elsewhere.

> 3) Is c a suitable replacement for FORTRAN in terms of mathematical capabil-
> 	ities and portablility?

On UNIX and UNIX-like systems, the Fortran support library is written
almost entirely in C.  The only real problem with C is the lack of the
concept of an array (such references are always turned into pointers).
This makes some (admittedly rare) constructs difficult to do in C.

> 4) Are there reliable FORTRAN to c translators available under MS-DOS or UNIX
> 	that will allow moving over to c without re-coding the world?

Depends on what you mean by 'reliable'.  If your definition doesn't
include efficiency as a requirement, there are probably some such tools.

> Thanks in advance for the help!

I'm afraid I didn't help much.  Without specifics on the purpose and
size of the code you want to move, I can't really advise you on the
desirability of converting it.  (Nor can anyone else.)

J. Giles
Los Alamos

jerry@violet.berkeley.edu ( Jerry Berkman ) (06/08/88)

In article <20008@beta.UUCP> jlg@beta.UUCP (Jim Giles) writes:
>In article <2742@utastro.UUCP>, rlr@utastro.UUCP (Randy Ricklefs) writes:
>> We will soon start porting software from a number of different sources to a
>> micro-processor-based UNIX system.  Most of the code is in various dialects
>> of FORTRAN.  The question that arises is whether to convert all this stuff
>> to a more modern language, particularly c.

>> 3) Is c a suitable replacement for FORTRAN in terms of mathematical capabil-
>> 	ities and portablility?


C is missing many useful intrinsics.  I have trouble taking a language
seriously for numeric computation if the language doesn't even know about
absolute values, e.g.:   x = abs(x);  or signed numbers,  e.g.  x = +5;
Both statements are illegal in C.  And what about:
	i = j**k
In C this becomes:
	i = pow( (double)j, (double)k);
For that matter, how do you translate  y = x**6 from FORTRAN to C?
Most FORTRAN compilers will optimize this using only 3 multiplies.
If you translate it to C as y = x*x*x*x*x*x, then there is a chance the
compiler will do as well as FORTRAN,  but I wouldn't bet on it.  And
if you use the translation y = pow(X,5.0), you have an out-of-line procedure
call plus an expensive evaluation.

Actually, C does not have a concept of intrinsic at all.  In the FORTRAN
statement:
	x = sqrt(y)
you are guaranteed by the standard that the square root intrinsic is
invoked (unless there is an external statement).  By contrast, the
C statement:
	x = sqrt(y);
does not guarantee anything of the kind.  A user defined function could
be called, or "sqrt" could be a define.  For sqrt(), this is not usually
a problem.  But I'd be a lot less sure of other names like acos or sinh.
For that matter, since sqrt() is a FORTRAN intrinsics, I get an error
message from any decent FORTRAN compiler for sqrt(integer).  None from C
of course (running lint is a hassle).

Also, I like the semantics of sqrt() under FORTRAN better:  on all
FORTRAN systems I have used, if y = -1., the result is a fatal error.
In C, it depends on what the library does.  I have used C libraries
which returned sqrt(abs(y)), others which return 0, and 4.3 BSD on a
VAX returns the reserved operand.

>On UNIX and UNIX-like systems, the Fortran support library is written
>almost entirely in C.

The 4.3 BSD math libraries for the VAX are written mostly in assembler.
That the 4.3 BSD VAX FORTRAN I/O library is written in C using standard
I/O may be why it is so slow.  The VAX math library is about as fast
as the VAX VMS math library while the BSD I/O library is up to 3 or 4
times as slow as the VAX VMS I/O library.

Much of the Cray UNICOS math and I/O support libraries are written in
assembler.

	- Jerry Berkman
	  Central Computing Services, U.C. Berkeley
	  jerry@violet.berkeley.edu

gil@limbic.UUCP (Gil Kloepfer Jr.) (06/08/88)

In article <2742@utastro.UUCP> rlr@utastro.UUCP (Randy Ricklefs) writes:
|>We will soon start porting software from a number of different sources to a
|>micro-processor-based UNIX system.  Most of the code is in various dialects
|>of FORTRAN.  The question that arises is whether to convert all this stuff
|>to a more modern language, particularly c.  This suggests several questions
|>which I hope the NET readers will help answer (without starting a 100-years
|>war on languages ... please! :-) ):

No problem...I hate those wars myself (being a fan of both languages!).

|>1) Are people actually initiating new projects in FORTRAN, or are they
|>	maintaining and porting old FORTRAN code?

Both.  There are still a number of research groups who are solve mathematical
problems in FORTRAN (simply because it's all they know).  This code is many
times proprietary, and the authors simply do not care to let anyone port the
existing code.

There are also a LOT of statistical (again mathematical) and graphics software
in FORTRAN which is so large that it would be a great expense to port.  It is
therefore maintained (ported if the need is there).

|>2) Does the answer to 1) change if we restrict discussion to PC's & Macs?

Yes and no.  It all depends on cost, although personally I would look more
towards porting if I had the PC/Mac marketplace in mind.

|>3) Is c a suitable replacement for FORTRAN in terms of mathematical capabil-
|>	ities and portablility?

C can do almost anything.  The question is with how much trouble.  FORTRAN,
in my book, handles mathematical stuff MUCH easier and clearly than C.
As stated in a past net-debate (no flames please if it is slightly out of
context), C lacks some of the array flexibility that FORTRAN has (although
with FORTRAN, you need to know how big the arrays are, with C you can
allocate memory at run-time).

Once you have successfully ported a FORTRAN-based mathematical procedure to
C, you can rest assured that the program is pretty-much portable (I am at
a loss for a system it wouldn't be portable to).

|>4) Are there reliable FORTRAN to c translators available under MS-DOS or UNIX
|>	that will allow moving over to c without re-coding the world?

I have heard of some, but I haven't used any and don't know how well they
work.

|>Thanks in advance for the help!

You're welcome.

NOTE:  The final decision on which language to use for your application
should not rest on which is more "modern."  There are FORTRAN compilers
for almost every computer in existance nowadays.  Whether you code in C
or FORTRAN should rest in the application and what it does.  Further, the
conversion costs should be considered as well as portability when making
the decision to convert.  Standard (F77) FORTRAN that isn't I/O intensive
will generally compile and run on any machine with the same compiler.  There
are people that still develop FORTRAN-based applications, but the number
is decreasing because much of the mathematical stuff can be "black-boxed"
(and possibly just that module written in FORTRAN), while the rest of the
system (including file handling and user-interface) can be more easily (and
elegantly) written in C.

|>  Randy Ricklefs  uucp:  {ut-sally, ut-ngp, noao, charm}!utastro!rlr
|>  arpa:  rlr@utastro.UTEXAS.ARPA    phone:  (512) 471-1342

+------------------------------------+----------------------------------------+
| Gil Kloepfer, Jr.                  | Net-Address:                           |
| ICUS Computer Group, Systems Dvlp. | {boulder,ihnp4,talcott}!icus!limbic!gil|
| P.O. Box 1                         | Voice-net: (516) 968-6860              |
| Islip Terrace, New York  11752     | Othernet: limbic!gil@icus.UUCP         |
+------------------------------------+----------------------------------------+

grimlok@hubcap.UUCP (Mike Percy) (06/08/88)

From article <10655@agate.BERKELEY.EDU>, by jerry@violet.berkeley.edu ( Jerry Berkman ):
> 
> C is missing many useful intrinsics.  I have trouble taking a language
> seriously for numeric computation if the language doesn't even know about
> absolute values, e.g.:   x = abs(x);  or signed numbers,  e.g.  x = +5;


  x =+ 5 used to be an example of a C operator which is now x += 5. Most
compilers I've used warned me about an obsolete operator or some such. 
Just write is as x = +5 rather than x =+5 and things should be fine.

x = abs(x) is provided by virtually every math library.

> For that matter, how do you translate  y = x**6 from FORTRAN to C?

For that matter, how do you translate *p %= 2 from C to FORTRAN?

> For that matter, since sqrt() is a FORTRAN intrinsics, I get an error
> message from any decent FORTRAN compiler for sqrt(integer).  None from C
> of course (running lint is a hassle).

"Gosh Dad, why do those airline pilots have to run through that
checklist, it's such a hassle"
"Well, Beaver, if they didn't, they might miss some small detail that
could cause a crash"
"Geeee"

> 
> Also, I like the semantics of sqrt() under FORTRAN better:  on all
> FORTRAN systems I have used, if y = -1., the result is a fatal error.
> In C, it depends on what the library does.  I have used C libraries
> which returned sqrt(abs(y)), others which return 0, and 4.3 BSD on a
> VAX returns the reserved operand.
> 

Which is why you have the freedom to decide exactly what you want by
redefining the function slightly, maybe with a #define.

Also, if you like FORTRAN math stuff, why not call functions from a
FORTRAN library. NAG comes to mind. It's easy enough to do.

FORTAN does have an extreme advantage over C in one respect --
vectorizability (is that a word?) of certain things (some array
processing for example). If I remember right, this was one of the things
that noalias was supposed to help change.

eric@snark.UUCP (Eric S. Raymond) (06/08/88)

In article <2742@utastro.uucp>, rlr@utastro.UUCP (Randy Ricklefs) writes:
> 1) Are people actually initiating new projects in FORTRAN, or are they
> 	maintaining and porting old FORTRAN code?

New projects are still being initiated in FORTRAN. Lots of old FORTRAN code
is still being maintained, too -- FORTRAN is still the computer lingua franca
of the engineering and scientific world.

> 2) Does the answer to 1) change if we restrict discussion to PC's & Macs?

I am not aware of a FORTRAN for the Mac. Good FORTRANs do exist for the PC/PS
machines (but beware of Microsoft's, which is said to be slow and buggy!).
Sorry for not giving references, but it's been many years since I hacked
FORTRAN myself.

> 3) Is c a suitable replacement for FORTRAN in terms of mathematical capabil-
> 	ities and portablility?

Pre-ANSI C wasn't, quite -- the promote-everything-to-double lossage in K&R
and lack of complex-number support caused problems. ANSI C solves the first
problem, and C++ the second. A perhaps more serious problem is the lack of a
C-portable equivalent of LINPACK (though the UNIX C math libraries cover a 
fair amount of ground).

> 4) Are there reliable FORTRAN to c translators available under MS-DOS or UNIX
> 	that will allow moving over to c without re-coding the world?

I have seen ads for FORTRAN to K&R-C translators. I expect FORTRAN
to C++ translaters with COMPLEX-to-complex mapping will be along any month
now if they're not already here.

Despite problems pointed out under 3), C has gained a lot of ground at former
FORTRAN strongholds during the last five years; it is much easier to code in
and maintain. The rise of UNIX has of course helped it.

Assuming you decide to convert -- *don't* try converting by hand! Assuming you
can get a translator, be aware that none of them are perfect and expect the odd
bug or two to turn up post-translation.

I guess I can sum up my gut feel about the change best with a pair of lists:

Indications *for* switching to C:
   1. Your FORTRAN code base is relatively small (so you don't need the next
five years to satisfy yourself that the translator code did a correct job!).
   2. Your applications have a long expected lifetime.
   3. The code needs to be extended and modified on a continuing basis.
   4. The application wants to run on UNIX or MS-DOS boxes (for the forseeable
future, the best compiler technology is going to go first into C on these).

Indications *against* switching to C:
   1. Translator-introduced bugs (that might be *very* subtle!) could kill
people.
   2. Your applications use COMPLEX (some translators may not handle this).
   3. Your applications use LINPACK or other math functions not available in
the C/UNIX world.
   4. Your application uses EQUIVALENCE or COMMON in weird untranslatable ways.
   5. Your installation is dominated by FORTRAN-head engineer/scientist types
who would be reduced to a pathetic state of confusion by the change.

You *must* budget time for a post-conversion desk check of the generated C!
Lint the whole thing at absolute minimum. If floating-point computation is
involved, have a numerical analyst scan for hotspots.

I hope your circumstances are such that you can attempt this. I'm speaking
only from theory and comparative knowledge of the two languages; I'd really
like to see a how-we-did posting from a shop that actually took the plunge.
-- 
      Eric S. Raymond                     (the mad mastermind of TMN-Netnews)
      UUCP: {{uunet,rutgers,ihnp4}!cbmvax,rutgers!vu-vlsi,att}!snark!eric
      Post: 22 South Warren Avenue, Malvern, PA 19355   Phone: (215)-296-5718

eugene@pioneer.arpa (Eugene N. Miya) (06/09/88)

I have been asked to post this.  Please send mail to him, not me.
Thanks.

--eugene

============mesg start===============

Some flames for thought ...

I agree that Fortran is a somewhat primitive language and that a
better language for scientific programming would be nice.  I see two
issues in making transition to something better.  The first is the
choosing of a suitable replacement language.  The second is that of
translating Fortran Dusty Decks.


1.  Choice of Language

I do lots of programming in both C and Fortran.  I think C is not the
answer.  It's too low level.  Multidimensioned arrays in C are hard to
implement well and in a way that will be portable.  One person's idea
of how to implement multidimesioned arrays will differ from another's.
Now try to write code that will handle both!  YECH!

Fortran 8X is not the answer.  It's a "dirty" language (to put it
mildly).  This is my personal debatable opinion.  The approch by the
committee here seems to be "let's add stuff we think is neat and hope
over the next 20 years that people decide on their own that they
shouldn't use things like COMMON, EQUIVALENCE, and column oriented
format." I don't see much chance of success in this approach.

OK, How about Ada?  I am _very_ new to this language but it seems to
be able to handle much of what one might desire for scientific
programming.  Code writtin in Ada has a good chance of being portable.
The problem with this language seems to be its complexity.  It won't
run nicely on a small (PC class) machine.  I wonder whether a possible
solution to this problem is to define a sublanguage of Ada for
scientific computation.  That is, maybe some features could be removed
to make the language run on small machines and still be nice for
scientific computation.  Will removing the task handling and exception
handling fix the complexity problem?


2.  Tranlation

What are the problem areas of tranlation of Fortran into other (more
sane) languages (e.g., C, pascal, Ada)?  A few problem areas I see are

	a.  multidimensioned arrays.  Fortran code is _often_ optimized
	    to account for Fortran's columnwise storage of 2-D arrays.
	    Pascal (and Ada, I assume) store rowwise.

	b.  EQUIVALENCE

	c.  COMMON

Any more here?

Matt Wette
mwette%gauss@hub.ucsb.edu

jerry@violet.berkeley.edu ( Jerry Berkman ) (06/09/88)

This message is a reply to three of the people who commented on my previous
message.

wan@cory.Berkeley.EDU (Hank S. Wan) wants a FORTRAN type checker:

> if FORTRAN is so great as in all the "RE: Should I convert FORTRAN code to C"
> somebody must have a type checker so the following is not merrily accepted
> by unix f77.
> 
> 	PROGRAM bar
> 	    j = sub1( i )
> 	    PRINT *, i, j
> 	END
> 	SUBROUTINE sub1( r )
> 	    r = 1.0
> 	END
> 
> lint would do the job for c code.  (and NO, lint is not a hassle if you're
> smart enough to use it often, and interpret the results right.)
> Checking consistency in type is useful for any large project in any serious
> language.

Here is what IBM's VS FORTRAN, version 2, release 2 says about your sample
program, when the ICA option is specified:

	VS FORTRAN VERSION 2 ENTERED.  13:04:37
	
	**BAR** END OF COMPILATION 1 ******
	
	**SUB1** END OF COMPILATION 2 ******
	
	(W) CONFLICTING NAME USAGE -- THE NAME, SUB1, HAS BEEN REFERENCED AS A
	FUNCTION IN BAR(COMPILATION 1). IT IS DEFINED AS A SUBROUTINE IN
	SUB1(COMPILATION 2).
	
	(W) CONFLICTING TYPE - AT THE MAIN ENTRY TO SUBROUTINE, SUB1(COMPILATION
	2), ARGUMENT NO. 1, "R", IS EXPECTED TO BE REAL*4; HOWEVER,
	BAR(COMPILATION 1), AT ISN 2 PASSES THIS ARGUMENT, "I", AS INTEGER*4.
	
	VS FORTRAN VERSION 2 EXITED.   13:04:40

Sorry, but it's not public domain.  By the way, when you are asking for a
type checker, you are commented on the implementation, not the language.
If you want complete checking, try WATFOR77, which check not only for
argument agreement, but also check subscripts, and for variables used
before they are defined.  Is there any C equivalent?

swarbric@tramp.Colorado.EDU (Frank Swarbrick) comments:

> To Jerry Berkman,
>   Gee, I just tried compiling x = +5; and x = abs(x); both in C and they both
> worked.

I just tried both on monet.berkeley.edu, where the most current distributed
4.3 BSD UNIX lives.  The C compiler, given the program:

	main()
	{
	int i;

	i = +5;

	}

comments:

	"junk.c", line 5: syntax error

It may very well work in other compilers, and will probably be added in
the new standard, but is not there now.

> (Now I don't know why anyone would ever use x = +5, but I guess
> that is not the point.)
It could be output from a program which generates source code, or a
person just likes symmetry.  It does not seem unreasonable to ask a
compiler to correctly compile it.

As for "x = abs(x);", it does compile and load.
However, it's calling a library function.  What's wrong with that?
(1) It's slow.
(2) It returns the absolute value of integers.  You can type it "float abs();"
    and it works on the VAX, but it may not work on all systems.
The FORTRAN generic abs() which works on any numeric data type and
generates in-line code is superior.

grimlok@hubcap.UUCP (Mike Percy) says:
>>> Also, I like the semantics of sqrt() under FORTRAN better:  on all
>> FORTRAN systems I have used, if y = -1., the result is a fatal error.
>> In C, it depends on what the library does.  I have used C libraries
>> which returned sqrt(abs(y)), others which return 0, and 4.3 BSD on a
>> VAX returns the reserved operand.
>Which is why you have the freedom to decide exactly what you want by
>redefining the function slightly, maybe with a #define.

This makes it an act of faith in reading large programs as to what
procedure calls do.  I prefer intrinsics for common functions.

	- Jerry Berkman, U.C. Berkeley Computing Services
	  jerry@violet.berkeley.edu

gwyn@brl-smoke.ARPA (Doug Gwyn ) (06/09/88)

The original poster was wondering if he should convert Fortran code
to C.  My answer to that is, not if you can get an adequate Fortran
compiler for your system.  If you think it would be useful, there is
at least one automatic Fortran-to-C translator commercially available
(Fortrix).  If you plan to thoroughly revise your application (so that
it amounts to a rewrite), you would be better off designing the
replacement from scratch, and it might make sense to implement the
replacement in C if you're not going to be dependent on EISPACK, IMSL,
etc.

Fortran's single biggest problem is that it has shitty support for
data structures.  If this doesn't bother you, then by all means
continue to use Fortran.  I think by now everyone who is likely to
learn better techniques would have done so.

It happens that many of our more interesting applications are
primarily written in C, because Fortran is just too puny.  And we
do run them on our Crays as well as on small and medium sized
systems.  I find that with sufficient care, useful C code can be
even more portable than Fortran, more efficient, and more
maintainable.  Of course with insufficient care, horrible code
can be produced in ANY language.

Use whatever tool seems right for the job and that you are
comfortable using.

owen@wrs.UUCP (Owen DeLong) (06/09/88)

In article <2742@utastro.UUCP> rlr@utastro.UUCP (Randy Ricklefs) writes:
>We will soon start porting software from a number of different sources to a
>micro-processor-based UNIX system.  Most of the code is in various dialects
>of FORTRAN.  The question that arises is whether to convert all this stuff
>to a more modern language, particularly c.  This suggests several questions
>which I hope the NET readers will help answer (without starting a 100-years
>war on languages ... please! :-) ):

Ahh, Why not?  Language wars are so much fun.... You get to tie up so many
peoples telebits with such garbage, and everyone can flame you... :-)

>1) Are people actually initiating new projects in FORTRAN, or are they
>	maintaining and porting old FORTRAN code?

Some, but that's just because they haven't ported their programmers to c yet.

>2) Does the answer to 1) change if we restrict discussion to PC's & Macs?

Yes, more Mac and PC programmers have been ported to c than in the system 3
environment.  (What, you mean someone besides IBM makes computers? :-)

>3) Is c a suitable replacement for FORTRAN in terms of mathematical capabil-
>	ities and portablility?

Absolutely not, for this, you need COBOL! :-)... Seriously, I wouldn't wish
COBOL on my worst enemy.

>4) Are there reliable FORTRAN to c translators available under MS-DOS or UNIX
>	that will allow moving over to c without re-coding the world?

I haven't seen anything.  There was a review of FORTRAN to LISP converters in
Computer Language once, I think, and the author there basically said he hadn't
seen any inter-language translator he found to be reliable.

>
>Thanks in advance for the help!
>
>Randy
>

I hope some of this is helpful, but I couldn't resist the opportunity to poke
fun at a language that should have died before assembly was born.

Owen

Disclaimer:  WRS won't give me execute access to cc yet.

swarbric@tramp.Colorado.EDU (Frank Swarbrick) (06/09/88)

To Matt Wette,

   Am I totally missing something, or is this not a multidimentional array:
int array[10][15];
??

Certainly there are different ways of accessing them (as an array, as points,
or both at the same time), but they are all portable.  If I have greatly
misunderstood something I'm sure I will get many corrections.

Frank Swarbrick (and, yes, the net.cat)           swarbric@tramp.Colorado.EDU
...!{ncar|nbires}!boulder!tramp!swarbric
"...This spells out freedom, it means nothing to me, as long as there's a PMRC"

swarbric@tramp.Colorado.EDU (Frank Swarbrick) (06/09/88)

(I am really wondering if this belongs in comp.lang.fortran at all, but I am
not sure if Jerry Berkman reads comp.lang.c.  Sorry.)

Anyway, just because your outdated compiler doesn't compile x = +5 means only
that your compiler is outdated...  Or maybe even buggy, as it should not really
think it means x =+ 5.  And indeed, it doesn't, as it gave you a syntax error
instead of a warning saying you never initialized x.  Or maybe C used to not
accept this format; I don't know.

Anyway, I'm not disagreeing that it's good that FORTRAN can generate differnt
things for x = abs(x) depending on whether or not x is float, int, or whatever.
It's just in C the compiler does not know what a function looks like.  They
are just black boxes with a few restrictions.  C was made this way for a
reason, and I like it.  FORTRAN is different for a reason, and that's fine
too.

(Oh, by the way, if x is float or double use x = fabs(x);)

Frank Swarbrick (and, yes, the net.cat)           swarbric@tramp.Colorado.EDU
...!{ncar|nbires}!boulder!tramp!swarbric
"...This spells out freedom, it means nothing to me, as long as there's a PMRC"

cjl@ecsvax.UUCP (Charles Lord) (06/09/88)

In article <22ad4e5b!4683@snark.UUCP>, eric@snark.UUCP (Eric S. Raymond) writes:
> I am not aware of a FORTRAN for the Mac. Good FORTRANs do exist for the PC/PS
> machines (but beware of Microsoft's, which is said to be slow and buggy!).

Since when? perhaps you are confusing MS Fortran with MSC.

I have used MS Fortran from 3.2 to 4.1 and have had
little to no trouble.  No ad, just a satisfied customer.

Charles Lord
cjl@ecsvax.UUCP

walter@garth.UUCP (Walter Bays) (06/10/88)

jlg@beta.UUCP (Jim Giles) writes:
>Most code (new and old) in major scientific computing environments is
>Fortran, even when C is available.  Whether this is because Fortran is
>actually superior, or just programmer inertia is a question that spurs
>that 100-years war you complained about.

paolucci@snll-arpagw.UUCP (Sam Paolucci) writes:
>Ah!  Most major scientific computing environment use CRAYs as their
>CPU.  Do you know of a good C compiler on the CRAY that produces code
>of somewhat comparable performance as CRAY's Fortran compilers?
>There, I suggest, is part of the answer.

   I would venture that most C compilers have not produced code that is as
   fast as most Fortran compilers.  And even as the computer industry
   continues doubling hardware performance, scientists like Jim Giles
   immediately use the new power by expanding the range of problems
   studied - and ask for more.  Software efficiency will always be
   important to them.

jlg@beta.UUCP (Jim Giles) writes:
>Here you are putting the cart before the horse.  There was no C compiler
>for Crays until recently because there was no demand for it.  The present
>demand is almost entirely from within Cray and from other (non-scientific)
>Cray customers.  Again, whether this is from inertia or valid preference
>is a combative issue.

   A chicken and egg problem.  IF excellent C compilers had been
   available, would they have used them?  Probably so.  IF user demand had
   been present, would Cray (and others) have provided C compilers as fast
   as the best Fortran compilers?  Probably not.

   C provides lower level primitives which a programmer can use to write
   fast code.  So the worst C compilers are better than the worst Fortran
   compilers.  But C's liberal assumptions about memory volatility and
   aliasing have interfered with many optimizations that are fairly easy
   to do on Fortran.  So the best Fortran compilers are better than the
   best C compilers.
   
   Hence we have ANSI C and the battles over volatile (in the language)
   and noalias (rejected).  Chris Torek captured the essence of the
   'volatile' debate in many dozens of notes.  If you personally have no
   use for 'volatile', but would like to see C displace Fortran (perhaps
   to protect yourself from having to use Fortran :-), read Chris' entire
   note.

chris@mimsy.UUCP (Chris Torek) writes (Subject: volatile: a summary):
>Is the [volatile] keyword necessary?
>No.  (As an existence proof, consider compilers that do not now have
>the keyword.  Most of them work by not doing much in the way of
>optimisation.  There is more to it, though.)
>    Summary of the summary:
>Is the concept necessary?	Yes.
>Is the keyword necessary?	No.
>Is the keyword useful?		Yes.
>Is the keyword a `good thing'?	Opinion: yes.

jlg@beta.UUCP (Jim Giles) continues:
>I use Fortran mostly because I know how to use it WELL.  To some
>extent, the lack of detailed knowledge of C is my reason for not using
>it. (For example: why is 'a+=b' faster than 'a=a+b'?  Seems to me that
>the two are identical and should generate the exact same code.)  ...

   If you're a Fortran programmer and have not tried C because you KNOW
   its' too slow, look again.  Many C compilers have been getting much
   better, even before ANSI.  Any good compiler will generate the same
   code for those constructs.  There's a lot of folk wisdom about how to
   get around the pcc code generator and write fast C code.  (Absolutely
   essential to such things as writing systems code.) Unfortunately, much
   of this wisdom is counter-productive today, because it obfuscates the
   code and interferes with the work of the optimizer.  (Example:
   indiscriminate 'register' declarations steal from the compiler's pool
   of allocatable registers.)

swarbric@tramp.Colorado.EDU (Frank Swarbrick) writes:
>As for C not generating inline code for stuff like x = pow(x, 2); that is
>just not "C's way."  It has been discussed a lot in comp.lang.c.  Some people
>think C should generate inline code for it, and some do not.  So far, it
>doesn't.

   C compilers are starting to do more procedure inlining.  The widespread
   use of the Dhrystone benchmark has accelerated this trend, since
   inlining strcpy() and strcmp() produce much higher Dhrystone numbers.
   (The Dhrystone rules forbid inlining, but many people only care that
   the program executes correctly - and don't care what the compiler
   does.)

   On some RISC CPU's (not ours) multiplication is a procedure call that
   is sometimes inlined.  Who cares?  That affects performance, certainly,
   but the bottom line of performance is all that matters.

jlg@beta.UUCP (Jim Giles) provides an appropriate postscript:
>Fortran does some things better, C does others, and both contain deficiencies.
-- 
------------------------------------------------------------------------------
I said it, not them.
E-Mail route: ...!pyramid!garth!walter		(415) 852-2384
USPS: Intergraph APD, 2400 Geng Road, Palo Alto, California 94303
------------------------------------------------------------------------------

mat@emcard.UUCP (Mat Waites) (06/10/88)

In article <6551@sigi.Colorado.EDU> swarbric@tramp.Colorado.EDU (Frank Swarbrick) writes:
>
>   Am I totally missing something, or is this not a multidimentional array:
>int array[10][15];
>??

I think the problem is with variable size
multidimensional arrays.

It's hard(er) to write functions in C to handle
multidimensional arrays of varying size.

People have come up with wacky techniques for doing it, but
if there is no standard way, it's difficult to use in
standard libraries, etc.


Mat

-- 
  W Mat Waites                     |  PHONE:  (404) 727-7197
  Emory Univ Cardiac Data Bank     |  UUCP:   ...!gatech!emcard!mat
  Atlanta, GA 30322                |

platt@emory.uucp (Dan Platt) (06/10/88)

In article <5241@ecsvax.UUCP> cjl@ecsvax.UUCP (Charles Lord) writes:
>In article <22ad4e5b!4683@snark.UUCP>,eric@snark.UUCP(Eric S. Raymond) writes:
>> I am not aware of a FORTRAN for the Mac. Good FORTRANs do exist for the PC/PS
>> machines (but beware of Microsoft's, which is said to be slow and buggy!).
>
>Since when? perhaps you are confusing MS Fortran with MSC.
>
>I have used MS Fortran from 3.2 to 4.1 and have had
>little to no trouble.  No ad, just a satisfied customer.
>
>Charles Lord
>cjl@ecsvax.UUCP


Actually, I've been quite impressed with the MS Fortran 4.10.  It has a few bugs
(I found one -- there are probably more), but I'm more tolerant of these than
some people are (judging by the flames that  some people have generated and
pointed at microsoft).  The products MS Fortran and MS C are very similar in
quality, speed of compilation and speed of executable code.  The code is 
quite fast for MS Fortran (it beat out MSC and Turbo C for some numerical
procedures that I benchmarked),  and all of these were much faster than
the previous generation of products available for PC/s. 

But not to stray too far from the course, I feel that:

1) the issue is subjective to some extent (hence the lead in "I feel").
	How well do you like fortran?  How well do you like C?  How
	well do the people you work with like Fortran and C?

2) Objective criterea would include:

	a)  How well are the various languages supported in your environment? 
		Does your system have a good C compiler that generates
		fast reliable code?  Does it have good system support 
		(libraries &c)?  If you are doing PC work, there are good
		cheap C compilers that give you a great deal of control over
		your system resources at efficiencies that would have been
		nice some years ago.

	b) How well does your environment support fortran?  In some cases, the
		fortran support is inferior to that provided for C.  In some
		cases, such as IBM 370's, CRAY's, Cybers &c, the Fortran
		compiler will be the best choice.

	c) Who will be using the code?  If it is engineers who are doing and
		have been doing mainly number crunching work, with little or
		no nead for dynamic data structure manipulation, then Fortran
		might be better, and if these people don't know C, it may be
		best to work in fortran --- save lots of lost time and money.
 
There is lots of research being initiated in fortran and work being ported in
fortran --- often dictated by criterea defined in 1, 2b, and 2c.  The work
I've been doing has included both fortran and C coding -- depending on the
application and environment I'm working on --- some of it being duplicated
for various reasons in both languages.

I believe there's room for both languages, and use both.  The rest depends
on the above criterea.

Dan Platt

bobal@microsoft.UUCP (Bob Allison) (06/10/88)

In article <2742@utastro.UUCP> rlr@utastro.UUCP (Randy Ricklefs) writes:
>1) Are people actually initiating new projects in FORTRAN, or are they
>	maintaining and porting old FORTRAN code?
>2) Does the answer to 1) change if we restrict discussion to PC's & Macs?

  I'd say that on PCs most of the stuff going on is porting.  But that is
  because there is a lot of stuff on mainframes which people want to run
  on PCs and are finally getting the horsepower to do.  I was actually 
  surprised by how much new development is going on.

>3) Is c a suitable replacement for FORTRAN in terms of mathematical capabil-
>	ities and portablility?

  Plenty of other postings arguing this issue.  I will just toss in my
  opinion that you'll almost always get better execution time on a FORTRAN
  program than a comparable C program (see my next posting).

>4) Are there reliable FORTRAN to c translators available under MS-DOS or UNIX
>	that will allow moving over to c without re-coding the world?
>

  I've seen some ads in typical PC magazines.  Buy a few and take a look.
  But be skeptical: call them up, ask them hard questions.  Most of them
  will require at least some user intervention.  Almost all of them generate
  crummy source, which you practically have to rewrite before you can do
  any serious maintenance.  Be prepared to do some debugging.  

  All of this boils down to: how much are you willing to invest to move
  to a "modern" language?  Is execution speed important?  What are the
  real reasons for switching?  Are you going to have to maintain this
  later?  Try to figure out the economics of the effort, then decide.
  How much time/effort/money are you going to save down the road by 
  investing a bunch of it now? It might be better to spend the time 
  doing something else.

>Thanks in advance for the help!
>

  We're always willing to offer opinions when it isn't our project :-)

bobal@microsoft.UUCP (Bob Allison) (06/10/88)

>In article <2960@emory.uucp> platt@emory.UUCP (Dan Platt) writes:
>>In article <5241@ecsvax.UUCP> cjl@ecsvax.UUCP (Charles Lord) writes:
>>
>>[responding to gripe, says nice stuff about MS Fortran]
>
>Actually, I've been quite impressed with the MS Fortran 4.10. It has a few bugs
>(I found one -- there are probably more), but I'm more tolerant of these than
>some people are (judging by the flames that  some people have generated and
>pointed at microsoft).  The products MS Fortran and MS C are very similar in
>quality, speed of compilation and speed of executable code.  The code is 
>quite fast for MS Fortran (it beat out MSC and Turbo C for some numerical
>procedures that I benchmarked),  and all of these were much faster than
>the previous generation of products available for PC/s. 
>
>But not to stray too far from the course...
>	[a good description of criteria for selection of FORTRAN deleted]
>
>I believe there's room for both languages, and use both.  The rest depends
>on the above criterea.
>
>Dan Platt

Well, this isn't exactly an ad either, but I am the Lead for MS FORTRAN now.
I have three basic comments:

1)  It's nice to hear good things every now and then (let's not fill the
    net with endorsements or flames: I just wanted to say I appreciate it).

2)  (This isn't directed at you, Don)
    I've been reading the net for at least two years and I hear a
    lot of people who find bugs in products.  As a developer, nothing is
    more frustrating than hearing vague rumors of bugs, but never getting
    any solid evidence of such.  Please, please, pretty please, take the
    effort to slog your way through whatever customer service is available
    for whatever product and try to report the bug.  You're probably 
    helping someone else, maybe helping yourself, and you give us job 
    security (developers are often the worst about this).

3)  MS FORTRAN and MS C use the same back end.  This means that there are
    very few optimizations which one compiler performs that the other does
    not (none that I know of).  Yet, Don says that FORTRAN sometimes ran 
    faster than C.  I've worked at other companies with similar compiler 
    technology and I have found this to be the case for many benchmarks.  
    We all know why, too.  FORTRAN has a lot of problems, but it has a 
    couple of advantages which are what has kept it around for so long 
    and this is clearly one of them.

PS: About porting FORTRAN code to C: one of the most obnoxious features
    of the port is that all REAL arguments become DOUBLE PRECISION (C 
    always passes double).  It doesn't hurt the answer, it just slows 
    things down a WHOLE BUNCH on a lot of machines.

Bob Allison
(I got a bunch of positive response about X3J3 stuff, so I'll keep it up)

karl@haddock.ISC.COM (Karl Heuer) (06/11/88)

In article <10681@agate.BERKELEY.EDU> jerry@violet.berkeley.edu (Jerry Berkman) writes:
>By the way, when you are asking for a type checker, you are commented on the
>implementation, not the language.

I'm glad you were the one to bring that up.  Many of the issues you raise are
not intrinsic to the language, either.

>If you want complete checking, try WATFOR77, which check not only for
>argument agreement, but also check subscripts, and for variables used
>before they are defined.  Is there any C equivalent?

Yes, it's my understanding that some implementations of C have this.  I
haven't used them (though I've often threatened to write one).  Certainly the
language doesn't forbid it.

>As for "x = abs(x);", it does compile and load.
>However, it's calling a library function [which is slow].

That's an implementation issue.  The better C compilers generate inline code.

>(2) It returns the absolute value of integers [only].

The floating-point version is named fabs().  If you want to argue whether a
single generic name is better than a family of typed functions, fine; but I
think that the issue you raised (existence) is closed.

>grimlok@hubcap.UUCP (Mike Percy) says [about the semantics of sqrt(-1.0)]
>>Which is why you have the freedom to decide exactly what you want by
>>redefining the function slightly, maybe with a #define.
>
>This makes it an act of faith in reading large programs as to what
>procedure calls do.  I prefer intrinsics for common functions.

Mike Percy has fallen victim to a common misconception.  The user does not
have the guaranteed freedom to redefine standard functions.  (It may happen to
work; this is also true in FORTRAN.)  The standard functions in C are quite
analogous to the intrinsics of FORTRAN.  (Note: "analogous" does not mean
"identical".)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

karl@haddock.ISC.COM (Karl Heuer) (06/11/88)

I really don't want to continue this cross-posted discussion, but I'd like to
comment on the multi-dimensional array issues.

In article <10032@ames.arc.nasa.gov> mwette%gauss@hub.ucsb.edu (Matt Wette) writes:
>Multidimensioned arrays in C are hard to implement well and in a way that
>will be portable.

Since we're talking about FORTRAN conversion, the straightforward solution is
to use the array notation supplied by the C language: "float a[3][5]".  The
only major problem is that FORTRAN allows an array parameter to be declared
with a nonconstant dimension; to render the equivalent code in C (unless you
have Gnu's gcc) requires explicit subscript calculation.  (This is no less
efficient than in FORTRAN, but it is tedious to write.  A macro can be
helpful.)

>Fortran code is _often_ optimized to account for Fortran's columnwise storage
>of 2-D arrays.  Pascal (and Ada, I assume) store rowwise.

No problem.  You translate the FORTRAN expression A(J,I) into the C expression
a[i][j], or its Pascal or Ada equivalent.  (This is assuming your translator
knows which parens are arrays rather than function calls.)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

smryan@garth.UUCP (Steven Ryan) (06/11/88)

Another big problem is that Fortran programs run like a bat out of hell with a
good compiler. It is hard to convince people to give up the performance for
(?)ephermal advantages of maintainablity.

shenkin@cubsun.BIO.COLUMBIA.EDU (Peter Shenkin) (06/13/88)

In article<10032@ames.arc.nasa.gov> eugene@pioneer.UUCP (Eugene N. Miya) writes:
>
>I have been asked to post this.  Please send mail to him, not me.
[ note:  "him" is:
    Matt Wette
    mwette%gauss@hub.ucsb.edu
]
>                                                     ...I see two
>issues in making transition to something better.  The first is the
>choosing of a suitable replacement language.  The second is that of
>translating Fortran Dusty Decks.
>
>1.  Choice of Language
>
>                           Multidimensioned arrays in C are hard to
>implement well and in a way that will be portable.  One person's idea
>of how to implement multidimesioned arrays will differ from another's.
>Now try to write code that will handle both!  YECH!

Just on this issue, I wonder what other numerikers in the audience think
of Press et al's solution to this problem, given in "Numerical Recipes in
C", Wiley, 1988.  To make a long story short, they supply a routine:

    float **matrix( int nrl, int nrh, int ncl, int nch )

which uses dope vectors to dynamically allocate a 2-dimensional array of floats
with range [nrl...nrh][ncl...nch].  They also supply similar routines
for double-precision and integer matrices (called dmatrix() and imatrix() ),
and the corresponding "free" routines.  They do a similar thing for
vectors, and obviously an extension of this approach using varargs
-- or whatever the hell it's called in the draft ANSI standard :-) --
could easily be accomplished for arbitrary dimensionality.

This is, in Matt's words, just "one person's idea of how to implement
multidimensioned arrays", but it seems like a reasonable one.  The reason
for raising this issue here on the net is simply that if we who do write
numerical code in C (for better or for worse!) were to standardize on
this practice, we could better understand each others' code (or at least
this part of it!)

For the record, this generalizes to the following:

	float **array( int Ndim, 
	  int n1l, int n1h, int n2l, int n2h, ..., int nNl, int nNh )
	  /* allocate an N-dimensional array of floats with range
	   *   [n1l, n1h][n2l,n2h]...[nNl,nNh]
	   */
	void free_array( float **ar, int Ndim,
	  int n1l, int n1h, int n2l, int n2h, ..., int nNl, int nNh )
	  /* free array allocated with array() */

Then we also would have the following routines:
	int **iarray()     /* allocate an N-dimensional array of ints....  */
	double **darray()  /* allocate an N-dimensional array of doubles....  */
and the corresponding free routines.

Of course, we could then have:

#define vector( NL,NH )              array( 1, (NL), (NH) )
#define matrix( NRL,NRH,NCL,NCH )    array( 2, (NRL), (NRH), (NCL), (NCH) )

and perhaps even (for "real" C programmers):

#define vector0( N )              array( 1, 0, (N) )
#define matrix0( NR,NC )          array( 2, 0, (NR), 0, (NC) )

...and so on.  All presumably in some header file with a name like "arrays.h".

Any thought on this?

("Numerical analysts of the world, unite....")
-- 
*******************************************************************************
Peter S. Shenkin,    Department of Biological Sciences,    Columbia University,
New York, NY   10027         Tel: (212) 280-5517 (work);  (212) 829-5363 (home)
shenkin@cubsun.bio.columbia.edu    shenkin%cubsun.bio.columbia.edu@cuvma.BITNET

greg@csanta.UUCP (Greg Comeau) (06/13/88)

>>   Gee, I just tried compiling x = +5; it worked.
>	i = +5;
>comments:
>	"junk.c", line 5: syntax error
>It may very well work in other compilers, and will probably be added in
>the new standard, but is not there now.

If an old compiler accepts this it is probably just being lazy for some reason.
Since C does not have a unary plus, it should be a syntax error.  Note that
the ANSI draft does allow a unary plus now though since "hey, there's a unary
minus so let's at least be consistent".  Also, at one time ANSI did apply
a binding characteristic to the unary plus applied to parenthised expression
(say: a + +(b + c) if I recall), but that has since been withdrawn.

kjartan@raunvis.UUCP (Kjartan Pierre Emilsson Jardedlisfraedi) (06/13/88)

  Now here there seems to be a little misunderstanding.  I have never
understood why Fortran users keep saying that array indexing is awkward
in C.  This is probably because they find the idea of having to allocate
memory for an array rather repulsive.  I  remember that when I made
the change from Fortran to C, I thought that the memory allocation
routine malloc() was only intended for compiler designers and other
computer wizards.  But one quickly finds out that allocating memory
for whatever you are doing is not only simple but also helps you a lot
in keeping the whole program under control, since you have to have in 
mind a clear image of all your variables.
  For people that frequently use the same sort of data structures, e.g
two dimensional double precision array, it is a simple task to write
a little subroutine wich handles the allocation. For this particuliar
data structure, the subroutine is basically a one-liner:

double **Create2DArray(w,h)
int w,h;{ double **r;
for(r=(double**)calloc(h,sizeof(*r));h-->0;r[h]=(double*)calloc(w,sizeof(**r)));
return(r);}

  This may look very cryptic but then you only write it once anyway! A small
extension of the routine above could handle multidimensional array of
arbitrary dimensions and arbitrary data structures.
  

  If the array had been initialized with Create2DArray() then indexing
would be just as normal,i.e:

		DoSomething(array,m,n)
		double **array;
		int m,n;
		{
		...
		array[ i+k ][ j-i ]= 1.0;
		...
		}

 More generally: if an array is initialized with arbitrary dimensions, its
indexing is exactly as in FORTRAN, and can be passed to functions in exactly
the same manner (that is by pointers, which in this case is simply the array
name).

 I personally made the change from FORTRAN to C one year ago, and today I
do not regret it , though there came times when I wanted to do some really
mean things to that stupid computer.  I haven't  completely given up 
FORTRAN though, as there are still many libraries in FORTRAN around here, but I
simply build jacket routines for them (i.e routines which interface calling
conventions of two different languages) with the JBL utility. In that way
I don't have to write anything in FORTRAN but I still can use all the
available FORTRAN subroutines. Knowing that FORTRAN calls everything by
reference and C calls everything by value, it is easy to pass the arguments
from the C program in such a way that the only interfacing you need to do is
converting the pre-underscored C routine function name to the upper-case
FORTRAN name.

  I think that the C offers two qualities that makes it a very comfortable
scientific programming language:

		i) Argument are passed by value, which translates to
		   the fact that to let a subroutine change a variable
		   you have to specify it (by passing its adress).  This 
		   makes subroutines more like real mathematical operators
		   which have a very definite input and a very definite
		   output. This is really a psychological quality, but I
		   think that it has its effect in organizing your program
		   (a What You Get Is What You Asked For quality).

	       ii) You can define your own data structures, which can be any
		   combination of system defined structures and user defined
		   structures, array of structures, self-referential
		   structures and so on. This I think is perhaps the most
		   interesting quality and probably anyone who has done some
		   mathematics will appreciate the fact that most complex
		   problems can be made simpler by a suitable change of
		   formalism which most often is a change of data structure
		   with accompagnment of new operators acting on these
		   structures. For example if you are working in
		   4-dimensional space you simply define the data structure
		   4-vector and then proceed to write the basic operators
		   that you are going to need (DotProduct(vector1,vector2)
		   ,Add(vector1,vector2),Scale(scalar,vector), and so on).
		    Quickly you will see that your program is talking the
		    same mathematical language as you are, and program
		    writing then becomes a real FORmula TRANslation!

  This is not meant as an artillery in the Language Wars, but rather as an
explanation and maybe a clarification for those who haven't had any special
experience with C ,and still think that indexing doesn't exist in C and that
C is bad because it doesn't have the complex data type!

	Say it in any language you like, but say it clearly!


...........................................................................    

    "If you don't like what your left hemisphere thinks, shoot if off."

			Kjartan Pierre Emilsson, Iceland.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

hirchert@uxe.cso.uiuc.edu (06/14/88)

FORTRAN remains the preeminent language for numerical (esp. scientific and
engineering) computing for a number of reasons:
o Inertia
  - Much scientific and engineering computing is based on earlier work.  If
    that earlier work is in FORTRAN (and the odds are that it is), then it is
    usually easier to continue working in FORTRAN than to switch to another
    language.  [This effect may be reduced somewhat if automatic language
    conversion programs become both more reliable and more widely available.
    However, unless someone figures out how to translate the comments from
    describing the source language to describing the result language, there
    will always be some barrier here to language switching.]
  - Many of the people doing scientific and engineering computing are
    professional scientists and engineers and only part-time programmers.
    Since programming is not their business, they are far more likely to be
    proficient in only a single language, so even when projects are started
    from scratch, they are far more likely to use the language that they are
    already using when building on existing work - FORTRAN.  [This effect may
    be reduced as more and more colleges and universities teach languages other
    than FORTRAN to their science and engineering students.  On the other hand,
    if one's only exposure to a language is a few class problems, one may still
    feel uncomfortable using that language for "serious" computing.]
o FORTRAN is, in a number of ways, a superior language for many kinds of 
  numeric computing.
  - Features
    . FORTRAN includes a number of features that many more "modern" language
      make you build yourself from more basic features.  The classic example
      is the COMPLEX data type.  A less appreciated example is FORTRAN formatted
      input/output.  If you are reading and writing the classic tables of
      numbers and labeling information, it is a substantially more compact and
      more convenient tool than what is offered in most more "modern" languages.
      (Of course, if you want to some other kind of textual input/output, it
      can be a major pain.)  [In theory, the "modern" languages could match
      this power with library procedures of comparable power.  In practice, the
      portable routines tend to make FORTRAN input/output look fast and the
      fast routines tend not to be portable.  The development of standards, so
      the fast routines are all written to the same specification, would help
      here.]
    . The FORTRAN programmer usually has access to a much wider selection of
      "canned" numerical software than the programmer in other languages.
      (This is an outgrowth of the inertia factor.)  [Automatic translators
      can help with this problem when source code is available.  Mixed language
      programming environments can make irrelevant the issue of what language
      was used to code your "canned" software.  Unfortunately, the way two
      languages interact seems to vary significantly from environment to
      environment, so mixed language software tends to be less portable than
      software written in a single language.  This is another area where the
      development of standards might eventually reduce FORTRAN's advantage.]
  - FORTRAN compilers tend to produce faster code.
    . Historically, vendors have put more effort into optimizing FORTRAN than
      other languages.  (Inertia again.)  [This effect is slowly being reduced
      by an increased demand for optimizing compilers for other languages and
      by the increased use of techniques such as common compiler back-ends to
      facilitate meeting these demands.]
    . FORTRAN is inherently more optimizable (using today's compiler
      technology) than most more "modern" languages.  FORTRAN is close enough
      to the machine to avoid the problem of being forced to do extensive
      analysis/optimization just to produce reasonable code, but far enough
      removed from the machine to allow the application of such analysis/
      optimization to produce signficant improvements.  In particular, where
      other languages frequently insist on complete and orthogonal definitions,
      FORTRAN will disallow unusual (and unlikely) combinations of features if
      this will allow significant improvements in the generated code.  The 
      classic (and single most important) example of this are the restrictions
      in FORTRAN concerning the use of the same or overlapping actual arguments
      corresponding to the dummy arguments of a procedure.  These restrictions
      allow a wide range of optimizations, from removal of loop invariants and
      recognition of common subexpressions to vectorization, to be applied to
      dummy arguments in the same way they are applied to ordinary variables.
      [This inherent advantage may not always be realized.  If a vendor uses
      a common compiler back-end, he may forego these optimizations in order
      simplify its use.  Alternatively, he may provide for compiler directives
      that allow the programmer in a more "modern" language to explicitly
      assert the restrictions implicit in FORTRAN.  (As I understand it, that's
      what the ANSI C noalias controversy was all about.)]

From my point of view, all of the above suggests that FORTRAN will be around
for some time to come.  On the other hand, the factors I mention in my bracketed
comments will tend to reduce FORTRAN's advantages, FORTRAN is most definitely
not without its deficiencies:
o FORTRAN's memory management is inadequate for many of todays problems.
o The array is not sufficient as the primary data organizing facility.
  (Structured data types would provide assistance in expressing fixed relations
  between non-heterogenous data.  Pointers, or something with equivalent
  semantic power, would provide assistance in expressing more dynamic or less
  uniform relations.)
o As typical portability requirements expand from porting programs from unlike
  systems on a one-shot basis to running programs under continuing development
  on several systems simultaneously (e.g. doing test runs on a workstation and
  production runs on a supercomputer), FORTRAN needs to provide more 
  assistance in writing portable code.  A classic problem in this area is
  switching between the use of REAL and DOUBLE PRECISION, including the related
  problems of switching constants and name management for libraries offering
  both REAL and DOUBLE PRECISION versions of routines.
o As the exploitation of parallelism becomes increasingly important in high-end
  computing, more powerful notation for expressing this parallelism becomes
  highly desirable.

In the long run, the extent to which FORTRAN continues to be used may depend
on what is produced as a result of the Fortran 8x effort.  If that result
retains FORTRAN's current strengths and remedies its most pressing deficiencies,
then it seems likely that Fortran will remain the preeminent numerical
computing language.  If the Fortran 8x process fails to produce a new standard
or produces one which is so tied to existing practice that it fails to address
FORTRAN's more pressing deficiencies, then a slow (but accelerating) decline
seems likely.  My guess as the most probable successor would be C.  It has
some serious problems as a numerical computation language, but the ANSI C
committee seems willing to address the extensions and changes necessary to
remedy these problems.

(Just so no one misinterprets what I'm saying:  When I suggest the possibility
of a decline in the use of FORTRAN, I'm not talking about something that will
happen in the next year or two or even in the next 5 to 10 years.  The factors
cited at the beginning of this posting are too significant.  A significant
decline, if it occurs, may well take place over a period of time comparable to
the time it took us to get where we are now, and FORTRAN is more than 30 years
old!)

Kurt W. Hirchert     hirchert@ncsa.uiuc.edu
National Center for Supercomputing Applications

henry@utzoo.uucp (Henry Spencer) (06/15/88)

> C is missing many useful intrinsics.  I have trouble taking a language
> seriously for numeric computation if the language doesn't even know about
> absolute values, e.g.:   x = abs(x);  or signed numbers,  e.g.  x = +5;
> Both statements are illegal in C.

Curious, my compiler compiles the first one just fine :-).  The second
is admittedly a bit of a nuisance, but hardly a disaster.  In any case
X3J11 has fixed both:  abs is one of the potentially-intrinsic functions
defined in the standard, and unary plus is provided.

> [Much moaning and groaning about the lack of exponentiation, an operator
> whose general case is (a) notoriously hard to define well, and (b) very
> seldom used.]

> Actually, C does not have a concept of intrinsic at all.

X3J11 (ANSI-to-be) C does.

>  (running lint is a hassle).

Ah, we come to the heart of it:  the man wants to convert to C without
having to learn anything new, go to any trouble, or buy modern compilers.
My nose bleeds for him.
-- 
Man is the best computer we can      |  Henry Spencer @ U of Toronto Zoology
put aboard a spacecraft. --Von Braun | {ihnp4,decvax,uunet!mnetor}!utzoo!henry

chpf127@ut-emx.UUCP (J. Eaton) (06/17/88)

In article <224@raunvis.UUCP>, kjartan@raunvis.UUCP (Kjartan Pierre Emilsson Jardedlisfraedi) writes:
> 
> [stuff deleted about dynamic memory allocation]
>
>                                 For this particuliar
> data structure, the subroutine is basically a one-liner:
> 
> double **Create2DArray(w,h)
> int w,h;{ double **r;
> for(r=(double**)calloc(h,sizeof(*r));h-->0;r[h]=(double*)calloc(w,sizeof(**r)));
> return(r);}
> 
>   This may look very cryptic but then you only write it once anyway!

    Yes, perhaps, but you (and, most likely, someone else) will have
    to read it more than once.  Will that future reader be able to
    quickly grasp what is being done (especially if that future
    person is a scientific "programmer")?

> 	Say it in any language you like, but say it clearly!

    I agree.

 
> 			Kjartan Pierre Emilsson, Iceland.


    J. Eaton
    UT Dept of Chemical Engineering

    Practice what you preach.

chpf127@ut-emx.UUCP (J. Eaton) (06/17/88)

In article <224@raunvis.UUCP>, kjartan@raunvis.UUCP (Kjartan Pierre Emilsson Jardedlisfraedi) writes:
> 
>  I personally made the change from FORTRAN to C one year ago, and today I
> do not regret it , though there came times when I wanted to do some really
> mean things to that stupid computer.

   I don't understand this idea of refusing to write code in more than 
   one language.  Why not write in whatever language is most convenient
   for the job at hand?  I use mostly Fortran because there are a lot
   of numercial libraries available that I simply don't care to rewrite
   or translate to another language.  However, I don't object to C or
   any other language (except BASIC :-) if it fits the requirements of
   the job...

>                                           I haven't  completely given up 
> FORTRAN though, as there are still many libraries in FORTRAN around here, but
> I simply build jacket routines for them (i.e routines which interface calling
> conventions of two different languages) with the JBL utility. In that way
> I don't have to write anything in FORTRAN but I still can use all the
> available FORTRAN subroutines. Knowing that FORTRAN calls everything by
> reference and C calls everything by value, it is easy to pass the arguments
> from the C program in such a way that the only interfacing you need to do is
> converting the pre-underscored C routine function name to the upper-case
> FORTRAN name.

   But I DO object to this.  At the present time, multilanguage programming
   is NOT a good idea.  AVOID it if at all possible.  It makes porting
   to new environments especially difficult, if not impossible in many
   cases.  Fortran may not be your favorite, and C isn't perfect either,
   but mixing the two is bound to cause trouble for you or someone else
   in the future.  The whole world is not VM/CMS, COS, NOS/VE, VMS, or
   even 4.3 BSD.  Moving a program which contains only Fortran or only
   C from any one of those environments to another is hard enough.
   Don't make it any more difficult by mixing in a load of interface
   routines which are system dependent!  This will make moving your
   code to new machines/operating systems such a pain in the ass that
   very few will even give it a second thought.

   Of course, if you really want your code to die with the machine it was
   written for, disregard the above.

> 	Say it in any language you like, but say it clearly!

   I still agree, just say it in one at a time.
 
> 			Kjartan Pierre Emilsson, Iceland.


   J. Eaton
   UT Dept of Chemical Engineering

   And old machines really do die.  Just ask any old CDC 6600.  What?
   You're still using one?  Oh.  Sorry.  Maybe machines ARE forever.

bobal@microsoft.UUCP (Bob Allison) (06/17/88)

In article <50500055@uxe.cso.uiuc.edu> hirchert@uxe.cso.uiuc.edu writes:
>
>
>FORTRAN remains the preeminent language for numerical (esp. scientific and
>engineering) computing for a number of reasons:
>
> [a very complete, fairly concise, excellent description of FORTRAN's
>  strengths and weaknesses]
>
>Kurt W. Hirchert     hirchert@ncsa.uiuc.edu
>National Center for Supercomputing Applications

You know, I read this article and was actually envious.  Here is someone
who writes a crisp, clean, definitive, informative, objective,
technically sound article.  I wondered what would happen if I could 
write articles like this.  I wondered what would happen if the whole net
started writing articles like this.  Then I saw it was Kurt, and I thought
"Oh, of course".  For Kurt is intelligent, informative, and rational:
truly a gentleman and a scholar.  

In short: that was a really good article.  Thanks.

P.S.  Now, don't you wish you hadn't skipped that article? :-).

Bob Allison
(If we could only find someone who knew about all the FORTRAN to C
translators who would write a similar article for us)

firth@sei.cmu.edu (Robert Firth) (06/17/88)

The following code, contributed by a C programmer, allocates dynamic
memory for a two-dimensional array:

>                                 For this particuliar
> data structure, the subroutine is basically a one-liner:
> 
> double **Create2DArray(w,h)
> int w,h;{ double **r;
> for(r=(double**)calloc(h,sizeof(*r));h-->0;r[h]=(double*)calloc(w,sizeof(**r)));
> return(r);}

Any Fortran programmer who seriously proposes to convert to C would, in
my opinion, be advised to study this example very carefully.  Verbum
sapienta sufficit.

jlg@beta.lanl.gov (Jim Giles) (06/18/88)

In article <224@raunvis.UUCP>, kjartan@raunvis.UUCP (Kjartan Pierre Emilsson Jardedlisfraedi) writes:
>   Now here there seems to be a little misunderstanding.  I have never
> understood why Fortran users keep saying that array indexing is awkward
> in C.
> [...]

Awkward isn't the problem.  I don't like the double bracket notation,
but anyone can write a macro to turn ARRAY(i,j,k) into array[i][j][k].
The Problem is that 2-d arrays are not optimizable because they are
immediately turned into pointer-to-pointer-to-data type of constructs.

>   If the array had been initialized with Create2DArray() then indexing
> would be just as normal,i.e:
> 
> 		DoSomething(array,m,n)
> 		double **array;
> 		int m,n;
> 		{
> 		...
> 		array[ i+k ][ j-i ]= 1.0;
> 		...
> 		}

If your use of array here is in a loop (that might otherwise be vector-
izable), the C compiler can't vectorize it because a pointer-to-pointer
'may' contain a vector dependency - the compiler doesn't know it's a
2-d array!  (If you don't have a vector machine, the problem still exists,
you can't unroll the loop for a pipelined archetecture because of the
same possible dependency.)  This problem is the reason that so much
discussion on this news group has recently been about 'noalias' in C (not
exactly an appropriate topic for comp.lang.fortran, but relevent to this
particular issue anyway).

> [...]
> 	       ii) You can define your own data structures, which can be any
> 		   combination of system defined structures and user defined
> 		   structures, array of structures, self-referential
>                  structures and so on. [...]

This capability is NOT an adequate replacement for the complex data type.
Complex is more than just a pair of reals, there are several operations
defined on complex (like plus) which should work naturally.  No use of
C programming constructs can do this:

      COMPLEX CVAR
      REAL RVAR
      INTEGER IVAR
      ...
      CVAR=(CVAR+RVAR)*IVAR
      ...
The operations (including the mixed-mode type conversions) are all done
IN-LINE and efficiently.  C provides no way to even do this calculation
without function calls.

>   This is not meant as an artillery in the Language Wars, but rather as an
> explanation and maybe a clarification for those who haven't had any special
> experience with C ,and still think that indexing doesn't exist in C and that
> C is bad because it doesn't have the complex data type!

Clarifications which contain false or misleading information don't
clarify anything.  In fact, such 'clarifications' DO add to the
Language Wars in very unproductive ways.

J. Giles
Los Alamos

smryan@garth.UUCP (Steven Ryan) (06/18/88)

First of all I agree with Dijkstra with respect to Fortran. I feel the
challenge designing a new language that can be Fortran at its own game,
which C does not do.

>  Now here there seems to be a little misunderstanding.  I have never
>understood why Fortran users keep saying that array indexing is awkward
>in C.  This is probably because they find the idea of having to allocate
>memory for an array rather repulsive.

A Fortran compiler is permitted to allocate all arrays statically, before
compilation, and many do this. Also Fortran subroutine are not required to
be recursive and hence do not need a procedure frame. All allocation can be
done in the compiler and the runtime overhead can be zero.

Also it is easy for programmer to modify the array base address to implement
nonzero lower bounds. It is also easy for the compiler. I suspect Fortran
programmers know alot less about dope vectors biased base addresses and that
ilk than C programmers (scientists and engineers vs. computer science and
system programmers).

>		i) Argument are passed by value, which translates to
>		   the fact that to let a subroutine change a variable
>		   you have to specify it (by passing its adress).

And simplifies defined/referenced detection for an optimiser.

>	       ii) You can define your own data structures,

Apparently some Fortran programmers equivalence different typed arrays to
create structures (shudder).

    Nature is immacuately fair and implacably cruel -- Sara James.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (06/18/88)

In article <5917@aw.sei.cmu.edu> firth@bd.sei.cmu.edu.UUCP (Robert Firth) writes:
>Any Fortran programmer who seriously proposes to convert to C would, in
>my opinion, be advised to study this example very carefully.

They would be much better off studying literate code.

rrr@naucse.UUCP (Bob Rose ) (06/20/88)

In article <20340@beta.lanl.gov>, jlg@beta.lanl.gov (Jim Giles) writes:
> In article <224@raunvis.UUCP>, kjartan@raunvis.UUCP (Kjartan Pierre Emilsson Jardedlisfraedi) writes:
> >   Now here there seems to be a little misunderstanding.  I have never
> > understood why Fortran users keep saying that array indexing is awkward
> > in C.
> > [...]
> 
> Awkward isn't the problem.  I don't like the double bracket notation,
> but anyone can write a macro to turn ARRAY(i,j,k) into array[i][j][k].
> The Problem is that 2-d arrays are not optimizable because they are
> immediately turned into pointer-to-pointer-to-data type of constructs.

Ok, what gives. Some else post the following code (not exact but close enough)

	real a(5,2)
	...
	call foo(a)
	...
	end

	subroutine foo(a)
	real a(10)
	...

Now doesn't the following c code work to do the same

	double a[2][5]        /* <-- note [2][5] not [5][2] */
	...
	foo(a)
	...
	}

	void foo(a)
	double a[10]
	{

If it is not the same, would someone please post or email a counter
example. I would like to see what is wrong.

Note there are problems if you dynamicly allocate arrays but you cannot
dynamicly allocate arrays in fortran so this is a void arguement.

                               -bob

g-rh@cca.CCA.COM (Richard Harter) (06/20/88)

In article <738@naucse.UUCP> rrr@naucse.UUCP (Bob Rose ) writes:
>In article <20340@beta.lanl.gov>, jlg@beta.lanl.gov (Jim Giles) writes:

>> Awkward isn't the problem.  I don't like the double bracket notation,
>> but anyone can write a macro to turn ARRAY(i,j,k) into array[i][j][k].
>> The Problem is that 2-d arrays are not optimizable because they are
>> immediately turned into pointer-to-pointer-to-data type of constructs.

>Ok, what gives. Some else post the following code (not exact but close enough)
>
>	real a(5,2)
>	...
>	call foo(a)
>	...
>	end
>
>	subroutine foo(a)
>	real a(10)
>	...

	My example, but this isn't the right context.  This code was
posted in response to someone proposing a macro which would produce
the following C code:

	double **a;
	a = (double **)malloc(2 * sizeof(double *));
	for (i=0;i<2;i++) a[i] = (double *)malloc(5 *sizeof(double));

which is not the same thing at all as your example.  However the quoted
statement is not, as far as I know, correct.  Two dimensional arrays in
C are not pointer to array constructs.

>Now doesn't the following c code work to do the same

>	double a[2][5]        /* <-- note [2][5] not [5][2] */
>	...
>	foo(a)
>	...
>	}
>
>	void foo(a)
>	double a[10]
>	{

	Yes, it does.  However in fortran you can do the following

	real a(10)
	...
	call foo(a,2,5)
	call foo(a,5,2)
	...
	subroutine foo(a,m,n)
	real a(m,n)
	...

This is what fortran users mean when they talk about variable dimensioning;
all it really means is that the compiler will generate address calculations
for arrays using variables as well as constants.  You can do this by hand,
but it is much more convenient if the compiler will do it for you.  As far
as I know, there is no good reason why this feature could not be added to
C.  The discussion revolves around ways to fake it in C, using preprocessor
tricks.  They all look kludgy to me.

>Note there are problems if you dynamicly allocate arrays but you cannot
>dynamicly allocate arrays in fortran so this is a void arguement.

	This is not quite right, but it is close enough for practical
purposes.  The correct statements are:

(1)	Does the language provide intrinsic dynamic storage allocation.
Answer:  Intrinsic dynamic storage allocation is not a part of either language.

(2)	Does the standard support environment include a dynamic storage
allocator?  Answer:  C does, fortran doesn't.

(3)	Given a dynamic storage allocator, does the language permit use of
it?	Answer:  The C language provides a convenient portable means for
doing so.  It can be done in fortran, but the means are not as convenient
and cannot be guaranteed to be portable.
-- 

In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
	Richard Harter, SMDS  Inc.

mouse@mcgill-vision.UUCP (der Mouse) (06/20/88)

In article <10655@agate.BERKELEY.EDU>, jerry@violet.berkeley.edu ( Jerry Berkman ) writes:
>> [C vs FORTRAN]

> C is missing many useful intrinsics.  I have trouble taking a
> language seriously for numeric computation if the language doesn't
> even know about absolute values, e.g.:   x = abs(x);  or signed
> numbers,  e.g.  x = +5;  Both statements are illegal in C.

Not so.  The first one is perfectly legal; any compiler that won't
accept it is broken.  The second one is legal under the dpANS (or at
least in K&R V2), though it used to be illegal.  (Why do we need a
unary plus operator anyway?  I never missed it.)

> [ i = j**k   and   y = x**6 ]

How do you express link->next->chain = vec[i++]; in FORTRAN?  Why try
to create a war of features?  It sounds as though your sort of work is
better expressed in FORTRAN.  Please stick to FORTRAN, then, and stop
complaining about C.  You aren't complaining about how Snobol makes it
difficult and slow to do what you want to do, are you?

> Actually, C does not have a concept of intrinsic at all.

It does under the dpANS, or very close to it.  If we say, for example,

#include <math.h>

 x = sqrt(y);

then we are justified in believing the sqrt() routine to be the math
library routine.

> For that matter, since sqrt() is a FORTRAN intrinsics, I get an error
> message from any decent FORTRAN compiler for sqrt(integer).  None
> from C of course (running lint is a hassle).

In other words, you recognize that you have such a checking feature
available, but using it is too much trouble, so you complain about the
lack of checking.  Riiight.  (I certainly can't see the hassle in
running lint; just say "lint" instead of "cc"....)

					der Mouse

			uucp: mouse@mcgill-vision.uucp
			arpa: mouse@larry.mcrcim.mcgill.edu

mouse@mcgill-vision.UUCP (der Mouse) (06/20/88)

In article <10681@agate.BERKELEY.EDU>, jerry@violet.berkeley.edu ( Jerry Berkman ) writes:
> As for "x = abs(x);", it does compile and load.

> However, it's calling a library function.  What's wrong with that?
> (1) It's slow.
> (2) It returns the absolute value of integers.  You can type it
>     "float abs();" and it works on the VAX, but it may not work on
>     all systems.

Doesn't work on our VAX.  Your VAX must be using a different
floating-point format from the one in the VAX architecture manual.

I tried compiling and running this:

float abs();
main()
{
 printf("%g\n",abs(123.456));
 printf("%g\n",abs(-123.456));
}

and it gave me

-0.00210706
0.00210706

Of course, maybe you think that's what it means for it to work on the
VAX....but I daresay most people would disagree.

(You could also break down and use fabs, the floating-point absolute
value routine - or is that cheating?)

					der Mouse

			uucp: mouse@mcgill-vision.uucp
			arpa: mouse@larry.mcrcim.mcgill.edu

rrr@naucse.UUCP (Bob Rose ) (06/21/88)

In article <29697@cca.CCA.COM>, g-rh@cca.CCA.COM (Richard Harter) writes:
> In article <738@naucse.UUCP> rrr@naucse.UUCP (Bob Rose ) writes:
> >Ok, what gives. Some else post the following code (not exact but close enough)
> > [Some fortran code and the C equivalent]
> 
> 	Yes, it does.  However in fortran you can do the following
> 
> 	real a(10)
> 	...
> 	call foo(a,2,5)
> 	call foo(a,5,2)
> 	...
> 	subroutine foo(a,m,n)
> 	real a(m,n)
> 	...
> 
> This is what fortran users mean when they talk about variable dimensioning;
> all it really means is that the compiler will generate address calculations
> for arrays using variables as well as constants.  You can do this by hand,
> but it is much more convenient if the compiler will do it for you.  As far
> as I know, there is no good reason why this feature could not be added to
> C.  The discussion revolves around ways to fake it in C, using preprocessor
> tricks.  They all look kludgy to me.
                         ^^^^^^

Here is the equivalent C code (right?)

	double a[10]
	...
	foo(a,2,5)
	foo(a,5,2)
	...

	#undef a
	void foo(a,m,n)
	double a[]
	#define a(x,y)     a[(x)*n+(y)]  /* works with ansi-c */
	int m,n;
	{
	...
	a(p,q) = ...                     /* same syntax as fortran, golly gee */

Yes, it is kludgy, but it does work.
Sooo, the question again is is there any fortran constructs that cannot
be translated into fortran through a brute force kludge. You know,
something that a well trained ape couldn't do. I would like to see it.
Please no complex numbers, these well just be function call (and if
you are worried about speed, get a compiler that well do inline function
calls.)
                                 -bob


-

jlg@beta.lanl.gov (Jim Giles) (06/21/88)

In article <1171@mcgill-vision.UUCP>, mouse@mcgill-vision.UUCP (der Mouse) writes:
> [...]                                            (Why do we need a
> unary plus operator anyway?  I never missed it.)

The proposed ANSI standard for C has unary plus operators.  Among other
uses, it can force ordering of expression evaluation.  The famous case
where C doesn't evaluate a+(b+c) in any particular order is fixed by
doing a+ +(b+c).  The unary plus forces the subexpression to be eval-
uated before adding the other constant.

> [...]                         It sounds as though your sort of work is
> better expressed in FORTRAN.  Please stick to FORTRAN, then, and stop
> complaining about C.  You aren't complaining about how Snobol makes it
> difficult and slow to do what you want to do, are you?
> 
This is exactly the point of previous responses.  There really are things
This is exactly the point of previous responses.  There really are things
which are best done in Fortran.  The points raised about C in this
discussion are reasons for not switching.  No one is complaining about
C in isolation, these are legitimate answers to the original posting
about the desirability of switching to C.  As such, discussion of the
inadequacies of C for certain types of work are quite appropriate.

J. Giles
Los Alamos

leo@philmds.UUCP (Leo de Wit) (06/21/88)

In article <20340@beta.lanl.gov> jlg@beta.lanl.gov (Jim Giles) writes:
>In article <224@raunvis.UUCP>, kjartan@raunvis.UUCP (Kjartan Pierre Emilsson Jardedlisfraedi) writes:
>>   Now here there seems to be a little misunderstanding.  I have never
>> understood why Fortran users keep saying that array indexing is awkward
>> in C.
>> [...]
>
>Awkward isn't the problem.  I don't like the double bracket notation,
>but anyone can write a macro to turn ARRAY(i,j,k) into array[i][j][k].

Matter of style. I don't like seeing an identifier that could be both
an array and a function call (oh yeah, Fortran uses CALL in front of it 8-).

>The Problem is that 2-d arrays are not optimizable because they are
>immediately turned into pointer-to-pointer-to-data type of constructs.

Depends on how you implement them.

>
>>   If the array had been initialized with Create2DArray() then indexing
>> would be just as normal,i.e:
>> 
>> 		DoSomething(array,m,n)
>> 		double **array;
>> 		int m,n;
>> 		{
>> 		...
>> 		array[ i+k ][ j-i ]= 1.0;
>> 		...
>> 		}
>
>If your use of array here is in a loop (that might otherwise be vector-
>izable), the C compiler can't vectorize it because a pointer-to-pointer
   [stuff about vectorizing deleted]...

So I suggest another alternative for Create2DArray():
double **Create2DArray(w,h)
int w,h;
{
    double **r, **a;

    for (a = calloc(w * h, sizeof(**r)), r = calloc(h,sizeof(*r));
         --h >= 0;
         r[h] = a + w * h;
    return r;
}

This has two advantages: only 2 calls to calloc needed (while the
original needed h + 1), and furthermore the data itself is contiguous
in memory (pointed to by r[0]). Furthermore you can have both the speed
of vectored arrays and flat ones (whatever is more appropriate).
Another remark: perhaps it's better to replace the second calloc by a
malloc, since the contents of r[h] is changed anyway. And you can
combine the two allocations into one, as The Walking Lint pointed out.
If you're out for speed, use flat arrays and pointers into these.

>
>> [...]
>> 	       ii) You can define your own data structures, which can be any
>> 		   combination of system defined structures and user defined
>> 		   structures, array of structures, self-referential
>>                  structures and so on. [...]
>
>This capability is NOT an adequate replacement for the complex data type.
>Complex is more than just a pair of reals, there are several operations
>defined on complex (like plus) which should work naturally.  No use of
>C programming constructs can do this:
>
>      COMPLEX CVAR
>      REAL RVAR
>      INTEGER IVAR
>      ...
>      CVAR=(CVAR+RVAR)*IVAR
>      ...
>The operations (including the mixed-mode type conversions) are all done
>IN-LINE and efficiently.  C provides no way to even do this calculation
>without function calls.

This is simply not true. Even if the C compiler cannot generate inline code
it is perfectly possible to use macro's to achieve the speed that FORTRAN
boasts of (and I think even more than that). For instance:

typedef struct {
   double c_re, c_im;
} complex;

#define C_MULT(p,q,r) \
    ((r).c_re = ((p).c_re + (q).c_re, (r).c_im = (p).c_im + (q).c_im)

    complex z1, z2, result;

    /* ------- */

    C_MULT(z1,z2,result);

You can have even macro's for functions on complex numbers, and even
the best Fortran compiler cannot forsee to implement all user functions
inline (in fact I think only a very limited number of functions are
supported).  The only drawback of the macro approach is that most
people don't like the splitting up of expressions into these elementary
ones (if C had structure assignment and runtime declarators also this
problem was solved).

But I think Fortran would get into trouble if you had to work with
quaternion calculations, e.g. Nice as it is to have predefined types
and operations, it is even nicer to support creating you own types.
What if you want to describe distributions in your data model? C offers
a much cleaner approach. Pure number crunching: ok, Fortran. But
compiler building? Databases? Operating systems? Juicy, juicy (You see:
use C ;-). If I want speed, I'd better have no Fortranquilizers 8-).

   Leo.

bobal@microsoft.UUCP (Bob Allison) (06/22/88)

In article <741@naucse.UUCP> rrr@naucse.UUCP (Bob Rose ) writes:
>Sooo, the question again is is there any fortran constructs that cannot
>be translated into fortran through a brute force kludge. You know,
>something that a well trained ape couldn't do. I would like to see it.
>Please no complex numbers, these well just be function call (and if
>you are worried about speed, get a compiler that well do inline function
>calls.)
>                                 -bob

Much as I hate to get embroiled in this my-language-can-do-anything-your-
language-can-do-better issue, reading this article I did manage to come
up with a feature which is fairly difficult to implement in C: assigned
gotos.  I don't believe C can take the address of a label, which is the
way a "well-trained ape" would do it.  Otherwise, you could (I suppose)
assign each label as it appears a monotonically ascending number and then
in place of the "ASSIGN 10 TO L" statement, assign the assigned number of
the label to L, then in place of the "GOTO L" statement do a case statement
and branch to the appropriate label based on the value in L.  Frankly, this
stinks.  

This is clearly a contrived example (I'm not suggesting we all use FORTRAN
so we can do assigned GOTOs), but I think that it is obvious that there are
things which C can do easily which FORTRAN can't and things which FORTRAN
can do easily which C can't, and let's just live with it.  (I love it,
soon we'll be having lawsuits about discrimination and equal opportunity 
for programming languages).

A very sensible comment:
>	Offhand, my feeling is that I wouldn't use any of these schemes.
>C isn't fortran and vice versa.  C doesn't allow 
>
>	foo(m,n,a)
>		int m,n;
>		double a[m][n];
>	{....}
>
>and that's the way it is.  Cute tricks to simulate this just make the
>code obscure.  
>
>	Richard Harter, SMDS  Inc.

Of course, it is just as easy to construct a C program which is difficult
to write in FORTRAN.

Bob Allison
(It seems this debate comes up every six months. The basic response is
"Who cares?  Let people use whatever language they like.  It's their life."
Why do even mundane things like programming language selection need to be
turned into religious issues?)

leo@philmds.UUCP (Leo de Wit) (06/26/88)

In article <750@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:
>First of all I agree with Dijkstra with respect to Fortran. I feel the
>challenge designing a new language that can be Fortran at its own game,
>which C does not do.

So what IS FORTRAN's game?

> [stuff deleted]...
>A Fortran compiler is permitted to allocate all arrays statically, before
>compilation, and many do this. Also Fortran subroutine are not required to
>be recursive and hence do not need a procedure frame. All allocation can be
>done in the compiler and the runtime overhead can be zero.

A few remarks:
A C programmer can CHOOSE (note: uppercase 8-) whether he wants arrays
to be global, static or automatic. This means that the runtime overhead
can be at least as little as that of a FORTRAN program (zero overhead is
rubbish; you always have to page or swap the data in, whether you use data
/heap space or stack space, or you at least have to claim core).
Furthermore you make it sound as if it was a merit when functions
cannot be recursive (are not required to..); procedure frame are more
or less for compiler builders: you can do without them, making it much
harder for yourself (most procedure frames can be build and broken down
with a single, fast instruction; this goes also for pushing/popping
sets of registers). If you can design a function in which the system
spends significant time doing call, return, push, pop, link, unlink
there must be very little code inside that function (try a macro; no,
I do not mean an assembler! 8-). Dropping off these things (call, push ..)
can only gain a few percent, at what other cost (inflexible subroutine
scheme, permanent variables)? You can even totally rule out any use of
subroutines if you're out for speed: large monolotic blocks with many
pieces of repeated code, is that desirable?

The scope of local variables can be more restricted than in FORTRAN if you
wish so (yes, for auto AND for static vars); more like Algol block-bound.

>Also it is easy for programmer to modify the array base address to implement
>nonzero lower bounds. It is also easy for the compiler. I suspect Fortran
>programmers know alot less about dope vectors biased base addresses and that
>ilk than C programmers (scientists and engineers vs. computer science and
>system programmers).

The trouble here is obviously that scientists want their problem to map
too literally onto the notation and possibilities of a computer
language.  Strange, because C you have to learn only once (that is,
twice if that is not the proposed ANSI draft standard), scientific
notations may change all the time. Knowing how to work with pointers
can improve on speed considerably.

>
>>	       ii) You can define your own data structures,
>
>Apparently some Fortran programmers equivalence different typed arrays to
>create structures (shudder).

Now this one I cannot grasp (English not being my native language); what do
you mean by this sentence (what are the predicate and the subject) ?
Can you give an equivalence 8-) ?

    Leo.

mouse@mcgill-vision.UUCP (der Mouse) (06/26/88)

In article <20340@beta.lanl.gov>, jlg@beta.lanl.gov (Jim Giles) writes:
> In article <224@raunvis.UUCP>, kjartan@raunvis.UUCP (Kjartan Pierre Emilsson Jardedlisfraedi) writes:
>> [...]
> The Problem is that 2-d arrays are not optimizable because they are
> immediately turned into pointer-to-pointer-to-data type of
> constructs.

Real 2-d arrays turn into pointer-to-array, not pointer-to-pointer.  If
you have one of these dynamically-allocated arrays that have been
bandied about, which is really an array of pointers to blocks of data,
*that* is pointer-to-pointer.

>> ii) You can define your own data structures,
> This capability is NOT an adequate replacement for the complex data
> type.  Complex is more than just a pair of reals, [...]

It's both more and less powerful.  To put it another way, FORTRAN's
COMPLEX data type is NOT an adequate replacement for the ability to
define custom data types.

> No use of C programming constructs can do this:  [FORTRAN example]
> C provides no way to even do this calculation without function calls.

Sure it does, it just takes a little more code than the FORTRAN
example.  But that's a strawman anyway.  For every such example, I can
write one in C that FORTRAN similarly "can't" do.

					der Mouse

			uucp: mouse@mcgill-vision.uucp
			arpa: mouse@larry.mcrcim.mcgill.edu

mouse@mcgill-vision.UUCP (der Mouse) (06/26/88)

In article <738@naucse.UUCP>, rrr@naucse.UUCP (Bob Rose ) writes:
> In article <20340@beta.lanl.gov>, jlg@beta.lanl.gov (Jim Giles) writes:
>> The Problem is that 2-d arrays are not optimizable because they are
>> immediately turned into pointer-to-pointer-to-data type of
>> constructs.

> Ok, what gives. Some else post the following code (not exact but
> close enough)

> 	real a(5,2)
> 	call foo(a)
> 	end

> 	subroutine foo(a)
> 	real a(10)

> Now doesn't the following c code work to do the same

> 	double a[2][5]        /* <-- note [2][5] not [5][2] */
> 	....foo(a)....

> 	void foo(double a[10]) { ... }

No, I'm afraid not.  foo() is expecting an array of ten doubles.
Instead, you're passing it an array of two arrays of five doubles.
(Actually, a pointer to an array of five doubles.)

What's the difference?  To put it briefly, I find no guarantee that
sizeof(double[5]) == 5*sizeof(double).  (If that didn't make sense to
you, read on.)  Of course, most compilers won't produce surprises like
this, but that's no guarantee that some machine won't come along on
which there are good performance reasons for doing it.

A is just an array of two elements.  Like other arrays of two elements,
the memory allocated for it can be thought of as being in two pieces:
one for each element.  By the definition of pointer arithmetic and its
relation to arrays, the distance from the start of the first piece to
the start of the second piece is the size of the thing a is an array
of.  When the elements of an array are, say, structures, nobody finds
this surprising.  For example, suppose we have

struct { int i; char c; } b[2];

Now suppose sizeof(int)==2.  Then that structure really *needs* only
three bytes of storage.  However, the compiler is free to waste a byte
and decree that the structure type takes up four bytes, one of which
has no name.  As far as I can tell, the same is true of arrays: if I
declare

char c[3];

the compiler is free to do the same padding trick and make c take up
four bytes, one of which has no name.  Of course the same is true of
arrays of five doubles.  So when we allocate an array of two such
arrays, the compiler may put padding in between.

					der Mouse

			uucp: mouse@mcgill-vision.uucp
			arpa: mouse@larry.mcrcim.mcgill.edu

g-rh@cca.CCA.COM (Richard Harter) (06/27/88)

In article <1189@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes:

>>> ii) You can define your own data structures,
>> This capability is NOT an adequate replacement for the complex data
>> type.  Complex is more than just a pair of reals, [...]

>It's both more and less powerful.  To put it another way, FORTRAN's
>COMPLEX data type is NOT an adequate replacement for the ability to
>define custom data types.

The CDC 3600 version of fortran II had an interesting wrinkle.  You could
define your own data types with arithmetic operators.  The compiler would
generate calls to functions which you supplied.

The issue really is -- what data types are supported by the language as
primitives.  Any type which is a primitive language type can be compiled
much more efficiently than one which must be built up by hand.  C has 
characters and pointers as primitives; fortran has complex as a primitive.
C also has structures as a primitive.  
-- 

In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
	Richard Harter, SMDS  Inc.

rob@kaa.eng.ohio-state.edu (Rob Carriere) (06/28/88)

In article <528@philmds.UUCP> leo@philmds.UUCP (L.J.M. de Wit) writes:
>
>The trouble here is obviously that scientists want their problem to map
>too literally onto the notation and possibilities of a computer
>language.  Strange, because C you have to learn only once (that is,
>twice if that is not the proposed ANSI draft standard), scientific
>notations may change all the time. Knowing how to work with pointers
>can improve on speed considerably.
>
Yes.  I have written FORTRAN 66 programs where I could not set the
array lower bound, and was forced to drag ``-lb'' through every array
index in the entire code.  Rest assured, it did absolute wonders to
readability (and my nerves :-) I know how to work with pointers, I'm
just not proud enough of the fact to have to demonstrate it throughout
the code.  I'll hide this stuff where it belongs, in a couple of
low-level functions.  Not to mention, *my* notation tends to be very
consistent, I use whatever makes the problem the easiest to understand
:-)
>
>>Apparently some Fortran programmers equivalence different typed arrays to
>>create structures (shudder).
>
>Now this one I cannot grasp (English not being my native language); what do
>you mean by this sentence (what are the predicate and the subject) ?
>Can you give an equivalence 8-) ?
>
Methinketh the man useth ``equivalence'' as a verb, at least that's
what Dijkstra likes to do (though he at least has the good sense to
disambiguate to ``equivale'' -- don't you wish everybody spoke ``de
enige echte taal ter wereld'' :-) :-)

Rob Carriere
"Never translate your formulae!"

smryan@garth.UUCP (Steven Ryan) (06/28/88)

>So what IS FORTRAN's game?

Running big huge numerical models like a bat out of hell. Watching people
getting bigger and faster computers is like watching a heroin addict:
more! more! MORE!

People who say nasty things about fortran are right, but what have they to
offer?

>A few remarks:
>A C programmer can CHOOSE (note: uppercase 8-) whether he wants arrays
>to be global, static or automatic.

By only offering static allocation, the compiler does not have to support
any overhead at all. A C program must keep the stack pointer correctly
aligned and rest of the protocol straight even if it doesn't use the stack
because somebody it calls may use the stack. Similarily, in supporting
recursion, the stack has to be maintained in case some called program needs
the stack. Further, supporting recursion means all automatic variables must
be mapped into the stack because the procedure may recurse indirectly.
Forbidding recursion means the compiler can map automatic variables into
static areas.

However convenient it might be, recursion is not strictly necessary in practical
programs. In some numeric models, it would actually be inconvenient. This is
another case where fortran gives up something of questionable value (for them)
to simplify optimisation. (However, we can always use a transitive closure
which takes (?)cubic time to detect recursion, but most customers would
rather a fast compiler.)

>                                                       (zero overhead is
>rubbish; you always have to page or swap the data in, whether you use data
>/heap space or stack space, or you at least have to claim core).

Pagein cost vs. pagein + computation cost.

>                                             procedure frame are more
>or less for compiler builders: you can do without them, making it much
>harder for yourself

Unless it is impossible for a procedure to recurse, directly or indirectly,
local variables must be mapped onto the stack. You cannot avoid this
overhead without avoiding recursion.

>                                Dropping off these things (call, push ..)
>can only gain a few percent, at what other cost (inflexible subroutine
>scheme, permanent variables)? You can even totally rule out any use of
>subroutines if you're out for speed: large monolotic blocks with many
>pieces of repeated code, is that desirable?

Unfortunately--some people do find that desirable. As far as few cycles, look
back a few weeks when somebody said a C function should make the argument
list length available. Many jumped on the poor guy because they didn't
want their code to waste the single instruction necessary to load a register.

Please, don't suggest I want speed or I find this desirable. My favorite
compiler was an Algol60 compiler. I never turned off array bound checks or
switch range checks. I think call-by-name (real call-by-name with deferred
execution and not wimpy call-by-reference) is fun. The compiler permitted
assembly procedures to have variable length lists. The calling protocol
gave the parameter list length and a descriptor with type and kind for each
element in the list. And the address of dope vector was passed along.

>>Apparently some Fortran programmers equivalence different typed arrays to
>>create structures (shudder).

Some fortran programmers use the EQUIVALENCE statement to adjust the
beginning address of different arrays with different types so that 
they map their elements into interleaved storage. Don't know details--just
heard about some of things they do just to stay in fortran. Like using
blank common as a heap.

jlg@beta.lanl.gov (Jim Giles) (06/28/88)

In article <1189@mcgill-vision.UUCP>, mouse@mcgill-vision.UUCP (der Mouse) writes:
> In article <20340@beta.lanl.gov>, jlg@beta.lanl.gov (Jim Giles) writes:
> > The Problem is that 2-d arrays are not optimizable because they are
> > immediately turned into pointer-to-pointer-to-data type of
> > constructs.
> 
> Real 2-d arrays turn into pointer-to-array, not pointer-to-pointer.  If
> you have one of these dynamically-allocated arrays that have been
> bandied about, which is really an array of pointers to blocks of data,
> *that* is pointer-to-pointer.

I'm sorry.  To me a 2-d array is a 2-d array is a 2-d array is a ....
Any routine that gets a 2-d array as an argument must assume that it is
either static (which restricts you one way), or it must assume that it
is dynamic (in which case it IS a pointer-to-pointer etc.).  This means
that you can't write a general routine which takes a 2-d array as an
argument.  This is EXACTLY the sort of problem that I meant originally
when I said that C didn't have the concept of multi-dimensional arrays
in the language.

By the way, I've not seen any C compilers which optimize static 2-d
arrays anyway.  An early step in the compiler usually turns the array
reference into a linear function on the indices - this throws out the
dependency information.  As a result, very similar code is actually
generated whether the array was statically or dynamically allocated.
C gives you the worst of both worlds - you can't treat them the same
in source, and you can't get better optimization out of them in object
code.

> [...]
> > type.  Complex is more than just a pair of reals, [...]
> 
> It's both more and less powerful.  To put it another way, FORTRAN's
> COMPLEX data type is NOT an adequate replacement for the ability to
> define custom data types.

I never claimed it was.  To repeat: the ability to define derived data
types, and the operations thereon, is very useful and Fortran SHOULD have
it.  This has NOTHING to do with the debate about whether COMPLEX should
be built-in.  It has NOTHING to do with the fact that C cannot do COMPLEX
as efficiently as Fortran.
> 
> > No use of C programming constructs can do this:  [FORTRAN example]
> > C provides no way to even do this calculation without function calls.
> 
> Sure it does, it just takes a little more code than the FORTRAN
> example. [...

This 'little more code' that you're talking about does less than you
think.  Because COMPLEX is built-in to Fortran, the compiler writer is
free to use his knowledge about the semantics of COMPLEX in designing
optimizations.  Whereas your 'little more code' spells out a specific
sequence of operations to simulate complex artithmetic, the Fortran
compiler is free to choose from all mathematically equivalent
sequences for the most efficient one.  User definable data types
are useful, but commonly used data types should be built-in.

> ...]      But that's a strawman anyway.  For every such example, I can
> write one in C that FORTRAN similarly "can't" do.

Please feel free to do so when someone asks the question: 'Should I
convert C code to Fortran?' Why do you consider a direct answer to a
question to be a 'strawman'?  Or didn't you read the "subject" line on
this article.

J. Giles
Los Alamos

chris@mimsy.UUCP (Chris Torek) (06/28/88)

>In article <738@naucse.UUCP> rrr@naucse.UUCP (Bob Rose) suggests that
this C code is is legal:
>> 	double a[2][5]        /* <-- note [2][5] not [5][2] */
>> 	....foo(a)....
>> 	void foo(double a[10]) { ... }

In article <1190@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse)
gets the right answer, and the right reason:
>No, I'm afraid not.  foo() is expecting an array of ten doubles.
>Instead, you're passing it ... Actually, a pointer to an array of
>five doubles.)

but the wrong explanation:
>What's the difference?  To put it briefly, I find no guarantee that
>sizeof(double[5]) == 5*sizeof(double).

There is indeed such a guarantee.  The one that is missing, which makes
this particular example fail, is that pointers to arrays of objects need
not at all resemble pointers to the objects themselves.

Please remember that C is a strongly typed language (no matter what
else you have been told).  Mixing types is often legal, and the
cross-checking required by the language is extremly weak, but the
type system itself is quite strong.  The difference is like that
between an extensive law system and extensive enforcement:  If the
system is there, any missing enforcement can be provided later, at
need, without much hassle.

The whole example may be corrected quite simply:

	... foo(&a[0][0]); /* or foo(a[0]) */ ...

	void foo(double a[10]) /* or void foo(double *a) */ { ... }
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

smryan@garth.UUCP (Steven Ryan) (06/29/88)

>> > type.  Complex is more than just a pair of reals, [...]
>> 
>> It's both more and less powerful.  To put it another way, FORTRAN's
>> COMPLEX data type is NOT an adequate replacement for the ability to
>> define custom data types.

C does not provide custom data types either. It permits new structures,
but those are not orthogonal to the primitive types: no new operators,
no new casts, (on some implementation) no new assignments, ...

smryan@garth.UUCP (Steven Ryan) (06/29/88)

>>>some Fortran programmers equivalence different typed arrays

In Fortranish, "equivalence" is verb: to equivalence A and B means to write
an EQUIVALENCE statement to control their relative starting addresses as in
          DIMENSION A(100),B(101)
          EQUIVALENCE (A(1),B(2))

------------------------------------------------------------
p.s.  who says Fortran-66 doesn't support zero-based arrays?

shenkin@cubsun.BIO.COLUMBIA.EDU (Peter Shenkin) (06/29/88)

A few points concerning the everpresent comparisons between C and Fortran.
(I like *both*!!!)  Anyway, my first point has to do with recursion.  The
second with EQUIVALENCE.  If you're bored already, hit "n".

In article <817@garth.UUCP> you write:

>However convenient it might be, recursion is not strictly necessary in 
>practical programs....

POINT 1:
I used to agree, and most people agree.  Most textbook examples of recursion
-- eg, calculation of factorial(n) -- would be much clearer and faster, in
practice if coded using simple iteration.  But I've come across a class of
problem which can only be generally handled through recursion, I think.  I'd
be intrigued if someone can come up with a Fortran solution.  (Mail it to me,
and I'll post a summary to comp.lang.fortran.)

This class involves, conceptually, nested DO-loops, when the depth of the nest
is unknown at compile time.  For example, the following C program generates
grid points within a hypercube, given the number of degrees of freedom 
(dimensionality) of the space, and the number of gridpoints (number of levels)
along each coordinate.  Turns out I need to do more complicated versions of
this sort of thing all the time in numerical work.

NB:  This *can* be coded in Fortran by setting up the maximum number of needed
DO-loops and escaping early, if need be.  But this is unwieldy, at best , unless
this maximum is small.  And here (if one malloc()'s -- see my note on MAXDF)
a maximum need not be specified.

/*****************************************************************************/
/* grid.c:  generate grid points in a hypercube */
/*  compile by saying, "cc -o grid grid.c"
/*  invoke by saying, eg, "grid 4 2", to generate the vertices, only, of
 *    a 4-D hypercube.
 */
#define MAXDF 100  
  /* max number of degrees of freedom -- not really needed,
   *   since we could malloc() value[] in grdgen() */
main(argc,argv)
int argc; 
char *argv[];
{
	int df,nlev;  /* number of deg. of freedom, number levels per df */
	df= atoi(argv[1]);
	nlev= atoi(argv[2]);
	printf("df=%d; nlev=%d\n",df,nlev);
	grdgen(df,nlev);
}
/*****************************************************************************/
grdgen(df,nlev)
int df;     /*  no. of degrees of freedom */
int nlev;   /*  no. of levels each df */
{
	static int begin=1;     /*  ==0 if func was called by itself */
	static int totaldf;     /*  total no. of degrees of freedom (1st call)*/
	static int value[MAXDF];  /*  to hold current values of all df's */
	int i,j;

	if(begin)
		totaldf=df;

	if(--df ==0)  {      /* iterate through last df and print values */
		for(i=0; i<nlev; ++i) {
			value[df] = i;
			for(j=0; j<totaldf; ++j)  {
				printf("%d ",value[j]);  }
			printf("\n");
		}
		begin=1;
	}
	else
		for(i=0; i<nlev; ++i)  {
			value[df] = i;
			begin = 0;
			grdgen(df,nlev);
		}
}
/*****************************************************************************/

POINT 2:
>>>Apparently some Fortran programmers equivalence different typed arrays to
>>>create structures (shudder).
>
>Some fortran programmers use the EQUIVALENCE statement to adjust the
>beginning address of different arrays with different types so that 
>they map their elements into interleaved storage.

Generally it's the same storage, not interleaved storage, and it's not to
create structures.  (The conceptual equivalent (not real equivalent -- there 
is none) of structures in standard Fortran is labeled COMMON.)  EQUIVALENCE
is sometimes used to be able to reuse declared (C programmers would say 
"defined") storage for different purposes in different places.  The conceptual 
equivalent of this in C is the union.
-- 
*******************************************************************************
Peter S. Shenkin,    Department of Biological Sciences,    Columbia University,
New York, NY   10027         Tel: (212) 280-5517 (work);  (212) 829-5363 (home)
shenkin@cubsun.bio.columbia.edu    shenkin%cubsun.bio.columbia.edu@cuvma.BITNET

js07@bunny.UUCP (Jack Shaio) (06/30/88)

In a previous posting, der Mouse replies to:
>
>>> ii) You can define your own data structures,
>> This capability is NOT an adequate replacement for the complex data
>> type.  Complex is more than just a pair of reals, [...]

with:

>It's both more and less powerful.  To put it another way, FORTRAN's
>COMPLEX data type is NOT an adequate replacement for the ability to
>define custom data types.
>

In fact, the reverse is true: C's ability to define custom data
types is no substitute for FORTRAN's COMPLEX type.
COMPLEX is a standard, and you can link any packaged math subroutine to
your own programs without having to worry about how complex was defined.
I recently obtained three FFT algorithms in C from various sources
and found three different ways of defining complex (all different from mine).
Had I done everything in FORTRAN, a look at the subroutine header would
have been enough.

The point is that if you plan to do numerical work, and not program every
last subroutine from scratch, one COMPLEX data type in FORTRAN is a plus;
ten different definitions of complex in C are a pain. Perhaps a remmant
of the days when people used computers to solve equations.

							js

clewis@spectrix.UUCP (Chris "where are you this week?" Lewis) (06/30/88)

In article <817@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:
>By only offering static allocation, the compiler does not have to support
>any overhead at all. A C program must keep the stack pointer correctly
>aligned and rest of the protocol straight even if it doesn't use the stack

Not always - besides, do you really think the prologs have:
	if (stack is odd)
		align it
	??

>because somebody it calls may use the stack. 

Some C (and other langs) compilers optimize a lot of function prolog and
epilog stuff out.  Prolog and epilog for C code is usually not
noticable (compared to, say IBM 360 series FORTRAN).  Especially
interesting is that FORTRAN subroutines tend to be far larger than C
ones.  This is frequently due to people learning FORTRAN on IBM 360
series stuff where the prologs and epilogs are enormous in time and 
space - I've worked (internals) on an 360 series version of C that 
used it's own super simple calling convention - ran considerably faster
(even tho 360's don't have stacks!).

C's calling convention is actually absurdly simple - usually little 
more than saving the return address and some registers (register
variables and temporaries) and decrementing the stack and then 
restoring same at the end.  Unlike most Pascals (or ADA for that 
matter) which frequently have some rather spectacular stack frames 
formats to handle.

Also, what's so bad about stacks?  Many machines can do some stack
references faster than static - sufficient in many cases to greatly outweigh
the calling convention.  Eg: short stack offset instructions on 386, 
68020, VAXen(?) etc. are as short as two bytes instead of six for 
static - which at least saves you some additional memory fetches (which
are usually far more expensive than register adds) and your pipelining
gets to help a little more.  Eg: on a 68020, these are some representative
timings (in cycles):

			Best case	Worst case
	mov Rn,-(SP)	3		6
	mov Rn,n(SP)	3		7
	mov Rn,addr.L	5		9
	mov n(SP),m(SP)	6		13
	mov a.L,b.L	8		16

Similarly, for expression intermediaries, machines with short stack
offsetting modes can be a big win, and are usually less wasteful of
memory than most static memory schemes (unless you have a million 
registers ;-).

So, blanket statements like "automatic variables are a lot of overhead"
are frequently wrong - frequently they are *less* overhead.

I've done some fairly substantial compiler benchmarking, and have noted
that auto variables are usually faster than static (depending on the
circumstances and the CPU).

>However convenient it might be, recursion is not strictly necessary 
>in practical

Nobody is saying "recursion is necessary" - it's occasionally a handy
tool to simplify some problems.  That's all.  I almost never use it in
C - but I do sometimes, and I'd greatly miss it in a language that doesn't
support it (I'd probably say "Oh sh*t - not another FORTRAN!" ;-).

>>                                                       (zero overhead is
>>rubbish; you always have to page or swap the data in, whether you use data
>>/heap space or stack space, or you at least have to claim core).

>Pagein cost vs. pagein + computation cost.

Ah yes, but static memory allocation usually lead to programs that
are bigger - taking *longer* to load (usually on swapping systems).  
Without stacks and/or dynamic storage allocation programmers usually don't
have the ability to decide how much memory he needs depending on the data -
another potential optimization loss (the program's data structure has
to be as large as the largest set of data, rather than being able to
start smaller and make it bigger if necessary).  And the stack model is 
especially convenient for "deep returns" (use of setjmp/longjmp to be able to 
conveniently recover from errors way down a subroutine tree - have you 
ever seen the insides of Oracle?  Sheesh!).
-- 
Chris Lewis, 
These addresses will last only til June 30: (clewis@lsuc afterwards)
UUCP: {uunet!mnetor, utcsri!utzoo, lsuc, yunexus}!spectrix!clewis
Moderator of the Ferret Mailing List (ferret-list,ferret-request@spectrix)

jgk@speech2.cs.cmu.edu (Joe Keane) (07/01/88)

In article <20454@beta.lanl.gov> jlg@beta.lanl.gov (Jim Giles) shows
he hasn't used C.

>Any routine that gets a 2-d array as an argument must assume that it is
>either static (which restricts you one way), or it must assume that it
>is dynamic (in which case it IS a pointer-to-pointer etc.).

Whether an array is static or dynamic has nothing to do with whether
it contains arrays or pointers.  

>[various implications of this assumption]

>By the way, I've not seen any C compilers which optimize static 2-d
>arrays anyway.

So you've not seen any C compilers.  Given `static foo[10][10][10]'
the reference `foo[2][0][7]' is a single address.  If foo were a
parameter the reference would be a single offset.  But see for
yourself.

>As a result, very similar code is actually
>generated whether the array was statically or dynamically allocated.

Yes, the same code.

--Joe

mike@arizona.edu (Mike Coffin) (07/01/88)

From article <20454@beta.lanl.gov>, by jlg@beta.lanl.gov (Jim Giles):
> By the way, I've not seen any C compilers which optimize static 2-d
> arrays anyway.  An early step in the compiler usually turns the array
> reference into a linear function on the indices - this throws out the
> dependency information.

This is not true.  How can information be lost by changing "a[i]" to
"*(a+i)"?  In fact at least one very fancy FORTRAN compiler converts
array references to exactly that form to extract dependency
information that is difficult to recognize otherwise.  See
"Interprocedural Dependency Analysis and Parallelization" by Michael
Burke and Ron Cytron, in the 1986 SIGPLAN Symposium on Compiler
Construction, pp 162-175.

For instance they are able to parallelize a loop with the following
references:

	DO i = 1 to N
		A(2i,2i+1) = ...
		... = A(i,i)
		END

They say (page 166) 
    "Existing techniques separately analyze the two dimensions of A,
    and so separately consider two dependence equations, neither of
    which can demonstrate independence.  However, the dependencies
    that exist independently in each dimension cannot hold
    simultaneously: for any value of i, the expressions at the
    definition (2i and 2i+1) are never equal but the expressions at
    the use (i and i) are equivalent.  Since the dependencies cannot
    hold simultaneously, no dependence exists between the definition
    and use of A.  By linearizing the references to A, we couple the
    two equations into one, allowing us to determine the independence
    of the accessed regions."
-- 

Mike Coffin				mike@arizona.edu
Univ. of Ariz. Dept. of Comp. Sci.	{allegra,cmcl2,ihnp4}!arizona!mike
Tucson, AZ  85721			(602)621-4252

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

In article <2130@pt.cs.cmu.edu>, jgk@speech2.cs.cmu.edu (Joe Keane) writes:
> Whether an array is static or dynamic has nothing to do with whether
> it contains arrays or pointers.  
> 
You haven't been reading this discussion at all!  The C gurus all have been
saying that a static multidimensional array is implemented as pointer to
array, but that a dynamic multidimensional array is implemented as pointer
to pointer (to pointer ... etc for the number of dimensions).  I have
no reason to dispute this claim since it is the same as the statements
made in a recent issue of _Computer Language_ magazine.

> >By the way, I've not seen any C compilers which optimize static 2-d
  >arrays anyway.
> 
> So you've not seen any C compilers.  Given `static foo[10][10][10]'
> the reference `foo[2][0][7]' is a single address.  If foo were a
> parameter the reference would be a single offset.  But see for
> yourself.

What you just described is constant folding (the constant subscript
expressions were done at compile time).  Now, show how this relates to
the issue which was being discussed - vectorization or pipelining.
> 
> >As a result, very similar code is actually
> >generated whether the array was statically or dynamically allocated.
> 
> Yes, the same code.

Exactly!! The same bad code.  It was neither vectorized nor unrolled
for pipelining.  Hence it is not the same code that Fortran compilers
generally produce.  The Fortran generally runs faster because its
conception of array is better suited to these types of optimization.

J. Giles
Los Alamos

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

In article <6067@megaron.arizona.edu>, mike@arizona.edu (Mike Coffin) writes:
> From article <20454@beta.lanl.gov>, by jlg@beta.lanl.gov (Jim Giles):
> > By the way, I've not seen any C compilers which optimize static 2-d
> > arrays anyway.  An early step in the compiler usually turns the array
> > reference into a linear function on the indices - this throws out the
> > dependency information.
> 
> This is not true.  How can information be lost by changing "a[i]" to
> "*(a+i)"?  In fact at least one very fancy FORTRAN compiler converts
> array references to exactly that form to extract dependency
> information that is difficult to recognize otherwise.  See
> "Interprocedural Dependency Analysis and Parallelization" by Michael
> Burke and Ron Cytron, in the 1986 SIGPLAN Symposium on Compiler
> Construction, pp 162-175.
> 
Most simple compilers (read 'C compilers') can't vectorize the following
(assume i is a loop index):

  A[i+N] = A[i+M]

regardless of the values of N or M.  However the following expression
might have been the source of the above expression:

A[4][i] = A[5][i]

This clearly has no dependencies and even a simple compiler (read 'some
Fortran compilers') can vectorize this (ie. A(i,4)=A(i,5)).  Turning
the references above into *(A+i+4*dim2) = *(A+I+5*dim2) which, after
constant folding, is the expression I started out with is what causes
the C compiler to incorrectly identify a dependency.

Now, it is true that with careful analysis of M, N, and the range if i,
the compiler could still have compiled this efficiently.  No C compilers
that I've seen do this very well.

Thank you for the reference.  I have always been convinced that dependency
analysis should TRY the kind of stuff you suggest, but only if simplistic
analysis fails to get rid of the dependencies (compiler speed should
be considered too).  The problem is that C doesn't use either analysis
technique very well.  C actually CAN'T analyse those dynamic multi-
dimensional arrays (pointer-to-pointer) because it can't assume the
pointers have any specific relationships.  It is probably for this
reason that it doesn't bother for static arrays either.  (vote for
'noalias', that should help.)

J. Giles
Los Alamos

smryan@garth.UUCP (Steven Ryan) (07/02/88)

>Not always - besides, do you really think the prologs have:
>	if (stack is odd)
>		align it
>	??
>
>>because somebody it calls may use the stack. 

On a previous machine I used, yes, the stack had to be kept at even word
boundary at all times.

>Some C (and other langs) compilers optimize a lot of function prolog and
>epilog stuff out.  Prolog and epilog for C code is usually not
>noticable (compared to, say IBM 360 series FORTRAN).

The compiler is cheaper if it never existed in the first place. I suspect
part of the size of prolog goes for adjustable arrays.

>Also, what's so bad about stacks?  Many machines can do some stack
>references faster than static - sufficient in many cases to greatly outweigh
>the calling convention.

I think this a base register+offset compared to a constant offset, which should
be avoiding in any case because it makes the code nonreentrant. Again, on the
previous machine I used, all data references were base register+offset so that
no time/space difference existed. Then again, if you want to consider a machine
designed for C, would you also consider a machine designed for fortran.

>So, blanket statements like "automatic variables are a lot of overhead"
>are frequently wrong - frequently they are *less* overhead.

All that is being compared is addressing modes.

>>However convenient it might be, recursion is not strictly necessary 
>>in practical
>
>Nobody is saying "recursion is necessary" - it's occasionally a handy
>tool to simplify some problems.  That's all.

For most problems, recursion is the most natural technique for me. Most times
I use loops is because compilers don't do recursion removal and most languages
make it difficult to define procedures.

Data structures also simplify many problems. The challenge is to design a
language as fast as Fortran but a shade more advanced (by about 30 years).

Fortran users are conservative and are already pushing their machines to the
limit. I have seen compiler complaints, not that the code is wrong, but that
uses one extra instruction.

>Ah yes, but static memory allocation usually lead to programs that
>are bigger - taking *longer* to load (usually on swapping systems).  

Unix has a disgusting loader, but this is not really a language issue. Also,
once loaded, a program may be run many times. In this case, a longer load
is offset by a shorter run.

>Without stacks and/or dynamic storage allocation programmers usually don't
>have the ability to decide how much memory he needs depending on the data -
>another potential optimization loss (the program's data structure has
>to be as large as the largest set of data, rather than being able to
>start smaller and make it bigger if necessary).

Some C programmers don't seem to notice--see previous complaints about Yacc.

smryan@garth.UUCP (Steven Ryan) (07/03/88)

>>                 An early step in the compiler usually turns the array
>> reference into a linear function on the indices - this throws out the
>> dependency information.
>
>This is not true.  How can information be lost by changing "a[i]" to
>"*(a+i)"?  In fact at least one very fancy FORTRAN compiler converts
>array references to exactly that form to extract dependency
>information that is difficult to recognize otherwise.

[at two fortran compilers--the vectorising compiler I worked on also
operated on an affine function of the subscripts.]

The C subscript, if taken literally, does lose dependency information.

    Strict C parse tree                   possible Fortran parse tree

    convert-*-to-variable                          subscript
              |                                   /         \
        integer-add                        symbol: a      integer-multiply
       /           \                                      /              \
symbol: a        integer-multiply                  element-size           i
                /                \
      element-size                i

By having an explicit subscript node, a Fortran optimiser can easily access
the array spans for each dimension, necessary for vectorisation. It also
simplifies determining what region is referenced or defined, necessary for
common subexpressions.

------------------------------------
USA - home of the modern revolution.
(tho we'd just soon fergit it.)

chris@mimsy.UUCP (Chris Torek) (07/03/88)

>In article <2130@pt.cs.cmu.edu> jgk@speech2.cs.cmu.edu (Joe Keane) writes:
>>Whether an array is static or dynamic has nothing to do with whether
>>it contains arrays or pointers.  

(Joe is correct.  A C array is simply `array N of T', where T is any
valid C type except `function returning T1', and where N is constant.
The last is the bugaboo.)

In article <20518@beta.lanl.gov> jlg@beta.lanl.gov (Jim Giles) writes:
>You haven't been reading this discussion at all!  The C gurus all have been
>saying that a static multidimensional array is implemented as pointer to
>array, but that a dynamic multidimensional array is implemented as pointer
>to pointer (to pointer ... etc for the number of dimensions).

Only the false gurus.  :-)

More seriously, what C lacks in array handling is only the ability to
conveniently write the following FORTRAN declaration:

	SUBROUTINE FOO(M, N, ARR)
	INTEGER M, N
	INTEGER ARR(M, N)

	... ref ARR(i, j) ...

	END

Ideally, one should be able to say

	void foo(int m, int n, int arr[n][m]) {
		... /* ref arr[j][i] */ ...
	}
	/* called as foo(M, N, arr) */

and have both compilers do the same thing---namely, compute the
address (&arr[0][0] + j * m + i).  In practise, one must write

	void foo(int m, int n, int *arr) {
		... /* ref arr[j*m + i] */ ...
	}
	/* called as foo(M, N, &arr[0][0]) */

There is at least one C compiler that supports the former syntax as an
extension, namely the GNU compiler `gcc'.  (It is a trivial extension,
mechanically speaking, in most compilers.)

>... The Fortran generally runs faster because its
>conception of array is better suited to these types of optimization.

which is correct, but not because of the form of subscripting, but
rather because of an implicit rule against aliasing---a rule that I
have seen violated in FORTRAN programs, incidentally.  (Such programs
are allowed to quietly produce mysterious results [as are malformed C
programs that are equally easy to come by: different error, same lack
of obviousness].  Ever hear someone gripe `but it works on VAX/VMS; the
<Cray/CDC/...> compiler must be broken'?)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

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

In article <12292@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:
> In article <20518@beta.lanl.gov> jlg@beta.lanl.gov (Jim Giles) writes:
> >You haven't been reading this discussion at all!  The C gurus all have been
> >saying that a static multidimensional array is implemented as pointer to
> >array, but that a dynamic multidimensional array is implemented as pointer
> >to pointer (to pointer ... etc for the number of dimensions).
> 
> Only the false gurus.  :-)

I would like to see dynamically allocated multi-dimensional arrays in
C that aren't declared as:
    int **a ...
But all implementaions (both here on the net and in journals) have done
this.  The result is that a reference to such an array really IS turned
into pointer-to-pointer type constructs.  If you have an alternate
implementation, please send it to me and I'll shut-up.

> [...]
> Ideally, one should be able to say
> 
> 	void foo(int m, int n, int arr[n][m]) {
> 		... /* ref arr[j][i] */ ...
> 	}
> 	/* called as foo(M, N, arr) */
> 
I agree.  The point is that you can't.  Furthermore, 'foo' has to
be implemented twice if the expected argument (arr) could be either
statically or dynamically allocated.  In the later case, the declaration
has to be: int **arr.

> [...]
> >... The Fortran generally runs faster because its
> >conception of array is better suited to these types of optimization.
> 
> which is correct, but not because of the form of subscripting, but
> rather because of an implicit rule against aliasing---a rule that I
> have seen violated in FORTRAN programs, incidentally.  (Such programs
> are allowed to quietly produce mysterious results [as are malformed C
> programs that are equally easy to come by: different error, same lack
> of obviousness].  Ever hear someone gripe `but it works on VAX/VMS; the
> <Cray/CDC/...> compiler must be broken'?)

Which is what I pointed out when I said that C needs the 'noalias'
directive.  The Fortran rule against aliasing is not implicit either.
The standard specifically prohibits it.  Due to separate compilation
constraints, the compiler can't check the problem.  But the prohibition
is explicit.

By the way, the Fortran 8x version of dynamic memory allocation doesn't
have the pointer-to-pointer problem.  When you declare an allocatable
array, its dimensionality is part of the declaration.  The ALLOCATE
statement then takes the actual dimensions and dynamically allocates
the whole space.  From a subroutine's point of view, all arguments
which are declared multi-dimensional are treated the same whether
they were dynamically allocated or not.

J. Giles
Los Alamos

chris@mimsy.UUCP (Chris Torek) (07/04/88)

>>In article <20518@beta.lanl.gov> jlg@beta.lanl.gov (Jim Giles) claimed that
>>>... The C gurus all have been saying that a static multidimensional
>>>array is implemented as pointer to array, but that a dynamic
>>>multidimensional array is implemented as pointer to pointer
>>>(to pointer ... etc for the number of dimensions).

>In article <12292@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>>Only the false gurus.  :-)

In article <20531@beta.lanl.gov> jlg@beta.lanl.gov (Jim Giles) writes:
>I would like to see dynamically allocated multi-dimensional arrays in
>C that aren't declared as:
>    int **a ...

Okay:

	int n, m, *a, i, j;

	/* make a an int a[n][m] */
	a = (int *)zalloc(n * m, sizeof(int));
	/* zalloc is like calloc but never fails (aborts on error) */

	/* work with it */
	for (j = 0; j < n; j++)
		for (i = 0; i < m; i++)
			... ref a[j * m + i] ...

The other reason your claim in >>> above is wrong is because statically
allocated 2-D arrays can be done with row vectors:

	/* these must be global */
	int a0[M], a1[M], a2[M], a3[M], ..., a99[M]; /* if N=100 */
	int *a[N] = { a0, a1, a2, a3, ..., a99 };

>But all implementations (both here on the net and in journals) have done
>this.

Because it is convenient.  The version above with j*m + i is not.
(This is the key point; more later.)

>The result is that a reference to such an array really IS turned
>into pointer-to-pointer type constructs.  If you have an alternate
>implementation, please send it to me and I'll shut-up.

Someone already did.  One can combine the row-vector and the flat
array:

	int **a, i;
	a = (int **)zalloc(N, sizeof(int *));
	*a = (int *)zalloc(N * M, sizeof (int));
	for (i = N; i < N * M; i += M)
		a[i] = *a + i;

	/*
	 * now may work with either a[j][i] (row vector)
	 * or a[0][j * M + i] (flat).
	 */

>>Ideally, one should be able to say
>>
>>	void foo(int m, int n, int arr[n][m]) {
>>		... /* ref arr[j][i] */ ...
>>	}
>>	/* called as foo(M, N, arr) */

>I agree.  The point is that you can't.

Right.  This makes working with flat arrays of more than one dimension
inconvenient (NOT impossible!).

>Furthermore, 'foo' has to be implemented twice if the expected
>argument (arr) could be either statically or dynamically allocated.

Wrong.  As long as the static and dynamic versions agree---both
must either be flat, or be row-vector---the same code can be used
for both.  If the dynamic array is both flat and row-vector, then
it does not matter which the static version is.  Incidentally, I
can make the static version also be both flat and row-vector:

	/* these must again be global */
	int a00[M * N];
	int *a[N] = { a00 + 0, a00 + M, a00 + 2*M, ..., a00 + 99*M };

>In the later case, the declaration has to be: int **arr.

In the row-vector case.  If we use the flat-and-row-vector dynamic
implementation, the call must read

	foo(m, n, &arr[0][0])

and the declaration must read

	void foo(int m, int n, int *arr) {
		int j, i;
		for (j = 0; j < n; j++)
			for (i = 0; i < m; i++)
				... work with arr[j*n + i] ...
	}

If we use the flat static implmentation, the call and the declaration
remain identical.

>>>... The Fortran generally runs faster because its
>>>conception of array is better suited to these types of optimization.

>>which is correct, but not because of the form of subscripting, but
>>rather because of an implicit rule against aliasing ...

>Which is what I pointed out when I said that C needs the 'noalias'
>directive.

I think that the noalias directive damages C far more than it improves it,
just as I think that rule in Fortran damages Fortran.

>The Fortran rule against aliasing is not implicit either.

I meant only that it is not explicit in the code.

>The standard specifically prohibits it.  Due to separate compilation
>constraints, the compiler can't check the problem.

... in the general case, yes.  In almost all cases the compiler
(`linker', if you prefer) can, at least if the Fortran rule against
aliasing matches what I think was intended by X3J11's `noalias'.  If
the rule is stronger than that (I hope not), the `linker' (which should
certainly do code generation, if you want any sort of decent inline
expansion) can detect all illegal aliasing (again, I hope the rule is
not *that* strong!---it would prohibit all sorts of useful tricks that
never cause trouble on real hardware).

>By the way, the Fortran 8x version of dynamic memory allocation doesn't
>have the pointer-to-pointer problem.  When you declare an allocatable
>array, its dimensionality is part of the declaration.

Likewise for gcc:

	void f(int n, int m) {
		int a[n][m];
		/* or, if you prefer to use malloc:
		    (*a)[m] = (int (*)[m])zalloc(n * m, sizeof(int)) */
		...
	}

Again, this is convenient.  Unfortunately, it is also not standard, so
it cannot be used in general.  If one wants a flat array (because the
compiler is unable to vectorise the row-vector version, perhaps), one
must use the inconvenient access version, a[j*m + i] (with either the
flat allocation or the combined flat-plus-row-vector allocation).  When
something is convenient, it gets used; when it is inconvenient enough,
it does not get used (for instance, I never use Fortran [*]).  This
gives a slight advantage to the flat-plus-row-vector version:  when
speed is unimportant (or when your compiler is smart enough), use the
convenient row-vector access a[j][i]; when you have to play tricks to
convince the compiler to vectorise, use the inconvenient flat acess
a[0][j*m + i].  The problems with the f-p-r-v version are that the
allocator is more complex (minor: it is only written once) and that
using it in two different ways is confusing (major: this must constantly
be documented).

-----
[*] Bet you took this one wrong!  Instead, when I must, I use Ratfor. :-)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

dik@cwi.nl (Dik T. Winter) (07/05/88)

In article <12302@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
 > Again, this is convenient.  Unfortunately, it is also not standard, so
 > it cannot be used in general.  If one wants a flat array (because the
 > compiler is unable to vectorise the row-vector version, perhaps), one
 > must use the inconvenient access version, a[j*m + i] (with either the
 > flat allocation or the combined flat-plus-row-vector allocation).

Se essentially there are two ways to do the thing in C.  Now what if I
am writing a portable library, should I make two versions (one for
vector machines and the other for smart compilers)?  This is a bit
ridiculous, so we will get libraries (like IMSL, NAG and packages as
LINPACK etc.) in only one version.  And if the programmer started with
the other version, but found he needed a library routine, he is in trouble.
The big point is: you are not going to write a complete numerical system
from scratch, so you have no options; it is the library that dictates
the option (which is most likeley a flat array).
-- 
dik t. winter, cwi, amsterdam, nederland
INTERNET   : dik@cwi.nl
BITNET/EARN: dik@mcvax

smryan@garth.UUCP (Steven Ryan) (07/05/88)

>A few points concerning the everpresent comparisons between C and Fortran.
>(I like *both*!!!)

I dislike both.

>>However convenient it might be, recursion is not strictly necessary in 
>>practical programs....

Practical as in how many Fortran programmers need indefinite looping.

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

I guess my major complaint against C multi-dimensioned arrays is that
the reference a[i][j] means different things depending upon the decl-
aration of a.  If these differences were transparent at the source
level it wouldn't be so bad.  But the user is REQUIRED to be aware of
the differences.  In Chris Torek's terms, the difference between
'flat' and 'row-vector' multi-dimensioned arrays requires explicit
different treatment by user code - in spite of identical syntax.
Fortran is superior in this case in that all arrays are 'flat' - in
Fortran 8x this includes dynamically allocated arrays.

In article <12302@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:
> [...]
> I think that the noalias directive damages C far more than it improves it,
> just as I think that rule in Fortran damages Fortran.
> 
The rule against aliasing in Fortran doesn't hurt it because all arrays
are 'flat' to begin with.  If C had a way of declaring 'flat' arrays
dynamically (like Fortran 8x and most large Fortran environments have)
it wouldn't need 'noalias' either.  (I declare dynamic arrays in Fortran
all the time.  It's non-standard, but it can be done in some way on all
systems I now use.)

To be sure, Fortran probably needs some way of allowing aliasing.  But
I think it should be with an explicit user request (an ALIAS statement)
rather than the default assumed.  Most frequently, aliasing is
accidental, deliberate aliasing is comparatively rare.  The rare usage
is the one that should require extra oversite from the user. (And C
DOES need 'noalias' in order to get a functionality that is otherwise
difficult.  A directive which gives extra flexibility to the user
without an undue burden on those that don't use it is not really
damaging to the language.)

> [...]                                                              When
> something is convenient, it gets used; when it is inconvenient enough,
> it does not get used (for instance, I never use Fortran [*]).

Hmm....  That's just exactly the reason that I rarely use C.

> [*] Bet you took this one wrong!  Instead, when I must, I use Ratfor. :-)

Hmm....  I don't use RATFOR either (at least not for many years - it
produces TERRIBLE code).  Still, I would like a version of Fortran
which allowed INTERNAL procedures - the ONLY useful item in RATFOR.

>  [...]                                                          This
> gives a slight advantage to the flat-plus-row-vector version:  when
> speed is unimportant (or when your compiler is smart enough), use the
> convenient row-vector access a[j][i]; when you have to play tricks to
> convince the compiler to vectorise, use the inconvenient flat acess
> a[0][j*m + i].

This last is just the sort of thing that simplistic compilers have
trouble vectorizing.  The statement: arr[4][i] = arr[5][i] turns into:
*(M+i) = *(N+i) where M and N are the result of constant folding (of
the array address and the product of the dimension size with either 4
or 5 respectively).  If this is in a loop on i, the first version (with
the syntax clearly displayed) is obviously free of dependencies.  The
second version requires additional calculation from the compiler to
determine dependencies.  In a more complicated expression, this
additional work may be beyond the ability of the compiler.  The rumor
is that this very example killed the early Cray compiler (ie. the
compiler incorrectly identified it as a dependency).  Actually, I have
no idea whether the Cray C compiler does this correctly even now - even
for statically allocated arrays.

It seems very strange to support a 'feature' which requires you to
make dependency analysis harder in order to vectorize at all.

J. Giles
Los Alamos

smryan@garth.UUCP (Steven Ryan) (07/06/88)

In Algorithmic Language and Program Development, Bauer and Wossner, they cite
Paterson and Hewitt as proving, essentially, recursion is more powerful than
iteration.

>                                           But I've come across a class of
>problem which can only be generally handled through recursion, I think.  I'd
>be intrigued if someone can come up with a Fortran solution.

I don't want to be in position of proving various examples can be done without
recursion, given the above statement and my own opinions. However this example
is interesting.

A recursive solution assumes the existence of a sufficiently large stack. If
this storage is made available to Fortran program (perhaps as blank common),
a nonrecursive solution would store the loop parameters as array elements:

           while still-something-do
              do-it
              increment-lowest-stack-entry
              while it-overflows
                 reset-it
                 increment-the-next-lowest-stack-entry

rob@kaa.eng.ohio-state.edu (Rob Carriere) (07/06/88)

In article <879@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:
>In Algorithmic Language and Program Development, Bauer and Wossner, they cite
>Paterson and Hewitt as proving, essentially, recursion is more powerful than
>iteration.
>
I don't know the learned gentlemen, but it is certainly true that for
anything that can run on a computer, recursion is *at most* as strong
as iteration.  Proof: the CPU is an iterative device, not a recursive
one (it iterates through its' microcode or eqv) and it can excecute
your program.  Since a computer with unbounded memory is as strong as
a Universal Turing machine, I have this nagging feeling that the proof
of P&H was intended for a much more restricted environment than either
B&W or the poster are (is) assuming.  If I'm wrong, *do* tell me, this
sounds interesting.

Rob Carriere
"He iterated until he had no recourse but to recurse his fate."

smryan@garth.UUCP (Steven Ryan) (07/07/88)

>>In Algorithmic Language and Program Development, Bauer and Wossner, they cite
>>Paterson and Hewitt as proving, essentially, recursion is more powerful than
>>iteration.
>>
>I don't know the learned gentlemen, but it is certainly true that for
>anything that can run on a computer, recursion is *at most* as strong
>as iteration.

I will step aside. The bibliography reference is, I think,

     Paterson M S, Hewitt C E (1970): Comparative Schematology. Record of
         the Project MAC Conference on Concurrent Systems and Parallel
         Computation, Woods Hole, Mass, 1970. New York: ACM 1970, p. 119-127

Have at it.

atbowler@watmath.waterloo.edu (Alan T. Bowler [SDG]) (07/15/88)

In article <817@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes:
>
>By only offering static allocation, the compiler does not have to support
>any overhead at all. A C program must keep the stack pointer correctly
>aligned and rest of the protocol straight even if it doesn't use the stack
>because somebody it calls may use the stack. Similarily, in supporting
>recursion, the stack has to be maintained in case some called program needs
>the stack. Further, supporting recursion means all automatic variables must
>be mapped into the stack because the procedure may recurse indirectly.
>Forbidding recursion means the compiler can map automatic variables into
>static areas.
>

Then again depending on the machine archetecture, access to something
mapped to a stack frame may be cheaper and faster than statically
allocated memory.  It depends on the addressing mechanisms of the
machine, and the skill of whoever does the stack design and call/return
mechanism.  The blanket statement that stack accesses were more
expensive than static memory accesses was true in the past,
but stopped being universally true sometime in the 1960's.  As
hardware caches become more important, and as addressing extensions
are added to increase the address space of existing architectures,
the tradoff between stack and static allocation changes.

smryan@garth.UUCP (Steven Ryan) (07/17/88)

[Suddenly, a pittrap opens beneath our hero's toes. From the darkness are
heard faint cries of `my mainframe is bigger than your mainframe.' He neatly
pirouettes out of danger.]

>Then again depending on the machine archetecture, access to something
>mapped to a stack frame may be cheaper and faster than statically
>...

I see three possibilities:

(1) On the hardware, static nonrecursive code is faster than stack-based
recursive code. Fortran wins; C loses.

(2) Static and stack code are equally well supported. Fortran wins; C wins.

(3) Stack code is faster than nonrecursive static code. C wins. Also, Fortran
wins. Although a standard conforming *program* cannot be recursive, the
implementation is unrestricted. A compiler can map a program into static
nonrecursive code, stack-based recursive code, heap-based multithreaded
recursive and reentrant code, or anything else as long as it accepts
nonrecursive code.

Is this cheating? Well.....

This is a case of underconstraining the solution so that the implementor has
greater freedom of action. A Fortran compiler writer has that many fewer
constraints than C hence that much more freedom. The Fortran compiler may
not be better but certainly will not be worse.

This is similar to the alias ban in Fortran. [NO! I'm starting that again.
This is just a fer instance, not an agreement/disagreement.] The Fortran
optimiser can depend on the alias ban to produce better code than C. Doesn't
have to, and it won't effect a conforming program either way.

In general, the fewer constraints that are put on a compiler, or any other
program, the more freedom the programmer has for getting any particular
implementation fast.

                                Hafa an godne daege.
                                             sm ryan

----------------------------------------
Bucky Bug sez:
    Poor Mother Earth..
    No one takes care of her in her old age..
                       - Odd Bodkins

smryan@garth.UUCP (Steven Ryan) (07/17/88)

>This is similar to the alias ban in Fortran. [NO! I'm starting that again.
                                                      ^
                                            [NO! I'm NOT starting that again.

Oh, well.