# Q about extended use of operators

## Q about extended use of operators

I was told that the standard math operators can be extended to include user defined

variables, such as what one would set up with a TYPE statement.

How does one tell the compiler what to do in those instances?

For instance, I want to use the * to refer to a DOT product of two vectors.

Like :

--------------------------------------------

type(vector)A,B,C

C= A*B

!  where A,B, and C are defined as follows:

type (vector)

integer nx

real(4) x(100)

end type

------------------------------------------

Likewise I would like the + and - operators to take the sum and difference of two vectors.

Or even one could do comparisons of absolute values:

if( A > B) go to 99

I was looking for an article about this topic, but I don't know what "lingo" is used to discuss this.

So I couldn't find it. Any suggestions?

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

C would be a regular scalar, not a vector,

unless one is referring to a CROSS product.

So S = A * B for example.

But maybe there is a way to tell the compiler to redefine another operator (ex: ** )

mean CROSS products? Or tell it what to do if one multiplies a scalar by a Vector?

Example:  B = S* A

where A and B are typed vectors, and S is an ordinary real(4) scaler variable.

Studying the many on-line references on Fortran operator overloading would keep you busy for a while.  As you said, the suggestions are to use * for a cross product rather than a dot product, which already has a standard intrinsic.

I realise this is an example but in the case of vector operations I really would not recommend using a derived type. The simple 1D array works just fine.

```Real(4) :: a(3), b(3), c(3)
Real(4) ::  magnitude, dot
a=b-c
a=b+c
magnitude= norm2(a)
a=a/magnitude
dot=dot_product(a,b)```

All of the above are quick, simple, understandable  and portable. They use intrinsics and require no coding. The only one you need to write is a simple cross product function (or subroutine).

Oh, sure, for simple 3 element vectors I WOULD do just that.

without getting involved in something much more complicated.

For cross products, I would do something like:

real(4) A(3),B(3), C(3), Cross

C = Cross (a,b)

Where Cross is a function that returns 3 element vectors.

Would I say real(4) Cross(3) or just what is above?

I have some books about Fortran '90, not sure yet whether this is adequately covered.

You would define an operator .CROSS. and write:

c = a .cross. b

This is not an overloaded operator, it's a user defined operator. The problem with overloading is that you can't redefine an existing signature, so if you wanted to overload an existing operator you have to satisfy the rules for generic disambiguation and make sure you're not adding a signature that matches an existing one. For the purpose you're describing, a user-defined operator makes more sense and is also more readable (given that assigning weird meanings to existing operators would be confusing.)

Retired 12/31/2016

IMSL has an entire chapter on linear operators: Chapter 10: Linear Algebra Operators and Generic Functions. One could use the defined operators (for matrix multiplication, inversion, transpose, etc.) in this chapter as an illustration of what can be done. Of course, one does not get to see how these operators are implemented, and it can be complicated while one is defining new operators to cover all the varieties of expressions where such defined operators could be used.

Any volunteer to provide code for defining .cross. and a simple example of it's use ?

I'd be interested to see an extension where the dimension of the vectors is general and not just 3, to see how arbitrary vector sizes are provided.

John

There are several issues that I need to reply to so I'll reply in separate messages.

First, I'll reply to the second issue that John Campbell mentioned.

Quote:

John Campbell wrote:

I'd be interested to see an extension where the dimension of the vectors is general and not just 3, to see how arbitrary vector sizes are provided.

John

The vector cross product is not an operation that can be generalized to an arbitrary number of dimensions.  I first learned this in my second semester course in Calculus and Analytic Geometry as a freshman at UW-Madison in the spring of 1974.  The vector cross product, as limited to non-trivial products with vector results, is valid only in three (3) and seven (7) dimensions.  See the Wikipedia article, "Cross Product":

http://en.wikipedia.org/wiki/Vector_cross_product

gfortran testsuite includes operator (.cross.) in gcc/testsuite/gfortran.dg/userdef_operator_1.f90

I'd like to follow up on Steve Lionel's last sentence.

Quote:

Steve Lionel (Intel) wrote:

For the purpose you're describing, a user-defined operator makes more sense and is also more readable (given that assigning weird meanings to existing operators would be confusing.)

IMHO, assigning weird meanings to existing operators is not just confusing, it is atrocious programming practice.  This practice violates just about all principles of good programming practice, most importantly, the Principle of Least Surprise.

You need to remember that multiplication, signified by *, is commutative.  I.e., C = A * B and also C = B * A.  This is not true with the vector cross product.  Instead, the vector cross product is anti-commutative.  I.e., if C = A .Cross. B and D = B .Cross. A, then C = -D.  I.e., the vectors C and D point in opposite directions, even though they have the same length.

Thus, it is far better programming practice to create a user-defined operator such as .Cross. to signify the vector cross product.

As John Campbell asked, I was going to provide a simple example of how to define a vector cross product and how to use it.  This example was going to be a shortened version of a module I wrote for vector operations in October 2011.  Due to the need for brevity, I did not include some of the functionality I had in the original module

However, when I tried to post the example, I got a message, "Your submission has triggered the spam filter and will not be accepted."

If there is some other way to provide the example I tried to post, please let me know.

Attaching the source file should work.

Retired 12/31/2016

The example Tim quoted is below. Personally, I think using a straight function call is more obvious /clear as this stuff isn't much used IMO.

```
module geometry

implicit none

interface operator(.cross.)
module procedure cross
end interface

contains

! Cross product between two 3d vectors.
pure function cross(a, b)
real, dimension(3), intent(in) :: a,b
real, dimension(3) :: cross

cross = (/ a(2) * b(3) - a(3) * b(2), &
a(3) * b(1) - a(1) * b(3), &
a(1) * b(2) - a(2) * b(1) /)
end function cross

end module geometry

program opshape
use geometry

implicit none

real :: t(3,3), a

a = dot_product (t(:,1), t(:,2) .cross. t(:,3))

end program opshape

```

As John Campbell asked, here is a simple example of how to define a vector cross product and how to use it.  This example is a shortened version of a module I wrote for vector operations in October 2011.  Due to the need for brevity, I will not include some of the functionality I have in the original module.  The type definitions could also be done with parameterized derived types (PDTs) but not all current Fortran compilers support PDTs.

The two attachments contain source code that shows how this is done.  The file Demo_Vector_3D_M.f90 shows how to define a 3-D vector and some operations, including the vector cross product.  The file Demo_Vector_Cross_Product.f90 show how to use a vector cross product  operator in a program.

Hope this helps.

## Attachments:

AttachmentSize
4.18 KB
1.36 KB

I looked at your examples, but I don't see how you told the compiler what to do with

".cross." you use as an operator.

In other words, is there a place where the compiler associates that with the actual subroutine?

Of course you also have to make sure that the compiler does NOT treat it as a commutative operator.

so you would have to define A.cross.B as different than B . cross. A

Quote:

billsincl wrote:

but I don't see how you told the compiler what to do with

".cross." you use as an operator

The idiom

```interface operator(.cross.)
module procedure crossproc```

tells the compiler to translate "term1 .cross. term2" to "call crossproc(term1,term2)".

The compiler is not expected to possess mathematical knowledge on topics such as commutativity, etc. The code for the procedure that implements the operator should satisfy the requirement that the result of the operation has the correct mathematical properties.

Quote:

billsincl wrote:

I looked at your examples, but I don't see how you told the compiler what to do with

".cross." you use as an operator.

In other words, is there a place where the compiler associates that with the actual subroutine?

Of course you also have to make sure that the compiler does NOT treat it as a commutative operator.

so you would have to define A.cross.B as different than B . cross. A

Bill,

Since you're asking very, very basic questions about enhancements to Fortran starting with the Fortran 90 standard, it may help you greatly if you study the various books which explain such topics in detail.  See Steve's recent blogpost on some of the new books.  I'd suggest you start with "FORTRAN 90 for Engineers and Scientists" by Nyhoff and Leestma, ISBN-13: 978-0135197295.  Studying these books will give you an all-around view and a far deeper understanding of "Modern Fortran" that simply cannot be offered by such forum posts and responses.

Thanks Craig and app4619 for your examples of the coding for .cross. They give me a good indication of what is required.

Bill, as A .cross. B = - B .cross. A, the example of "t(:,2) .cross. t(:,3)" has no ambiguity of order assumed.

I have always used a subroutine dcross (a, b, c) where C = A x B, rather than using a vector function. I'm not sure if I will adopt the use of .cross.  Given my recent interest in AVX performance, I wonder if adopting .cross. would have any benefit ?

Interesting topic,

John

It is my impression of F2003 and F2008 that the expanded language now provides for many alternatives for coding some basic approaches, such as vector algebra or list processing.

I'm with Bill in some of these, as it becomes difficult to identify if the new alternative syntax provides any benefit for solving the basic problem. While new syntax provides alternative ways of coding, which hopefully provides ways of expanding the range of problems that can be solved, they also introduce new ways of hiding coding bugs which means that no problems are robustly solved.

I need to broaden my horizons and look for new problems to solve, rather than redefining the problems I already have.

john

I am now looking thru the various texts on this topic, so I may be able to comment more intelligently later.

But the end purpose is to be able to pose complicated operations in a mathematically intuitive format - - -

Ex:

Z = A*B + C*D   - E* F as one would see in a Physics text,

instead of a long series of subroutine and function calls.

An example that does attached. I wanted to include the code but the new spam filters are a tad over enthusiastic.

An example that does attached. I wanted to include the code but the new spam filters are a tad over enthusiastic.

An example that does attached. I wanted to include the code but the new spam filters are a tad over enthusiastic.

And now it seems I've made three posts and not attached anything. What is going on with this forum????? I wrote 1 file called v3.f90 but it seems to be being renamed v3_0.f90 ... v3_3.f90. No idea why and no idea why it wasn't added to one of my previous posts, or even why those posts were made (since I didn't press submit). The preview says that the file is attached (with no name) so hopefully you'll be able to see it.

## Attachments:

AttachmentSize
2.28 KB

Coming into this a bit late so sorry if this has been covered.

An example for vectors is shown in Fortran 90/95 for Scientists and Engineers, by Stephen Chapman, page 505ff.

Linda

The following also works:

```program utest

implicit none
integer, dimension(3):: u, v, w
u = (/ 1, 2, 3 /)

v = (/ 4, 5, 6 /)

w = 3*u + 5*v

write(*,*) '3*',u,' + 5*',v,' = ',w

end program utest```

I am not convinced that the new way is such a step forward.

John

The point of the example was to show how to do what the OP was asking rather than comment on whether or not it was a good idea.

Personally I think the new way is an enormous step forward and that your code supports my view. The old way only works for POA (plain old arrays), even then it is limited. For example, if vector has all its components mod(.,7) then the new constructs allow that property to be separated from the application code whereas in the old world you have to add a call to mod(.,7) in the application code. And what of composite objects? I could have defined vector3_t  as

```type vector3_t
character(len=:), allocatable :: name
integer :: values(3)
contains
...
end type vector3_t
```

In some applications operator overloading is pretty much the only way to do it, automatic differentiation being one example, quaternions possibly another.

This new way is something I really like (along with associate), I'm now looking forward to parameterized derived types and the block construct.

@Simong #28.

The examples have been interesting however from a personal standpoint the functionality is not particularly useful to me. I concede we all have personal preferences in how we like to do things. Standard Vector operations are not really a suitable example, plain old arrays can be manipulated very efficiently and clearly as #27 and #14 demonstrate.

The use of derived types in this application adds additional overheads and makes vectorisation and other optimisations less likely. Making extra code to do something in a more complicated way does not seem like a good idea to me. Using standard array operations the code will always be 'inline' rather than potentially thrashing about in memory

Personally I think overloading standard mathematical operators is an exceptionally bad idea and hides what the code is actually doing. W=3*U+5*V is converted from what looks like standard Fortran into what happens in some hidden user code with some additional potential for bugs.

Stylistically we might prefer A .cross. B to cross(A,B) but at the end of the day the former is just an alias for the latter and does not confer any other advantage than the style.

Quote:

And now it seems I've made three posts and not attached anything...

I find it easiest to upload the files, submit the post, wait and see if the attachment has worked (you will get an indication whether it is going to work based on the state of the attachments area prior to hitting the final post submit button), then after the post has appeared - edit it, and use the MyFiles tab on the Select Media "dialog" to select the file that was uploaded but not attached, then resubmit the edited post.

I don't disagree that it's an enormous step forward for the compiler, although ifort ver 12.1 (XE 2011) did not recognise :
generic                        :: write(formatted) => write_v
I have never seen or was aware of the syntax to define a write format for a derived type.

The question I have is how many users of Fortran use or are aware of this language structure and is it good for the language to provide, what I am assuming, such a rarely used syntax. Given the changes that have taken place from F1995 to F2003 and to F2008, I wonder what F2020 might contain and how many compliant compilers will be available.

John

The examples that use a derived type to encapsulate the vector (particularly sgeard's in #25) offer expressive potential well beyond that available using an intrinsic array.

If you'll never need that potential, then - yes - there's little point using that style.  But that kind of misses the point.

For a simple example - consider what the code looks like if you have some vectors of vectors and you want to do some operations on them.  Consider if you want to customize the formatted output in some way.  Consider if you want to insert some validation or error checking code into the operations themselves.  Consider if the vector is really the internal implementation of some higher level concept as intimated in #28.  Etc.

I accept that inappropriate definition of the existing operators could create confusion.  But I could also write a procedure called Add that doesn't do what it says on the label, and merrily confuse all future readers of my code.  (In fact, the results of recent debugging indicate that is more or less what I have [inadvertently] done.)

I also accept with current compiler capability you may not get the fastest code.  But compiler capability is also constantly improving, and the ability to transform these higher level coding structures into efficient machine code is something that I regard as an important feature.

(On that topic - when the otherwise private procedures are accessed via bindings is the compiler able to see the "leaf" nature of the procedures and avoid the overhead associated with the use of a descriptor for the polymorphic argument?  If not, is that capability being considered?)

Restriction the discussion to language evolution (rather than compiler support of that evolution, which has an unfortunate but unavoidable lag) then the following two papers might be of interest.

The New Features of Fortran 2003.

There's always going to be tension between the level of use and familiarity with a language feature and the compiler support of that feature.

Where practical, you are better off pushing management of complexity and tedium up the chain to compilers and libraries (write once, test a lot, use many, many times) and free up the human programmers to do more abstract thinking type work (write once, test... maybe, use once).

"To each their own" - the standards extensions since Fortran 90 have been designed well to make this idiom quite applicable to Fortran developers - kudos to standards creators!  Hence those who wish not to make use of many of the new language features and enhancements are under no pressure to change.  But there is no need to question the march forward.  I wish the compilers would keep up with the change, or rather lead the change (as it used to be until F90).

I, for one, am finding great value in most of the new features of Fortran 2003 and 2008.  In applications involving numerical quadrature including ODEs and PDEs, I find my code written with OOP constructs, derived types with bound procedures, overloaded operators, generic programming, etc. to yield high-quality data abstraction and encapsulation while achieving better or similar performance compared to code written in FORTRAN 77 style, array-based, procedural paradigms.  In addition, I find it much easier to achieve thread-safety in the newer code, it is highly amenable to parallel computing, and increasingly scalable with multi-processor architecture.  For me, there is no looking back.

Another great benefit I am finding with all the new features is in being able to communicate with my colleagues in what is effectively the same "code design language" that they use with highly modern programming styles in C++, Python, C#, etc.  I can now illustrate my Fortran code design using similar unified modeling language (UML) constructs that they all can understand, I can implement various design patterns that they do as well.  In my world, gone are the days of "FORTRAN.. YUCK....".

Maybe I should have been a sheep farmer.

BAAAA !

Quote:

billsincl wrote:

Cheer up!

RTFM = "really tough for me" ?

Retired 12/31/2016

I goofed in one of the source code examples that I posted on Tuesday.  In the add and subtract functions in the Demo_Vector_3D_M module, I mistakenly used:

```C = A + B
```

```C%X = A%X + B%X
C%Y = A%Y + B%Y
C%Z = A%Z + B%Z
```

I.e., I should have written component-by-component definitions.  I am attaching a corrected copy of Demo_Vector_3D_M.f90 to this posting.

## Attachments:

AttachmentSize
4.34 KB

Quote:

Craig Dedo wrote:

... I should have written component-by-component definitions.  I am attaching a corrected copy of Demo_Vector_3D_M.f90 to this posting.

And, in those functions which have return values of type Vector_3D_DP_T, you need to declare the dummy arguments to be of type Vector_3D_DP_T instead of Vector_3D_SP_T (probably casualties of copy/paste?).

Quote:

mecej4 wrote:

Quote:

Craig Dedo wrote:

... I should have written component-by-component definitions.  I am attaching a corrected copy of Demo_Vector_3D_M.f90 to this posting.

And, in those functions which have return values of type Vector_3D_DP_T, you need to declare the dummy arguments to be of type Vector_3D_DP_T instead of Vector_3D_SP_T (probably casualties of copy/paste?).

Yes, you are correct.  Thank you very much for pointing out the mistake.  Yes, they were casualties of copy/paste.  Here is a second corrected copy of Demo_Vector_3D_M.f90.

## Attachments:

AttachmentSize
4.34 KB

Quote:

John Campbell wrote:

Thanks Craig and app4619 for your examples of the coding for .cross. They give me a good indication of what is required.

<snip>

I have always used a subroutine dcross (a, b, c) where C = A x B, rather than using a vector function. I'm not sure if I will adopt the use of .cross.  Given my recent interest in AVX performance, I wonder if adopting .cross. would have any benefit ?

Yes, adopting .Cross. instead of using a procedure reference would have significant benefit.  In a word:  readability.  It allows you to write your code in a more natural, straightforward style, just like you would write your problem on a piece of paper or on the blackboard.  It also allows someone else to much more quickly understand what your source code is doing.  The same expression using operators is much easier to read and understand than the equivalent expression using procedure calls.

Please keep in mind that using operators is in the original spirit of Fortran:  making life as easy as possible for the non-expert application developer to write correct, robust, and understandable programs.

Quote:

billsincl wrote:

I looked at your examples, but I don't see how you told the compiler what to do with

".cross." you use as an operator.

In other words, is there a place where the compiler associates that with the actual subroutine?

Of course you also have to make sure that the compiler does NOT treat it as a commutative operator.

so you would have to define A.cross.B as different than B . cross. A

Here is where the compiler associates the .Cross. operator with the actual functions that implement the operator.

```Interface Operator (.Cross.)

Module Procedure Vector_Cross_Product_SP

Module Procedure Vector_Cross_Product_DP

End Interface Operator (.Cross.)
```

As for your second question, the functions that implement the operator define how the arguments are evaluated and used within the defined operation.  By rules in section 12.4.3.4.2 in the Fortran 2008 standard, a defined unary operation maps to a function with one exactly argument and a defined binary operation maps to a function with exactly two arguments.  In the case of a binary operation, the left-hand operand corresponds to the first argument and the right-hand operand corresponds to the second argument.  Whether or not the operator is commutative depends solely on the statements that are in the body of the function that implements the defined operation.

Quote:

John Campbell wrote:

It is my impression of F2003 and F2008 that the expanded language now provides for many alternatives for coding some basic approaches, such as vector algebra or list processing.

I'm with Bill in some of these, as it becomes difficult to identify if the new alternative syntax provides any benefit for solving the basic problem. While new syntax provides alternative ways of coding, which hopefully provides ways of expanding the range of problems that can be solved, they also introduce new ways of hiding coding bugs which means that no problems are robustly solved.

I need to broaden my horizons and look for new problems to solve, rather than redefining the problems I already have.

I strongly disagree with this opinion.  Although there will always be ways in which to introduce coding bugs with new features, using modules, derived types, user-defined operators, user-defined assignments, and other features of modern Fortran will almost always reduce rather than increase the likelihood of undetected defects.  By rule, a module procedure always has an explicit interface, which means that mismatches in the procedure interface between the actual and dummy arguments will be caught at compile time instead of later.  Derived types are much more intuitive than surrogates because they much more closely model real world concepts.  User-defined operators and user-defined assignments make the source code much more readable than alternatives.

Quote:

FortranFan wrote:

Quote:

billsincl wrote:

I looked at your examples, but I don't see how you told the compiler what to do with

".cross." you use as an operator.

In other words, is there a place where the compiler associates that with the actual subroutine?

Of course you also have to make sure that the compiler does NOT treat it as a commutative operator.

so you would have to define A.cross.B as different than B . cross. A

Bill,

Since you're asking very, very basic questions about enhancements to Fortran starting with the Fortran 90 standard, it may help you greatly if you study the various books which explain such topics in detail.  See Steve's recent blogpost on some of the new books.  I'd suggest you start with "FORTRAN 90 for Engineers and Scientists" by Nyhoff and Leestma, ISBN-13: 978-0135197295.  Studying these books will give you an all-around view and a far deeper understanding of "Modern Fortran" that simply cannot be offered by such forum posts and responses.

Here are two books that I have found to be very useful.

Modern Fortran Explained by Michael Metcalf, John Reid, and Malcolm Cohen.  ISBN-13:  978-0-19-960142-4

The Fortran 2003 Handbook:  The Complete Syntax, Features, and Procedures by Jeanne Adams, Walter Brainerd, Richard Hendrickson, Richard Maine, Jeanne Martin, and Brian Smith.  ISBN-13:  978-1-84628-378-9

The first book is a very good exposition of all of the features of standard Fortran up to and including Fortran 2008.  The second book is a detailed, in-depth explanation of the features and syntax of Fortran 2003 but it does not cover Fortran 2008 features.  If you are unfamiliar with any version of Fortran later than FORTRAN 77, then you would benefit greatly from one or both of these books.

Craig Dedo # 44 wrote:
Although there will always be ways in which to introduce coding bugs with new features, using modules, derived types, user-defined operators, user-defined assignments, and other features of modern Fortran will almost always reduce rather than increase the likelihood of undetected defects.

I can not agree that increasing the complexity of the language will reduce the likliehood of undetected "defects". Having complex structures that are rarely used can not have this effect.

Given your experience on the Fortran committee, I would expect you would have considered what is required to minimise "defects". Providing complex and infrequently used code structures would not be near the top of that list.

As a Fortran programmer of over 40 years experience, the best advice I have had when writing code is the KISS principle. I agree that modules and derived types have been good and widely used features. I notice you did not include INTREFACE blocks in your list, which are flawed as they require code duplication. That few of us are able to implement overloaded or user defined operators without defects demonstrates the point I am trying to make, that increasing complexity will reduce the use of fortran.

I am answering questions from new users to Fortran and they are struggeling to understand many of the earlier features. While structures like modules were introduced as a very useful concept, we have recently seen levels of complexity introduced which very few will utilise. The danger comes when this complexity becomes a necessary inclusion in the language's use. These do not reduce the defects for newer users of the language and it will be the new users of Fortran that will carry the language in future years.

John

Quote:

John Campbell wrote:
...While structures like modules were introduced as a very useful concept, we have recently seen levels of complexity introduced which very few will utilise.

Speaking for yourself here!  It obviously depends on who you associate with, but a clear majority of those that I regularly interact with in the Fortran world are well and truly using on a regular basis some of the things that you appear to question.

As a practitioner of multiple languages, it becomes difficult to justify using Fortran for new code if the language fails to evolve in order to remain competitive with other options.

I'm not alone in thinking that - you only need to look at the precipitous decline in language use over the last few decades, despite the enormous sunk cost in tools, training and source code associated with Fortran.

The ultimate outcome of that failure to compete is language extinction.  That is a shame, because of that very sunk cost that I refer to above.  Consequently, I think the approach taken over the last two decades or so, of trying to coherently evolve the language in a manner that keeps it competitive, is completely appropriate and does the general Fortran community a great service.

Many of the new features introduced allow complexity to be moved from source code to compiler.  For anything other than trivial programs (which is the necessary domain of examples) that is the right thing to do.  That's just a natural continuation of the reason that higher level programming languages exist in the first place.  Compilers are good at managing that sort of complexity, humans are not.

Ian,

Where is this Fortran world ?
We Fortran programmers are humans and are being lead to code with an increasingly complex Fortran standard.
I see this as a problem, especially for new users.
I continue to write code that I must be confident will produce valid results for clients outside the Fortran world.
I choose a Fortran subset that limits coding and compiler bugs.
(I see many clients but few Fortran programmers !! Fortran forums provide me with an understanding of this rare but diverse group)

Actually, the main reason I have come to Intel ifort has been to understand how OpenMP and AVX instructions would improve run-time performance. After 18 months, I'm still trying to achieve and understand these performance gains. These issues are not addressed by F2003 or F2008, while the new features of F2003 or F2008 being discussed have minimal impact on my client delivery. This could explain our differing approach to this issue.

John

I'm referring to online communities, such as here, c.l.f., stackoverflow, various mailing lists, etc.  The number of captive technical programmers in the mob that I work for is so small and isolated these days that it might as well be zero.

The Fortran standard is of no greater complexity than the bulk of competitor languages or technology (perhaps arguably less, particularly if you ignore the legacy aspects of the language).  That hasn't stopped the decimation of Fortran's market share back to an all-but-niche position over the last few decades.  Increases in the complexity of the standard always need to be considered up against the resulting reduction in complexity of the code that humans need to maintain.

The language (in combination with compilers and IDE's etc) is one tool of the trade.  New capabilities get added to the tool (or competing tools become available) - you educate yourself and evaluate the relevance of those changes to your work and make a decision about if, when and how to use them.  That decision might quite validly be "no" in various circumstances.  Because the changes to the language have been made in a backwards compatible way (bar exotic corner cases) you do not need to change your practices, in isolation.

In the absence of language evolution, the issue that you will run up against with newcomers is that they haven't been exposed to Fortran at all, because the language will not be competitive and it will therefore no longer be taught.  I suspect this is already a problem.

OpenMP exists because people wanted to introduced "parallel stuff" into their code and the base language standards didn't support this out of the box.  There are two features in F2008 that directly address this want, one of which I reckon is one of the more substantial language additions ever made!

It's interesting that around these parts

(S Calif) there aren't ANY universities that teach the language.

So these graduating seniors think that C++ is the only language for solving a technical

problem. At JPL, though they do aggressively use Fortran 2008 for their high precision

technical work. That's because they always used the primitive versions back in the 60s and 70s when I was there.

I would like to teach it myself - I have two MS degrees, so I would qualify at least for a two year college.

But I don't think any universities or colleges are motivated to offer the course, unfortunately.

Do any of you know of ANY college that teaches the language? Probably MIT would.

In the US, very few universities teach Fortran, but in Europe and Asia it is much more common. I can tell you that a LOT of the programs I see from customers make extensive use of modern Fortran features such as modules, derived types and polymorphism.

I discuss some books on "Modern Fortran" here.

Retired 12/31/2016