It would be interesting to try and compile with fpm. I had a quick look at the project build scripts and it would appear that it would require some work to get this working.
What’s your point? I expect it to be the classic two-language problem argument Julians like to use.
There are a few C and C++ files, which is not unusual for a project of this size. If your are referring to the (ab)use of the C preprocessor in Fortran files, after the preprocessing stage is complete what you get is Fortran.
My point is: Fortran is not powerful enough for this kind of project. Let us not pretend it is. It needs a lot of hand holding from the preprocessor here. (Of course, the structure of this particular sw is not that impressive, even though the capability certainly is.)
Are C and C++ also “weak” languages since they use a preprocessor? And yet, so much of our world depends on them. Would you call any project or programming language that uses a macro preprocessing language not powerful enough for the job? Where do you draw the line? If I want to calculate the result of a formula containing a logarithm, and I read the value from a log table since I don’t know the series approximation, am I pretending to be doing math?
I think Bjarne Stroustrup captured the ethos of Fortran programmers who write such simulators when he said:
Fortran is harder to compete with. It has a dedicated following who […] care little for programming languages or the finer points of computer science. They simply want to get their work done. (emphasis added)
I can certainly agree with your comment about the structure not being impressive. If a team of Julia programmers (or any other language for that matter) want to create a competing product I applaud their determination and hope they can extract a few lessons from this solver.
Actually, yes. C and C++ are often criticized for having to rely on a preprocessor!
But my comment was directed at Fortran. It would appear that in order to put together software of this complexity, the facilities of the language are insufficient by itself. I do not know if the newest Fortran would be a match to this, but perhaps some expert would chime in?
I wrote a lot of Fortran in the past, and I myself ended up preprocessing it with M4 and the build became quite complex and hard to explain to other people. The build of the Radioss project is a tangle too. That is really what modern languages such as Julia got right: the package manager makes building almost invisible. Hence portability and reproducibility follow.
Technically you could replace the C-preprocessor #include with Fortran’s standard include syntax (no hand-holding in that case, but I doubt this argument will convince you otherwise). From a cursory look they are mostly using #include to bring in common-blocks (an obsolescent feature). They could probably refactor a lot of the ugly preprocessing with modules, submodules, parameters, and a few other Fortran features. I bet some things could also be handled cleaner using newer features of the build system (CMake). As to why these features aren’t used, I guess it’s a matter of taste (cough ignorance) of the Radioss team or constraints related to the environment (compiler versions) their code is deployed in.
I guess I can see this argument in some technical sense, but in a practical sense it is spurious. There are all kinds of reasons why a preprocessor is useful that have nothing to do with the power of a language. Any time there is machine-dependent code, then a preprocessor can be used to select the correct branches and, just as importantly, to ignore the incorrect branches. Machine-dependent code can arise from making operating system calls, or using special hardware that is available on some machines but not others, or different byte/word lengths or orderings, or different floating point representations, and on and on. None of those have much if anything to do with the language itself.
There are other ways to do conditional compilation, for example having multiple files with various versions of different routines which are then carefully selected by the build process for each machine/os/compiler combination. Sometimes that is a useful approach, but often a preprocessor is the best approach.
The c preprocessor has been used within fortran codes as a de facto standard for about 40 years. In my opinion, it should have been standardized in the early 1980s by the fortran committee (along with the MIL-STD extensions), but for various reasons, that did not happen. But programmers have continued to use the preprocessor all these decades since, mostly for conditional compilation, because it is the best solution to a common problem. A problem that will continue for the foreseeable future.
Have you been using GPUs on different machines that have different instructions, or different memory capacities, or different library interfaces for the last 20 years? Are you doing so now? Do you plan to do so in the future? If so, then you might well benefit from a standardized preprocessor capability. Are you running your codes on more than one version of Unix, or on both Unix and Windows machines, or on other operating systems? If so, then you might well benefit from a standardized preprocessor capability. None of those things have anything to do with the power of the language.
Actually, Julia enables configuration for the different computing paths (CPU, GPU, accelerators, …) without a preprocesor. Everything is just Julia code.
There are broadly speaking 5 areas where Fortran suffers when it comes to an application of considerable size and heft (you may include Altair Radioss if you would like to though it comes across as medium size):
Fortran currently has considerable limitations when it comes to Generics which can lead to code duplication in the absence of Fortran’s INCLUDE file facility. To avoid code duplication is one area where a preprocessor such as @aradi 's Fypp can help considerably. But outside of that there is very little need for preprocessing with Fortran.
Fortran’s module facility is outstanding for code development and consistent consumption of types and constants and data in large codes. However the standard and the processors (think compiler vendors) didn’t/couldn’t agree on options to make it easier for practitioners - no standard file format, no cross-platform compatibility, etc. Thus in reality. the practical aspects of build and package management across different platforms and compilers with MODULEs is a nightmare.
FUNCTION subprograms, unlike SUBROUTINEs, in Fortran have little support built into the language toward run-time exception handling which places significant limitations with their use and forces APIs to move toward SUBROUTINEs which can prove inadequate. Even with SUBROUTINEs there are issues to consider with the use of Fortran with codes where the program MAIN is defined by means other than a Fortran processor.
Certain language goodies that all modern languages have e.g., ENUMs, BITS type (or unsigned char/int) are entirely missing or horribly inadequate which makes many advanced programmers, esp. in industry, who are used to certain good coding practices (no magic numbers in code and easy, convenient ways to consume mnemonic constants, for example) not even consider Fortran for any modern/new code development.
Tooling around Fortran lacks those with other languages but the situation is fast improving thanks to tremendous contributions by the Community here.
Nonetheless what I see is tremendous potential with Fortran: a lot of the syntax and the facilities in modern Fortran are far more simpler and user-friendly to scientists and engineers and also highly performant.
If the Fortran language committee can succeed in addressing the 4 items above, then Fortran can be a far better option for large scientific and engineering applications than other languages out there.
Alas, it will take decades and time is one thing that is not on the side of Fortran. The scientific and technical computing domains would have moved far away from Fortran by the time it can right itself in the pending areas.
Since Julia operates at a higher level it isolates its users from the hardware better. The platform specific preprocessing details remain, but just hidden a layer deeper, for example in the JIT (julia/jitlayers.cpp at v1.3.1 · JuliaLang/julia · GitHub), users wishing to call different C or Fortran functions depending on the platform may use the @static macro and Sys calls which get handled by Lisp-like metaprogramming facilities. Sure it’s much more elegant than the non-standardized Fortran preprocessor tools.
Some platform control still remains in the form of environment variables (Environment Variables · The Julia Language), e.g. JULIA_LLVM_ARGS, and the command-line arguments. I would argue the situation with Julia is also slightly different because there is a single implementation.
As far as I’m aware you also can’t have static Julia executables on Windows; I’m also not sure if there are facilities for cross-compilation? I guess a lot of things are possible with the LLVM backend, but are they comprehensible/exposed to the average scientist like me?