Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default Modern Fortran flags #359

Open
epagone opened this issue Feb 15, 2021 · 32 comments
Open

Default Modern Fortran flags #359

epagone opened this issue Feb 15, 2021 · 32 comments

Comments

@epagone
Copy link
Contributor

epagone commented Feb 15, 2021

TL;DR

This proposal aims at collecting and setting up with fpm a modern Fortran environment by default (e.g. no implicit typing, no fixed form, etc...), without requiring any change to the current compilers behaviour or the standard. Packaging of important legacy code (of critical importance for much of the Fortran community but usually requiring special flags regardless) would be supported overriding the mentioned defaults.


As of 2021 no one should reasonably write Fortran

  • in fixed form
  • with implicit typing (thus making implicit none redundant as obvious)
  • using "implicit save" of module variables
  • what else? Please suggest.

I believe that fpm should provide default, overridable compiler flags enforcing the above. In this way, a little bit more dust and rust will be hopefully removed from the perception of the language to potential newcomers. Furthermore, since these changes are difficult to implement into the standard, fpm can be also presented as the only, long-awaited solution (by some practitioners, at least) to these issues.

Packaging of legacy libraries would likely require regardless a tailored fpm.toml thus, it would be a matter of adding a few more specifications to override the above defaults.

In more detail.

Fixed Form

This idea started from this conversation where I dream of reclaiming the .f extension for new code without resorting to the current, Jurassic .f90 to specify free from. The only potential issue that I foresee in this case is that legacy dependencies will be compiled with different flags but, if I understand correctly the logic of fpm, this should not be an issue.

However, it would be really amazing if fpm would be able to autodetect the source code form, as @ivan-pi suggested here, but I guess that it would require quite a lot more work.

Implcit typing

This sounds pretty simple to do, e.g. -fimplicit-none with gfortran or -implicitnone with Intel Fortran.

Implcit save

Is this possible? Googling, I have seen that with gfortran -frecursive might do the trick but I am not sure if it is really the case and if it will trigger some other side-effect undesired in a "default" setup (Intel seems to have -recursive).

What do you think?

@everythingfunctional
Copy link
Member

As much as I'd love for fpm's defaults to encourage modern best practices, our desire for legacy codes to be ported to fpm packages and encourage "legacy" programmers to use it, means it's probably a no-go for a lot of our target users.

That said, I would love for us to have a convenient option to turn lots of this kind of stuff on. As I mentioned in the discussion for my proposal for how we might deal with the compiler flags (#350), I think we should have an additional built in "profile", kind of like --release but --strict (or something along those lines) and these would be reasonable additions there.

@everythingfunctional
Copy link
Member

Another thought, perhaps we should have some sort of survey/poll for each supported compiler about what flags should be included in the default (--debug) set. There would be 2 possible responses for each proposed flag:

  1. Please don't turn this on
  2. Please turn this on

Thus, if a certain percentage of respondents (say 10-15%) say please don't turn this on, we won't, even if there is a large percentage of respondents who would like it. If a sufficient number of respondents indicate they would like it (25-30% ?), we turn it on by default. Thus a non-response to a particular flag indicates ambivalence about it for that particular respondent.

The hard part will be setting up the survey with a reasonable set of flags to start with, and allowing participants to add additional suggestions. Does anyone know of a polling site that could accomplish such a thing?

@awvwgk
Copy link
Member

awvwgk commented Feb 15, 2021

I was thinking about introducing a ~/.fpm/config.toml which allows to define additional compilers and maybe even overwrite built-in ones. While this goes against having reproducible environments in a way, a --custom build mode drawing from this configuration might work. Submitting a compiler profile as feedback to us might help us fill in missing compilers and refine existing compiler profiles.

@epagone
Copy link
Contributor Author

epagone commented Feb 15, 2021

As much as I'd love for fpm's defaults to encourage modern best practices, our desire for legacy codes to be ported to fpm packages and encourage "legacy" programmers to use it, means it's probably a no-go for a lot of our target users.

Fair enough. I note that I never met a single example of such "legacy" programmer that still actively writes code in fixed form and with implicit typing. The vast majority of them leverage libraries (making occasional modifications) of legacy code that could be packaged with fpm without perpetrating and inflicting to the entire community ancient practices.

@milancurcic
Copy link
Member

I would also like to reclaim .f.

As a new and radically innovative (for Fortran standrads, at least) tool, we have a unique opportunity to set the tone and recommended best practices, and even shift some long trends. Trends become trends because one or a few people decided something, and many just took it and accepted it without questions.

Why do we have an idea of which source file suffixes correspond to fixed or free format? Because existing compilers told us.

fpm should start with a clean slate and define its own conventions. Do we want fpm to always assume free format and explicit typing? I think so. But allow a flag (e.g. --legacy) to build valid legacy Fortran code. Having to add something like --legacy will serve as a gentle reminder for the user to update or modernize the code, if feasible.

@FortranFan
Copy link

Given issues such as "implicit save", it'll be awesome if the Fortran enthusiasts with fpm and stdlib projects can consider venturing a bit into compiler development also, particularly with open-source ones in GCC/gfortran, front-end(s) to LLVM, etc. That way, some added empathy can be brought forth toward Fortran practitioners.

This can then help Fortranners try out options such as -fno-implicit-save (just an illustrative example consistent with GCC/gfortran compiler option syntax) which might then flag an error at instructions like <type> :: var = val on account of the explicitly missing SAVE attribute in the declaration statement.

Outside of something like this that gets into the compiler side of things, I don't see what fpm can do with implicit SAVE.

@epagone
Copy link
Contributor Author

epagone commented Feb 15, 2021

Given issues such as "implicit save", it'll be awesome if the Fortran enthusiasts with fpm and stdlib projects can consider venturing a bit into compiler development also, particularly with open-source ones in GCC/gfortran, front-end(s) to LLVM, etc. That way, some added empathy can be brought forth toward Fortran practitioners.

This can then help Fortranners try out options such as -fno-implicit-save (just an illustrative example consistent with GCC/gfortran compiler option syntax) which might then flag an error at instructions like <type> :: var = val on account of the explicitly missing SAVE attribute in the declaration statement.

Outside of something like this that gets into the compiler side of things, I don't see what fpm can do with implicit SAVE.

Thanks for the info. I was too optimist then. It is quite an ambitious task what you suggest but I know a lot of people that hate "implicit save" (I haven't been bitten by it, yet). Since you are talking about compiler development, it is worth CCing @certik

@everythingfunctional
Copy link
Member

I was thinking about introducing a ~/.fpm/config.toml which allows to define additional compilers and maybe even overwrite built-in ones. While this goes against having reproducible environments in a way, a --custom build mode drawing from this configuration might work. Submitting a compiler profile as feedback to us might help us fill in missing compilers and refine existing compiler profiles.

One tweak that might make this option a bit safer would be that only the new command looks at ~/.fpm/config.toml and constructs the fpm.toml file for a new project to include the options set there. That way, projects are self contained and reproducible, but it's easier to get new projects configured the way you like. A workflow for updating the options for an existing project to your preferred set would be to create a new project and copy the relevant contents to the existing fpm.toml file. Or having the --custom flag to try out what's in your ~/.fpm/config.toml file with an existing project.

@FortranFan
Copy link

FortranFan commented Feb 15, 2021

As much as I'd love for fpm's defaults to encourage modern best practices, our desire for legacy codes to be ported to fpm packages and encourage "legacy" programmers to use it, means it's probably a no-go for a lot of our target users.

Yes, trying to "reclaim" .f is fraught on 2 fronts: it's a long-held "convention" .f signifies fixed-form source. besides several compilers have built-in "logic" to support the convention.

That's why I had suggested, even as it was somewhat light-heartedly, to attempt a new convention of .mf, that can be an easier route, a separate lane, to march ahead.

@epagone
Copy link
Contributor Author

epagone commented Feb 16, 2021

That's why I had suggested, even as it was somewhat light-heartedly, to attempt a new convention of .mf, that can be an easier route, a separate lane, to march ahead.

I see, but I am a bit hesitant: we all know that .mf is a well-established Metafont extension 😝

Jokes aside, I consider this community the avant-guard of Fortran and I believe that we should be a bit more brave. On the other hand, I see that many of the key contributors of fpm have expressed scepticism and I accept it.

@certik
Copy link
Member

certik commented Feb 16, 2021

@epagone can you join us at a Fortran call? We can discuss that there. There are pros and cons. In general, the .f90 is a well accepted extension to modern Fortran (in free form) so probably best to stick to that, all things considered.

@epagone
Copy link
Contributor Author

epagone commented Feb 16, 2021

@certik I can try. Do you mean the GSoC or the monthly call? I have seen that both have a quite packed agenda...

@certik
Copy link
Member

certik commented Feb 17, 2021

@epagone I meant the monthly call. We all have a packed agenda, but a video call has been very efficient at arriving at an agreement, or at least make progress on an issues such as the one that you posted.

Since the inception of fpm it has been my vision to be brave and enforce quite a bit of checks by default. For example fpm used to check that module names agree with the filename, and was enforcing naming conventions based on the filesystem position. But others felt it was too restrictive, so fpm does not check that anymore.

I still believe we should be strict by default, and only provide options to override the strict behavior for legacy codes.

Regarding reclaiming .f, I still don't know if it is worth doing, but I am more open to it now after thinking about this more, so I created a separate issue for it at #363.

@sblionel
Copy link
Member

My view is to leave .f alone - changing this will break so much stuff it isn't funny, and it would rely on everyone updating compilers.

Instead consider agreeing on a new extension - I like .ffr - for Fortran Free Form. The standard can't do anything about this - it would have to be multiple compiler developers agreeing to support the new file type. I wouldn't get my hopes up.

@epagone
Copy link
Contributor Author

epagone commented Feb 17, 2021

@certik

@epagone I meant the monthly call. We all have a packed agenda, but a video call has been very efficient at arriving at an agreement, or at least make progress on an issues such as the one that you posted.

🤔 ... what I meant is that the agenda of the call looks already packed with a few topics. Anyway, I have now shared my availability on Doodle and posted a short message on Discourse.

I have a couple of questions:

  1. Would you be interested in including in the development roadmap of lfortran a sort of -fno-implicit-save flag, as suggested above? Is it something feasible that you would be interested in pursuing? I definitely believe that there is an unsatisfied demand for that.

  2. Do you have any other ideal feature that you would like to make default in a modern Fortran environment that I have not considered in my first comment?

Thank you.

@epagone
Copy link
Contributor Author

epagone commented Feb 17, 2021

@sblionel

My view is to leave .f alone - changing this will break so much stuff it isn't funny, and it would rely on everyone updating compilers.

Instead consider agreeing on a new extension - I like .ffr - for Fortran Free Form. The standard can't do anything about this - it would have to be multiple compiler developers agreeing to support the new file type. I wouldn't get my hopes up.

This proposal has zero ambition to convince any compiler vendors to change the way it behaves (at least in the short-medium term). It only suggests to set up by default some overridable, suitable flags to write Fortran in a modern way. However, I can see that this is a recurring misunderstanding: I have amended my first post with the hope to be more clear about it.

PS: among all the many new, alternative extensions proposed for free form I like .ffr best. However, I believe that we should stick to .f because it provides the right message, IMO: i.e. there is no such thing as fixed form Fortran that is acceptable any more except for compatibility reasons with legacy code.

@FortranFan
Copy link

FortranFan commented Feb 17, 2021

Instead consider agreeing on a new extension

Given the Dr Fortran blogpost by Steve Lionel "Source Form Just Wants to be Free", maybe Fortranners should just "suck it up" and be willing to type a few more keystrokes for a 4-chaarcter extension instead of a new one with 1 or 2 or 3 alphanumeric characters!!

And go with .free :-))

@certik
Copy link
Member

certik commented Feb 17, 2021

@epagone wrote:

thinking ... what I meant is that the agenda of the call looks already packed with a few topics. Anyway, I have now shared my availability on Doodle and posted a short message on Discourse.

Perfect, thanks!

I have a couple of questions:

1. Would you be interested in including in the development roadmap of `lfortran` a sort of `-fno-implicit-save` flag, as suggested above? Is it something feasible that you would be interested in pursuing? I definitely believe that there is an unsatisfied demand for that.

Yes, we already have an issue for that:

https://gitlab.com/lfortran/lfortran/-/issues/148

2. Do you have any other ideal feature that you would like to make default in a modern Fortran environment that I have not considered in my first comment?

Yes, tons of ideas. I would like LFortran in this mode to print warnings (or error messages) for all things that we do not consider "modern". That way people can update their code to be following the latest recommendations. Things like "explicit imports" use, something: only f1, f2 and other things.

@ivan-pi
Copy link
Member

ivan-pi commented Feb 17, 2021

@epagone wrote:

I note that I never met a single example of such "legacy" programmer that still actively writes code in fixed form and with implicit typing.

I just found an example of one such programmer/project: PLTMG: A Software Package for Solving Elliptic Partial Differential Equations. The latest version 13.0 from 2018 continues to be developed in fixed-form and uses both implicit typing and common blocks. An example declaration block in the code:

c-----------------------------------------------------------------------
c
c            piecewise lagrange triangle multi grid package
c
c                  edition 13.0 - - - september, 2018
c
c-----------------------------------------------------------------------
        subroutine mpiutl(isw)
cx
            use mthdef
            implicit real(kind=rknd) (a-h,o-z)
            implicit integer(kind=iknd) (i-n)
            include "mpif.h"
            common /atest6/nproc,myid,mpisw,mpirgn,mpiint,mpiflt

They also distribute the code via Netlib. 😄

@certik
Copy link
Member

certik commented Feb 17, 2021

@ivan-pi indeed, there are such cases, although they are a minority. They would be supported by fpm with a simple option in fpm.toml.

@FortranFan
Copy link

FortranFan commented Feb 18, 2021

I just found an example of one such programmer/project ..

Good find.

Personally I'm not bothered about implicit typing as I am with what can be termed implicit mapping by which I mean the following:

image

The above snip is from the current Fortran standard (as per its proxy, 18-007r1 document), section 18.7 IMPLICIT statement, page 114, paragraph 3, lines 32 thru' 34.

If the standard can be enhanced to state:

If a mapping is not specified for a letter, the default for a program unit or an interface body shall be null. The default for a BLOCK construct, internal subprogram, or module subprogram is the mapping in the host scoping unit,"

that will be a major, major step forward. Such a change will have NO backward compatibility issue with programs such as PLTMG because of the explicit IMPLICIT declarations.

But now, it is due to an unknown but likely very tiny list of programs that supposedly have neither IMPLICIT NONE nor the IMPLICIT declarations and which then make use of this `implicit mapping' that a monumental burden exists for all the modern Fortranners.

Where I work, a team had a situation in 2017 where a subtle bug got introduced due to a missing implicit none in an INTERFACE body. Since an INTERAFCE body technically has no host scope, the implicit none from the outer body does not extend to it. The team was lucky the bug had only caused loss of productivity, though it was considerable. The damage could have been far worse. There is far more to this story with some decisions since re: Fortran but I'll let that pass.

So the question I ask myself is this: what if compiler implementations become truly brave and they themselves stop supporting the implicit mapping by default. Meaning, they don't conform to the standard by default, rather force users to apply some option, say -fimplicit-mapping (as per GCC/gfortran terminology), to get what the standard states with that one sentence.

The onus can then shift to those who want to continue with the old ways to do some "extra" work to avoid encountering errors with their unsafe coding practice. All other Fortranners will be freed from having to ensure implicit none in every scope, they will get that as processor default. If enough implementations do this, it will become easier for the standard to be updated.

@epagone
Copy link
Contributor Author

epagone commented Feb 18, 2021

@ivan-pi another example of such ancient remnants of the olden days of FORTRAN that are still very good pieces of code: ORDERPACK uses implicit typing.

@epagone
Copy link
Contributor Author

epagone commented Jun 23, 2021

On Discourse, @urbanjost adds an interesting suggestion for an additional feature: no line length limit. I agree.

@certik
Copy link
Member

certik commented Jun 23, 2021

I agree too. Limiting to 80 columns should be done via formatting tools, but fpm should simply compile everything, no matter how long lines.

@FortranFan
Copy link

FortranFan commented Jun 23, 2021

c.f.: https://wg5-fortran.org/N2151-N2200/N2184.pdf

The next version of the standard referred to as Fortran 202X will allow for the following:

  • Free form source line length: "A line shall contain at most ten thousand characters." Note this is a change from current standard 2018 that states a line "shall contain at most 132 characters."

  • Free form statements: "statement shall not have more than one million characters." Note this is a change from current standard 2018 that states, "A statement shall not have more than 255 continuation lines."

  • Effectively thus "The limit on the number of continuation lines has been removed" in Fortran 202X.

@epagone
Copy link
Contributor Author

epagone commented Jun 23, 2021

Discourse user implicitall suggests to add the pre-processor flags

gfortran: -cpp
ifort: -fpp
nvfortran: -cpp

to further simplify extensions and avoid the uppercase/lowercase confusion that I have seen affecting many newcomers. I think that it's an excellent suggestion.

As long as there are no side-effects, e.g. problems when there is no actual use of the preprocessor in the project (I do not have enough knowledge and experience to safely comment on this), I am in favour.

Your comments please.

@certik
Copy link
Member

certik commented Jun 23, 2021

Yes, we should not need a new file extension just to enable a pre-processor.

However, we should decide whether to encourage using the C pre-processor or rather enable some other pre-processor by default. I can see pros and cons of this.

@jalvesz
Copy link

jalvesz commented Apr 25, 2023

Hi, I wanted to know if there are some thoughts on adding by default the /fpp flag within fpm? It seems to me this could avoid unnecessary build-time errors with many libraries requiring preprocessing.

@everythingfunctional
Copy link
Member

I believe it would likely be safe to "turn on" preprocessing even for projects that don't use it, but I'm not 100% sure. @gklimowicz has been doing some research into the area of preprocessing in Fortran, so perhaps he could provide some insight.

@gklimowicz
Copy link
Member

Well, I don't have to look at sources to answer this, I don't think.

If your code has no lines in it that begin with a # character, the preprocessor won't have much effect.(*)

And if your code does have lines in it that begins with # character, then you probably wanted the preprocessor anyway.

  • The only gotcha I can think of here is: The preprocessor defines default macros that look like Fortran identifiers. This might unexpectedly replace text in your code. But that brings up the interesting (to me) question whether the preprocessor should make any changes at all in code with no directives. (I don't think we want to scan the entire file to make this decision. Perhaps we delay replacement processing until we see a directive. Probably a more implementable approach is for the preprocessor to avoid predefining macros that look like Fortran names.) gak: Making mountains out of molehills since 1955...

@urbanjost
Copy link
Contributor

It is appealing. C of course always preprocesses files, but it has a standard preprocessor.

The bigger issue is there is no standard set of macros defined, and some processors ( I entered bug reports for several of them) predefine relatively common words like linux and unix. Most prefix with an underscore so it is clear the word is unlikely regular code; but some preprocessors do not allow macros starting with an underscore. Scanning for a "#" in the beginning of a line is actually quite fast. vendor-supplied preprocessors vary significantly. There are likely to be issues until (if?) the next standard provides for a standard preprocessor, which may or may not even support macros for instance. We now allow the fpm file to specify a preprocessor and file suffixes to apply it to. Perhaps a compromise would be the "new" command would generate a fpm.toml file specifying the cpp processor and include .f, .f90 as suffixes to preprocess.

No strong feelings but a little concern given the current state of Fortran preprocessing. Just mentioning that the fpm.toml file already has options that can give you the desired behavior, so there is no issue with dependencies if the package specifies what should be preprocessed and what should not as-is. Note that fpm itself needs "unix" undefined when built with ifort/ifx or errors occur as an example of little things that go wrong; and until/if everyone expects all files to be preprocessed it conflates using remote dependencies (do they or do they not expect preprocessing?). The user can specify it now via fpm.toml options. Until there is a standard preprocessor I lean towards leaving it the way it is; but discussing making it the pseudo-default via "fpm new".

@rouson
Copy link
Contributor

rouson commented Feb 24, 2024

Fair enough. I note that I never met a single example of such "legacy" programmer that still actively writes code in fixed form and with implicit typing.

@epagone you might not know old enough coders then. :) I have met some and just met another last week. I'd like to help this person modernize their code and they're interested in doing so, but I'm stumbling into issues with the default settings in fpm. I'm finding that --flag isn't overriding the default flags even when --profile is not passed. It's costing me quite a bit of time to figure out how to build this person's code with fpm. Whenever I embark on a major refactoring effort, I like to start from a version of the code that is as close as possible to how I received it and then put tests in place to ensure that my changes don't break anything. That process has to start by having an easy way to compile legacy code (or in this case, brand spanking new code written to older versions of the Fortran standard).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests