Resistance to modernization

I am still coming to grasp with Fortran, and therefore have nothing of substance to add to this discussion.
I will however leave the wise words of Mr. Bjarne Stroustrup

Disclaimer in advance: I only worked in a relatively small group (astrophysics) and are no longer professionally involved in Fortran programming. However, I do not think that this constellation is unusual.

Maybe the *PACK routines and SLATEC are kind of special cases, because a huge (partly used but no longer really maintained) legacy codebase depends on them, so any change on their interface would break a large amount of code that itself may be used for years, but only very limited manpower is available for their maitainance.
So these codes are often used as black boxes and most users are okay with ‘if it is not broken do not fix it’.
Sometimes there might even be the case where nobody still working in the institution really understands these codes.
I agree that this is a serious red flag where the code has practically become unfixable and will likely be dropped completely in one point in the future. Furthermore, one could argue that these codes could use the “legacy” versions that become frozen and the rest moves on.

While, for a lot of numerical problems these libraries are just good enough,
outside the pure numerics part usually (e.g. for GUI, visualization, networking) usually other languages are used. Becoming a language used singly for one language purpose, which might be problematic.
Actually for a lot of people (certainly not everyone) the ability to use Fortran flexibly for new code may be more important than the way the “classical” libraries are written.

So I am thankful that a lot of the people here in this Forum contribute to a more accessible and flexible Fortran environment (gfortran/lfortran, fpm, stdlib, bindings to often-used libraries, documentation, … ). Actually, I think that the accessibility and flexibility of Fortran has really improved. Of course, this is also true for other languages.

4 Likes

I mostly agree with you, in a broader sense, but I would be cautious to take the Julia adventurous attitude (understatement) as a model to follow. The practice of get to a rewrite with such a small “pondering barrier” has lead to many problems therein. They even rewrite pure Julia libraries from one day to the other, without the previous version even becoming really mature. This for one point buys a lot into their stereotype as an unstable and “too young” language/ecosystems, and more importantly in practice leads to huge correctness problems. A full rewrite (which is far more disruptive of any modernization we were discussing here) must come with an unavoidable assumption that it introduces bugs. They seem to overlook too easily that view.

But maybe you were more about venting about the (frustrating for sure, I agree) resistance on implicit mapping removal, then actually praising Julia… otherwise I would guess you’d went on their boat long time ago :slight_smile:

1 Like

Anyway, my humble perspective as a PhD student that is slowly transitioning from using matlab for everything he codes and just using occasionally fortran codes from senior scientists/supervisors, to diving deep into fortran development himself:

  • coming from matlab I quite like modern fortran, and I’m especially exited about the far better facilities for structured code and libraries (quite hating matlab idiosyncracies with namespaces and so fort…)

  • so I’m actually eager to learn more about modern fortran and somewhat impatient with new features to come available: tried to inject some f2018 stuff into my group codebase but in the end could not manage to merge the “modernized version branch”, falling back to a the limited “standard f90 way” in my patch, cause the reviewer (although genuinely excited) was a bit worried about compiler support on some hpc systems we use, so ended up saying “for now let’s do the current way, but let’s keep an eye on it for the future”.

  • I can see my future self to be a modern fortran expert and kind of enjoy the idea

  • I don’t come from old fortran and know basically nothing about it… neither I want to spend any time learning that

—> for my future career I’m a little worried that collaborators and potential employers would expect me to be able to work or at least “deal” with legacy fortran code, which I’d be hesitant to tackle for the reasons mentioned above. So… is there really a place in the world for future modern-only fortran experts?

So, wrapping up the point, a benefit of modernization that I have not seen discussed here is this one: ensure that a potential young modern fortran expert is actually valuable in the (potential future) market, without requiring him/her to know anything about legacy FORTRAN practices. I believe the general feeling about this kind of implications could really “move the needle” for young programmers, when it comes to choose if invest time on fortran development / learning, or move to the “classic” python / C++ world. Probably it might do for me, at least.

7 Likes

I am going to create another thread on this (whole vs explicit) soon with my observations.

1 Like

https://www.researchgate.net/publication/362680171_An_Automated_Tool_for_Upgrading_Fortran_Codes
(full text available)

Open Access:

(Note that this paper is citing “The State of Fortran”)

3 Likes

Interesting paper by Mak and Tayeri, it’s good that they cite “The State of Fortran”.

So many tools that have been available over the years for Fortran modernization but due to the wrong definition of what is “broke” in the minds of certain key influencers, legacy codes appear stuck, starting with implicit typing:

image

2 Likes

This comment surely must have pegged the internet irony meter. :wink:

1 Like

I agree, but i wish that implicit typing was the worst ‘stuck’ legacy feature. If DATAPOOL disappeared quite a few aircraft would be grounded and the lights would go out in several places. If STRUCTURE/MAP/UNION disappeared the lights would definitely go out in central Europe.

One issue which does concern me is that legacy constructs should not be replaced if doing so significantly reduces performance. I think we might open a new thread on this issue.

1 Like

I can think of many instances of this. The problem is that nonstandard legacy features were often added to take advantage of some specific hardware or software feature. Then when that functionality is standardized, it must be emulated on other combinations of hardware and software, introducing some extra levels of overhead even on the original machine when compared to the original legacy implementation.

One example of this is the matmul() intrinsic, which is being discussed in a couple of other threads now. When first introduced in the 1990s, matmul() was always slower than whatever was being used in the legacy codes, sometimes by large factors of ~10x or ~100x. So programmers had the choice of writing less efficient standard/portable code, or writing more efficient nonportable code. Over time, as the performance of matmul() improved, more programmers switched over to the portable solution. But even now, some three decades later, programmers still call other library routines for this purpose, such as dgemm(), etc.

Another example might be using direct calls to MPI to implement parallel algorithms, compared to a standard (and arguably simpler) fortran coarray solution. Particularly when coarrays are implemented on top of an MPI library, it is clear that the MPI solution always has the potential to be more efficient. So the programmer must decide which is more important, and that decision can change over time.

I do not know of a general solution to this problem.

1 Like
  1. Make a language which gives developers the tools to develop robust, efficient and easy to use libraries
  2. Make a build system which makes it easy to pull in third party dependencies from the community

The tradeoffs between simplicity, flexibility and performance is different for each use case. Finding a one size fits all solution is impossible for anything but the most trivial problems.

One of Fortran’s biggest mistakes has been to repeatedly think that compiler vendors are the only ones capable of making these decisions for their users.

7 Likes

It is difficult to say what the biggest mistakes have been, there are so many to choose from over its 60+ year history. From my perspective, it was the contentious years in the 1980s when hardware was changing so quickly, it was difficult for standard fortran to keep up with the demands from the users. This was a broad issue, there wasn’t just one feature that was the make-or-break deciding point.

However, I once saw a talk where the speaker made the case that computer languages die not just because of a lack of some features, but more often because some half-baked feature is introduced to the language that turns out to be a bad idea. Once a feature like that is added to a language, it usually ends up killing the language. It is easier for programmers to switch languages, or even to start over with a new lanaugae entirely, than it is to remove a feature and have the remaining language survive.

I would say that fortran has not made that fatal mistake. Implicit save is maybe the worst feature that has been added to the language, and as annoying as it is, it doesn’t rise to the level of threatening the survival of the language. Others complain about implicit typing, which I also think is at worst a minor annoyance, and in the end is mostly benign; my feeling at this point is that it would do more harm to the language to change it than to keep it as is. Parameterized data types have been difficult to implement, but I don’t see the argument that they are such a bad feature that they threaten the survival of the language. There are some object-oriented features that I think are more difficult to use than necessary, but again I don’t see those things threatening the survival of the language itself.

So at least from my perspective, fortran does appear to evolve too slowly rather than the other mistake. One sign that the language itself is in a good position is to watch the threads about new language features. Many of those suggested features are basically just syntax sugar, making something a few keystrokes easier to type, and not really adding new functionality to the language. When those kinds of suggestions dominate the discussion, then you must conclude that the language itself is in good shape.

Let’s take an example. What happened to ADA? It was designed in the late 1970s by experts who were all well aware of the language trends of the time. It had the support of US research and academic funding agencies in the US. At one time, the Department of Defense attempted to phase in a mandate that all software written under its contracts must be programmed in ADA. Yet it barely survived the 1980s, and today I seldom even hear anyone mention it. What was its fatal mistake, or mistakes?

2 Likes

For me, if a person wants his/her code to work well (potentially work better) in the future, then the only reasonable choice is obviously to adopt the “standard (and arguably simpler)” approach.

Anyway, isn’t it a strange paradox if we introduce some (new) feature into the standard while not encouraging or even discouraging people to use it? I can never understand it if that is the case.

Anyone who codes for the future should STOP optimizing/tuning his/her code in an ad-hoc or case-by-case manner (if you only care about the performance of your code for today, this statement does not apply to you). Otherwise, either the compiler vendors will not be motivated to do the optimization that they should do, or the ad-hocly optimized/tuned code will not benefit (if not become suboptimal) when the compiler vendors do such optimization.

I am not claiming that the optimization on the compiler side is trivial. It is hard. We all know that and I appreciate any effort in this direction. However, I won’t agree with any argument that it is impossible or a bad idea — it is something that has been done and praised in MATLAB since last century. It is the very (if not the only) reason why MATLAB has been popular among scientists and researchers. It enables the users to focus on the mathematics and logic of the algorithm being coded instead of the hardware that will run the code — doesn’t this align with the original motivation of Fortran, i.e., formula translation?

Let the professionals do the professional things. This is how science and technology advance. Let’s give Fortran a chance to advance.

3 Likes

Well, I am a little torn about what to think in this regard. Generically I strongly agree with your viewpoint (which indeed has proven successful with matlab or scipy) but not everyone in bleeding-edge research would “code for the future”. There could totally be use cases where you want the fastest implementation you can get, to be used in production now. That’s why flexibility is important and, although I agree that new features should be indeed advised and encouraged for the generic user, I would make sure that the “lower level way” (so direct MPI calls in the example) remains viable and well documented. Especially given the slow pace of Fortran development (which has both good and bad consequences), conceiving only the “do the general way and wait for the professionals to do their thing” may be too restricting.

2 Likes

I think there are (very roughly) two patterns for a language to survive: one is to provide sufficient tools for library developments (as just written above), which is I think one of the reasons why C++ is actively used, and the other is to provide a lot of useful features and libraries out-of-the box for user convenience (Python and Matlab may be this pattern). Julia (and other languages) may be pursuing both at the same time. In this sense, I feel Fortran currently does not meet both the end of the spectrum, i.e. do not provide useful tools for library developments (a set of builtin containers, generics, metaprogramming, etc), while not providing a lot of convenient functions / standard libraries out-of-the-box (so the user often needs to “reinvent” things commonly available in other languages). One hope is that generics is now under consideration, but (as far as I am aware) there is little consideration for various containers (despite there were a lot of requests in the survey a few years ago, if I remember correctly…).

5 Likes

I think Ron’s comment above is very similar to the tone that I often find from the comments by the standard-committee people (e.g. found in the J3 mailing list or Fortran proposals). Here, I would like to ask this question: Are various features in the standard library in C++ (e.g. std::vector or std::string) a “syntatic sugar” (so not much useful in your opinion?), because you can create a similar thing / routine with pointers and malloc()? How about Coarrays? (I think one could say it is a syntatic sugar to MPI.)

Here, I think the key point is to what extent a given feature can reduce the development time for users (or increase the productivity per given coding time).

3 Likes

I’m not sure how this fits in with the discussion, but there are also shared-memory implementations of MPI. Also, some implementations of MPI look at the source and destination process addresses and pass the message in different ways, depending on whether the two processes are on the same core, different cores of the same cpu, different cpus on the same compute node, on nearby compute nodes, or on distant compute nodes.

Another feature of MPI is that it also has its own standardization process, there is a committee of people who decide which features to include, which kinds of networks and communications to support, etc. I remember 20 years ago when coarray fortran was first being developed, many thought that the effort should instead better be directed toward the MPI standard and implementation processes. In hindsight, I don’t know if that was a good or bad idea. For example, MPI has not kept up very well with fortran developments over the years; if coarrays had not been introduced into fortran, then perhaps there would have been more pressure on MPI to keep current.

“The nice thing about standards is that there are so many to choose from.”
-A. S. Tanenbaum

1 Like

I do not know the details of C++ well enough to answer that. I will say however, that there is essentially a continuum of possibilities between trivial syntactic sugar features and essential features. Sometimes, even if something can be done easily (with pointers and malloc, for example), it is still a good idea to standardize it. Imagine two different libraries that implement their subroutines with their own pointer+malloc+whatever features in incompatible ways. When a programmer wants to use both libraries at the same time, then he must copy/convert his data back and forth between the two conventions. This fosters both frustration and computational inefficiencies. In contrast, if that feature were standardized, then libraries that use that standard implementation can both be used easily with no unnecessary conversions.

I would say that if various people, including the J3 committee, say that some feature is syntactic sugar, then maybe it really is.

One of my personal beliefs is that DOUBLE PRECISION should have been designated obsolescent long ago. Maybe in the f95 revision. The KIND facility introduced in f90 encompasses and surpasses that older convention, and there is no need for any new code that is ever written to use DOUBLE PRECISION, or “D” exponents in constants. Compilers should print warning statements whenever they encounter these things. However, due to backwards compatibility with 60+ years of legacy code, I do not think those things should be deleted from the language, probably ever. It is just something that fortran programmers must know about, even if they never use those features. So that is some syntactic sugar that I’m willing to live with.

Also, I think we should have a COMPLEX(x,y) intrinsic function to convert from real to complex variables. It should be defined roughly as CMPLX(x,y,kind=kind(x)). One might argue that this is just syntactic sugar, since the functionality clearly already exists, just with some extra typing. But in this case, the problem is that CMPLX(x,y) looks like it does the right thing, but it really doesn’t. It is misleading, even to experienced fortran programmers. Also, I think that the compiler should warn the programmer whenever CMPLX(x,y) is used without the kind argument, even if the kind argument is redundant. That is just an accident waiting to happen.

1 Like

I somehow both agree and disagree with this perspective. Certainly MPI and coarrays have much overlap in implementation and capabilities, where they do exactly the same thing in exactly the same way, just with different syntax. As I said previously, MPI has not kept up with changes in fortran very well. It was developed in the f77 era, so it does not necessarily do things well with array stride expressions and derived types and pointers and so on. Coarray fortran, being part of the fortran standard, does know about those things.

MPI, somewhat like the fortran standard, does not specify the low-level implementation. It just specifies the programmer interface and some of the high-level semantics. Message Passing Interface, it is right there in the name. It allows for such things as heterogeneous processors, or even compute nodes that are running mixtures of codes written in different languages, which I’m not sure coarray fortran can do (anyone know?).

So while the two are definitely different, I’m not sure that “syntactic sugar” is entirely wrong either, and not in just a reductio ad absurdum way.

1 Like

This is yet another justification for “if a person wants his/her code to work well (potentially work better) in the future, then the only reasonable choice is obviously to adopt the ‘standard (and arguably simpler)’ approach.” Ad-hoc approaches do not really help the advancement of Fortran.

After making the choice, wait for, urge, or preferably help the professionals to do the professional things, namely, to improve the performance of the standard approach.

Standard approaches are the core strengths of Fortran. Ad-hoc approaches are important, but they represent less of the core strengths of the language. It will be strange if the community does not invest more in the former.