Implementation inheritance has ruined careers and entire businesses, and everyone who ever had to maintain a code base that makes use of it knows that. See Eric Elliot’s experiences with it.
Or do you consider the account of someone who lost not only his job, but also witnessed the ruin of an entire business because of it, an equally “naive idea”?
Most of the C++ CFD and FEM codes I’m aware of make more use of templates than classical OOP programming techniques. openFOAM is a good example. Its basically just one big collection of templates. I think you can make a case that the introduction of expression templates and the libraries that were based on them are what saved C++ from being relegated to a niche language that was not suitable for scientific programming. That and the realization that the temporary array allocation required for operator overloading was a major contributor (maybe the biggest) to the poor performance of C++ in the early days wrt Fortran. This led to better compilers that could optimize out the temporaries.
I apologize if you took what I said personally… But, since you seem prone to attack anyone disagreeing with you, I won’t apologize for sharing an opinion.
In the world were I live people has used inheritance multiple times (no pun intended) and survived. Sometimes it’s the right tool for the job —I suppose you don’t agree with that either… and that’s fine.
Since what prompted this split thread was the different behavior when class is used instead of type, I’ve always wondered.
Fortran compilers seem to take the pure/elemental prefix hint very well, and computationally intensive operations seem to be dealt with just fine, but I’m not sure the non_overridable attribute is aggressive enough… if at all.
He didn’t say you were naive, he qualified an idea as naive, that’s quite different.
Coming back on the topic, I repeat something I said before: to me, Fortran has already gone too far in the OOP direction, whether the direction was good or not. Most of Fortran user are not software engineers but rather scientists who happen to develop (and I am one of them). And as such, they can mess any code by misusing advanced features (too advanced features for them, actually), whether these features are “good” or “evil”. I would have preferred Fortran to focus on his strengths (number crunching/numerical applications) rather than trying to make it a C+±like or Rust-like language.
Do you happen to have a multi-lib setup for your GPU code? If so, have you noticed significant differences in performance when your pure subprogram is defined in one library (even a static one) but used in another library|program?
No! But I can test it easily tomorrow morning. I compile my code into a shared library that I call from a python wrapper through a c API and performance is the same as when I do good old input files, though.
If you have a Pure routine called from a do concurrent loop that’s on the GPU that’s in another module it does not get inlined in nvfortran no matter the size and the performance is awful.
The hack is to write a pure implementation inside the same module or use OpenACC with acc seq I think Nvidia is fixing this at some point tho.
I was wondering if nvfortran did something different, given its focus around the GPU.
Performance-wise, I’m stuck with ifort for now, and its -ipo flag (i.e., the one that supposedly mixes/inlines stuff from different objects) tends to consume all the RAM available, so it’s not worth the effort (imho).
(ChatGPT explains the RAM usage by saying that the object files are “decomposed” and detailed info considered, but it seems odd that in order to produce a 30 MB executable, ~64 GB of RAM are required.)
Not to defend particular OOP features, but I think this criticism of OOP being out of bounds is a bit off base. Folks who don’t want or need it shouldn’t have to fuss with it (unless the folks creating code you are importing have exported OOP interfaces).
As for those people exporting such interfaces … it can simplify things for users, if/when used well.
The point of objects in Fortran was never to make it a “comp sci” friendly language; it was intended to provide facilities that would enable library providers to shield users from complexity.
How, for example, sparse matrices are optimally stored can be hw dependent. If the consumer only has to specify “my_sparse_matrix” as a kind of object, the library can do all sorts of crufty stuff under the covers (possibly dealing with clusters with various cache sizes, multiple tiers of memory, etc.)
Whether the committee achieved optimally usable facilities, or if sw developers have leveraged the facilities well are different questions than “should OOP have been introduced to Fortran”.
Recently in C++ documentary, someone said “you have to introduce features to your language carefully, because you can never take them back”.
Fortran is not Python (in terms of popularity) to ever be able to afford breaking backwards compatibility. (Something may be named obsolete and emit compiler warnings, yes, but you can never truly remove it from the language).
I may be off-topic here, but I wanted to share a couple of my humble gripes about Modern Fortran OO. The features I think are lacking, comparing with C++ OO, are destructors and constructors.
MF provides structure constructors, but they are not the same as C++ constructors, which are functions that automatically run whenever a new object of a given class is created. They are much more versatile than structure constructors.
About destructors, of course I know that MF provides finalizers, but they are not automatically called when the main program ends. Some people suggest enclosing the body of the program with BLOCK - END BLOCK statements in order to call the finalizers when the program ends, but I think this is unappealing, aesthetically speaking.
Maybe you’re assuming that only the default constructor invocation is possible?
You can have as many specific functions as you want, acting as constructors (in the TKR-generic terms), provided the compiler can distinguish them from the default one, say:
type, public :: t
...
end type
interface t ! this is also public
module procedure t_new1
module procedure t_new2
...
end interface
I agree with you that the non-invocation of destructors from the main-program unit is… interesting.
But destructors not being invoked right before the program is about to end, really only matters if you’re relying on some side-effect to the destruction of the object itself.
Maybe a defer mechanism (like Go’s or Zig’s) could be proposed for the next revision? (the next ISO C will have “deferred blocks”, so it might not be hard to sell). Something like
db = fancy_database(...)
defer call db%close()
...
Indeed, but you have to specifically call the procedures in the code, not like C++ constructors which automatically initializes the object upon instantiation. Of course, if you prefer, you can include other functions as specific methods for a given class and then manually call then, as with MF.
Fortran’s default initialization of derived type instances already does most of that.
So the only limitation is that the default initialization doesn’t consider allocatable components (or pointers requiring complex initialization), am I right?
This is exactly the aspect I find lacking with the finalizer. In an application, I wanted to automatically save data created with specific methods and stored in a temporary memory when the object is destructed by the end program statement.
Yes. A means to pass information to the constructor upon instantiation that is not covered by the parameterized derived type mechanism. Something like parameterized constructors in C++.
That’s not that simple. Modern Fortran standard has got huge compared to F77 standard, and consequently its implementation in compilers is more and more complex.Admittedly this is not specific to Fortran, C++ has the same trend. But the consequence on the compilers is visible : there are less and less different Fortran compilers because it’s much more difficult for a small team to develop one than it used to be. And most of the ones that remain don’t even reliably implement the most advanced OOP features. Fortran is now a niche language and not a lot of resources are allocated to it, and the developers have to make choices on the effort spent for the implementation of a given feature.
Sure, and my point is not to say no OOP at all should have been put in Fortran. But I would argue that for this kind of need only basic OOP is needed.
it’s much more difficult for a small team to develop one than it used to be.
During the years I was at Sun, the Standard grew tremendously, the size of the Fortran team did not. The backend team(s) were larger. The size of the language is only modestly challenging for the front end (there are things that make the front end really hairy, like error recovery and good user error/warning messages) and inconsistency in features …. but language size itself wasn’t particularly challenging.
And most of the ones that remain don’t even reliably implement the most advanced OOP features. Fortran is now a niche language and not a lot of resources are allocated to it, and the developers have to make choices on the effort spent for the implementation of a given feature.
This is the more compelling issue, niche and since optimization is critical to Fortran (moreso than many other environments), and for peak performance there’s a lot that the front end needs to communicate to the backend that simply isn’t there in most other languages (so the backends don’t automatically have all the required hooks and functionality), as well the cost of QA … shrinking pie has many undesirable effects.