Form of equation handled by Fortran

Form of equation handled by Fortran

I have some code that uses an aquation like this:

E(T) = ( ( (C3 * T - C2) * T + C1) * T + C0) * T

The coefficients C0 - C3 are set in a data statement.  It seems to work OK but what intrigues me is the 'E(T)' part.  Outside of a Fortran context, there is no surprise:  it's a equaton in (independent variable) T.

However, within the Fortan context, it raises my eyebrow,.  When I first saw this, I expected E to be a one-dimentional array.  Accordingly, E(T) would set the element 'T' to the value evaluated by the right-hand side of the equation.

But this is not the case at all.  E is NOT an array!  I've never seen anything like this nor do I see it addressed in any Fortran syntax guide.

Why wouldn't it just be:

E = ( ( (C3 * T - C2) * T + C1) * T + C0) * T

How can Fortran syntax interpret E(T) to be anything other than an array?  Any thoughts are appreciated.

19 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

E(T) can be a function or and array. Add IMPLICIT NONE to the code that uses E(T) and then declare what/where the variables are located.

Jim Dempsey

www.quickthreadprogramming.com

This appears to be a "statement function." Many consider it to have been obsoleted 20 years ago by the introduction of internal functions, which most compilers optimize equally well by now. module functions might also be considered.
The placement requirements for the older and newer forms are entirely different. A statement function has to come immediately before DATA, while internal functions follow CONTAINS at the end of a compilation unit.

Jim,

Maybe I should have said - the original context was F77 and everything was implicit. Also, a function is a subprogram. The way this equation was being handled was just as a freestanding equation. I agree that, if E(T) is not an array (which it ain't), it has the distinct look of a function in T. But it was never configured or declared as such,

So I revise to my original question:
How can Fortran syntax interpret E(T) (as presented above) to be a function? Is it sort of an "implicit" interpretation? I'm guessing Yes.

Yes, you are right, Tim. Statement Function it is. I never had stumbled onto this.

I looked it up in my CVF Language Reference (1999) and it discusses this in Section 8.5.4. It doesn't say a whole lot about int but in the tiny example snippet, it looks like both the function name and its dummy argument must be declared. I did this:

real(4) :: E, T

and the compiler complains:
Error: This name has not been declared as an array or a function. [E]

Uggh.

If you have implicit none in that compilation unit (or an equivalent compile option), the dummy identifiers will require declaration. The same would apply if you replace it with an f90 internal function.
Prior to f77, there were sometimes conflicting ways of dealing with data types in statement functions, and it took a while for many compilers to implement the then-new rules, in part because people didn't want to have to fix their programs.

I think I should have said a statement function must come immediately after DATA. Besides having restriction about placement in the compilation unit, there re explicit restrictions against some combinations of newer f90 syntax with statement functions, such as not allowing them in array assignments (but not all compilers are picky).

Tim,

If you were standing behind my chair, you would see that I totally did what you suggested in your last 2 posts. I'm totally "implicit none" and I totally declared both E & T, s IO stated before. And I'm not even using a data statement; I set the constants with individual statements.

This is rather academic at this point - certainly not the end of the world. I just like to understand things and this isn't happening.
Thanks for your input.

The error message you received is what one might expect if the DATA statements immediately preceding the definition of statement function F initializing the values of C0, C1, C2, and C3 were replaced in situ with assignment statements. In this case F would no longer lie in the specification part of the program unit so it could not be interpreted as a statement function. Replacing DATA statements with assignment actually changes the semantic of the program. I recommend leaving the DATA statements as they were, or else replace them with initializers in the type declarations of C0, C1, C2, and C3.

Tim,

If I understand your last point, it's imperative that, if using a statement function, one use a data statement to assign constants and not initialization statements. I also understand you to say that F90 is particular as to where the data statement is placed.

I re-worked the code F90 so that the constant initializations are made w/ a data statement. I also placed the data statement in various logical places. I still get the same compile errors.

I will try to upload the code.

Oh, I have no earthly idea why this forum won't allow upload of harmless *.f90 files (crazy). I renamed *.txt.

Attachments: 

AttachmentSize
Download testcvp.txt1.54 KB

I think the comment about data statements might be a bit of a red herring.

The statement function needs to be defined in the specification section of the program unit - i.e. before the first executable statement. Data statements and type declaration statements aren't executable, but assignment statements are. There are assignments involving Tk, T, S, etc before the statement function definition.

IanH quoted the rule correctly about placement of the statement function. If you wish the constants to actually be named constants, PARAMETER would be appropriate. If you wish to set them by assignments, those assignments would come after the statement function but before reference to it. The use of DATA for constants seems to indicate code developed prior to f77.
If the unusual rules about statement functions are confusing, those are reasons for accepting obsolescence and replacing statement functions by internal functions.

We had much old code, some of which used statement functions. We converted most of those to module/subroutine functions (statements following CONTAINS at the end of the function or subroutine.

Linda

I finally see what's happening here. It's not based on any one thing any one person said, but rather by threading hints together. Everybody was hitting all around it; I'll see if I can articulate it in my own words here:

Yes,
E(T) = ( ( (C3 * T - C2) * T + C1) * T + C0) * T
is a statement function. I had never run into this animal before. Oddly, I noted that it appeared first thing in the program unit and, in trying to explore its behavior, I could never get the compiler to stop at a breakpoint set there - at least not first off. This really made me scratch my head. Now that I read some of these comments, the reason is understandable.

I moved some of the code to an isolated program to really test its behavior (that's the code I uploaded). When I read IanH's comment:
"The statement function needs to be defined in the specification section of the program unit - i.e. before the first executable statement."

it finally dawned on me. That was why I had seen it mysteriously (to me) appearing at the top of the original program unit, before any executables. There's another subtle part of this, which Tim just hit one. The statement function(s) appear at the beginning but must be referenced below in order to get their values, e.g., Et = E(T). In my original code, the references weren't very obvious: they were buried in statements and used different dummy arguments than what appeared in the statement functions themselves.

Well, I finally have these "statement functions" figured out and - best of all - I documented my code to indicate what the hell's going on.

Thanks again one and all.

I have been watching this post for a while.
"E(T) = ( ( (C3 * T - C2) * T + C1) * T + C0) * T"
As already stated, this is a statement function, where T is a supplied variable, while C0, C1, C2 & C3 are effectively contained variables common to both the routine and the statement function.
I would have said that this was removed at Fortran 90, although my memory of fortran history has been failing. It was definately available pre F77. This functionality can now be provided if C0..C3 are declared in a module and E(T) is a contained function.
.
A confusion could occur if the variable T is used in both the statement function and also in the routine. If IMPLICIT_NONE is used then T must be declared, although this declaration is shared between two different variables.
.
What troubles me is that when seeing the statement function, I would expect it to be defined as a cubic polynomial and not a quartic:
E(T) = ( (C3 * T - C2) * T + C1) * T + C0
.
John

Statement functions were marked as obsolete in Fortran 90, but they are still part of the standard, even in F2008. One of the reasons given for them being made obsolete was that their syntax and requirements can be confusing - for evidence of that see... well, this thread. Their obsolete status means that with appropriate switches (probably /stand) the compiler should whine if it sees one. Frankly these days if the compiler observed someone putting statement functions in new code a more appropriate response would be to reach out from the computer and box said programmer around the ears.

Ian,
I don't share your negative views of statement functions. They can be useful.
Replacing a simple construct with a far more complex arrangement has been a feature of F2003 and F2008.
My perspective is that F1995 is still preferred by a significant proportion of users and cash strapped compiler developers.
.
After reading today's headlines, it's good we are still free to disagree. I only hope I am not around when the internet develops to where your threat could become a reality.
.
John

The isolated source code statement might look simple, but if you have a look at the list of restrictions on those statements their apparent simplicity is somewhat deceptive. Consequently they are a potential source of "unintentional" errors.

From a parsing point of view they are a pain in the backside - you can't distinguish them in the general case from assignment statements unless you have access to the semantics of all declarations in the source up to that point (including declarations in modules). The difficulty in parsing mirrors the difficult that a human source reader might have following what's going on with the source code.

Internal procedures more robust to programmer mistakes, are far clearer to readers of the source and are vastly more capable. They may take a little more typing, but the trade-off against the negatives of statement functions make the decision pretty clear in my mind.

Statement functions (there equivilent) have been around a long time in other languages: LISP, FORTH, etc...
Effectively you could view C Preprocessor

#define E(T) ( ( (C3 * T - C2) * T + C1) * T + C0) * T

As a statement function.
Note, the above can also be used in FPP (FORTRAN PreProcessor)

It can also be said statemtent functions have the potential to remove unintentional errors.

Jim Dempsey

www.quickthreadprogramming.com

Leave a Comment

Please sign in to add a comment. Not a member? Join today