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

Eliminate implicit mapping #218

Open
FortranFan opened this issue Jul 30, 2021 · 19 comments
Open

Eliminate implicit mapping #218

FortranFan opened this issue Jul 30, 2021 · 19 comments
Labels
Clause 8 Standard Clause 8: Attribute declarations and specifications

Comments

@FortranFan
Copy link
Member

FortranFan commented Jul 30, 2021

Issue #90 proposes to eliminate implicit typing in Fortran. There is strong resistance to this, there being a major concern that to "eliminate implicit typing", if pursued with any seriousness, will require a deletion of the IMPLICIT statement from the language. There is great worry some existing code would break as a result.

Can the Fortran community then coalesce to a somewhat simpler proposal, to eliminate implicit mapping instead?

The main aspect of such a proposal is to primarily change one sentence in the section on IMPLICIT statement to introduce the following:
"If a mapping is not specified for a letter, the default for a program unit or an interface body shall be NULL, and the default for a BLOCK construct, internal subprogram, or module subprogram is the mapping in the host scoping unit"

Note the current Fortran standard (document 18-007r1) instead states in section 8.7 IMPLICIT STATEMENT page 114, paragraph 3, lines 32-34, "If a mapping is not specified for a letter, the default for a program unit or an interface body is default integer if the letter is I, J, ..., or N and default real otherwise, and the default for a BLOCK construct, internal subprogram, or module subprogram is the mapping in the host scoping unit."

This one sentence in the current standard effectively ends up achieving backward compatibility with code written from the days of FORTRAN I where "ICARUS was an integer unless specified as REAL", to paraphrase a long-standing joke with FORTRAN!

But now almost all the code written from the days of FORTRAN 77 then has tried to avoid the fate of the legend and not drown while trying to only take flight via the explicit use of the IMPLICIT statement, IMPLICIT NONE overwhelmingly but IMPLICIT INTEGER(I-N), xx(A-H, O-Z) {xx = DOUBLE PRECISION, REAL, REAL*8, etc.]. This proposal intends not to affect in any adverse manner any such existing code that makes explicit use of IMPLICIT statements.

The intended benefit of this one change is to set in motion finally a positive change where IMPLICIT NONE becomes the default in any and all program units and in all the interface bodies, gone will be the need to ensure the inclusion of implicit none in a list of explicit interfaces:

interface
   function foo(..) result(..)
      [import .. ]
      implicit none !<-- Per current standard, forget this and face peril
      ..
   end function
   function bar(..) result(..)
      [import .. ]
      implicit none !<-- Per current standard, forget this and face peril
      ..
   end function
   subroutine foobar(..)
      [import .. ]
      implicit none !<-- Per current standard, forget this and face peril
      ..
   end subroutine
end interface

Almost every processor tries to offer a compiler option to enforce the gist of this proposal, with fpm and LFortran considering making this even the default. Why not standardize all such good intent?

What say you all, can you support this for Fortran 202Y? Please keep in mind even with 202Y, it may be year 2040 by the time this can become practicable. Is it not time now to start giving this a serious consideration?

@jacobwilliams
Copy link

I don't understand quite how this differs from #90. By "eliminate implicit typing" I mean that any variables not explicitly declared (or declared by implicit double precision (a-h), etc. in any context would be a syntax error. Is that not what this is?

@FortranFan
Copy link
Member Author

@jacobwilliams wrote July 31, 2021 11:58 AM EDT:

I don't understand quite how this differs from #90. By "eliminate implicit typing" I mean that any variables not explicitly declared (or declared by implicit double precision (a-h), etc. in any context would be a syntax error. Is that not what this is?

This proposal differs in the sense it tries to be very specific and it strives to state what exactly is meant, and what particular aspect(s) in the Fortran standard will be addressed for improvement.

Sure the original post in this thread does not get into the fully detailed mode but that is intentional; ultimately, such effort will be completed by the Fortran standards committee no matter what.

Nonetheless the words in this original post here are an attempt with a "sharpened pencil" beyond "one-liners", intended both to convey scope and benefits better and to allay concerns.

@jacobwilliams
Copy link

Ah, I see what you are saying now (based on your comments here. What you are calling "implicit mapping" here, I was calling "implicit typing" in #90. I never proposed getting rid of the implicit statements (I don't think that's a good idea and will never happen anyway). So, this is the same thing I was proposing.

@certik certik added the Clause 8 Standard Clause 8: Attribute declarations and specifications label Apr 23, 2022
@p-pap
Copy link

p-pap commented May 25, 2022

implicit none should be the default for any code written in Fortran 90 or later. This is not the case and that only causes trouble. How often you forgot to type implicit none then spent time trying to figure out what's wrong with your code, just because you mistyped a variable somewhere - but the compiler happily accepts it, just because you forgot the goddamn implicit none in the beginning? It happened more than once to me, and the workaround to prevent it from happening again is to enable extra compiler warnings, so that the compiler will at least complain about such a mistyped variable. The worst bug is the one you assume it can't ever happen.

@Carltoffel
Copy link

My idea to solve this:

  • in fixed form code
    • business as usual
  • in free form code
    • using any implicit statement results in a warning (this warning should show up at any warning level)
    • the compiler accepts no implicit typing (unless explicitly enabled) and raises an error, if a variable without type declaration occurs

@klausler
Copy link

I don't understand how these proposals differ -- both just make IMPLICIT NONE the default, yes?

I doubt that could possibly gain approval for Fortran 202Y for 3<=Y<∞, but one thing that could find support: in MODULE FUNCTION and MODULE SUBROUTINE interface blocks in (sub)modules, automatically inherit the implicit mappings or IMPLICIT NONE from the (sub)module. There is little-to-no legacy to worry about with separate module procedure interfaces and I don't ever see anybody remembering to put any kind of IMPLICIT statement in them.

@jacobwilliams
Copy link

Yes, frankly, I think this is the same as #90. We don't need two of them. We should discuss it there.

@FortranFan
Copy link
Member Author

@jacobwilliams , with issue #90 with "eliminate implicit typing", it was entirely unspecific as to what was implied, perhaps removal of IMPLICIT statement altogether even? I explained this previously to you upthread:
#218 (comment)

You effectively had a "one-liner" initially that was provocative and which was not received well.

Given above, ideally you would have closed issue #90 so the discussion can move to the specific suggestions in this thread. But you insist otherwise, so I will close this thread.

@jeffhammond
Copy link

implicit none should be the default for any code written in Fortran 90 or later.

What exactly do you mean by Fortran 90 or later? If I write a strict ANSI Fortran 66 program except that I define a symbol name with 7 characters, that is a Fortran 90 program. Do you think implicit none should become the default for that program?

@Carltoffel
Copy link

Do you think implicit none should become the default for that program?

Yes! Because why would you want to write a Fortran 66 program in 2022? Anyway, you could turn implicit mapping on with implicit or maybe a compiler flag.

@jeffhammond
Copy link

Do you think implicit none should become the default for that program?

Yes! Because why would you want to write a Fortran 66 program in 2022? Anyway, you could turn implicit mapping on with implicit or maybe a compiler flag.

So you think that a code that currently makes heavy use of implicit types must immediately remove every single implicit type to merely call the LAPACK function DBDSVDX, for example?

I work on codes that are older than I am, which a millions of lines of Fortran, and generate dozens of scientific papers a year. Your suggestion will break those codes pointlessly and cause significant problems for those scientists, all because you aren't willing to put in the effort to add a single line of code to new procedures.

@FortranFan
Copy link
Member Author

@jeffhammond ,

I work on codes that are older than I am, which a millions of lines of Fortran, and generate dozens of scientific papers a year. Your suggestion will break those codes pointlessly and cause significant problems for those scientists, all because you aren't willing to put in the effort to add a single line of code to new procedures.

It may even be an understatement to say things are at the cusp of a fundamental transformation in so many areas starting with energy, health, all manner of social interactions and so forth where billions and trillions of new lines of code are being written or soon to be authored, even a small fraction of which if done in Fortran can easily dwarf what exists now. The notion that every applicable program unit and interface body in new Fortran codebases can do with implicit none or use processor-specific compiler options is too onerous to a significant segment of the community, to say the least.

Besides the existing codebases can do with refactoring too, nothing is perfect, least of LAPACK or any legacy FORTRAN code which consumes it on modern processors.

@certik
Copy link
Member

certik commented Jul 20, 2022

Old code must keep working, one way or the other, without needing to do any changes to it. And yes, you must be able to call Lapack from it, and do other changes or maintenance: you must be able to touch it, without forcing any rewrite, besides the part you touch. So let's all agree on that. I know there are some people who disagree on this point, but even if you disagree, it is going to be a tough sell to convince everybody else in the wider Fortran community that old codes must break like this. So to move forward, let's agree on this point.

Now, here it gets interesting: the above requirement (that is non-negotiable in my mind) does not imply that the standard forever must by default enforce implicit typing. Rather, there are many ways how to effectively eliminate implicit typing by default for new code (many of such proposals are available at this site). It also does not imply that compilers must forever assume implicit none by default. They should not and there are compilers that already do not. But what must happen is that the standard must be written in a way so that compilers can keep providing simple command line options to keep compiling older codes without modifications; while at the same time providing good defaults for new code. In other words, we should not break the standard in a way that would make old code conflicting with new code. However, using a command line option for older code in my opinion is totally fine, in fact that is already the case, for example I have to use -std=legacy with some older code already. So if -std=legacy in the future also implies implicit typing, that would be fine. Most of the disagreement is what "conflicting" means and all the details about it. But my comment hopefully shows that there are good ways forward.

@klausler
Copy link

klausler commented Jul 20, 2022

I may have accidentally hit the "close issue" button; sorry. (Edit: nope, it was already closed; re-closing now.)

@klausler klausler reopened this Jul 20, 2022
@FortranFan FortranFan reopened this Jul 21, 2022
@FortranFan
Copy link
Member Author

FortranFan commented Jul 21, 2022

@jeffhammond wrote July 16, 2022 1:16 PM EDT:

So you think that a code that currently makes heavy use of implicit types must immediately remove every single implicit type to merely call the LAPACK function DBDSVDX, for example?

@jeffhammond ,

In terms of type safety at least, DBDSVDX in and of itself is a coding "ideal"!! Check it out: DBDSVDX appears to go for explicit type declarations and no IMPLICIT statement!

That is exactly what we want to achieve in all new codebases i.e., let there be no IMPLICIT statements including no implicit none. But to get there with support from the standard.

Should one try to enhance DBDSVDX and as part of that exercise, say an object FOO is introduced but not declared it should not implicitly have default real type. Rather the Fortran standard, in such a circumstance, must require the processor to detect and report the missing declaration. That is precisely the intent of the proposal in the original post.

The point about certain processor adopting certain defaults and/or asking practitioners to fall back on compiler options all miss the point of the original post which is that the standard starting 202Y can be forward-looking and make implicit none the default.

Separately the point about "code that currently makes heavy use of implicit types .. simply to call the LAPACK function" is meaningless:

  • 10 out of the 17 dummy arguments are of either DOUBLE PRECISION or CHARACTER types that do not fit into the implicit mapping scheme with default integer and default real in FORTRAN.
  • So those callers need either explicit declarations and/or certain IMPLICIT statements to work with DBDSVDX, the implicit mapping is inadequate.

The callers, if at all they use implicit typing, are really "mixed implicit-explicit typing" codes. As such, they will be better off confronting a choice in the future:

  • add IMPLICIT INTEGER.. statements to conform or
  • be nonconforming in the future but can continue to function as they do now because processors will continue to support earlier standard revisions.

But I don't see how those old codebases should remain relevant in moving toward better type safety in newer standard revisions.

@klausler
Copy link

The engineering trade-off being proposed here is to change the language in such a way as to render a lot of valuable working Fortran code needlessly non-conforming so that newer code always gets compiled with -fimplicit-none without having to type it.

@Carltoffel
Copy link

so that newer code always gets compiled with -fimplicit-none without having to type it.

It's not about having to write an additional line because if it would, we should stick to implicit typing. Instead, it's about making the Fortran Standard more robust by removing pitfalls like "surprise wrong data types" if someone forgets to add implicit none and the type declaration. One idea to tackle this is to make implicit none the default. In this case, older code could have to use a compiler flag, which often times is already the case (-std=legacy).
But maybe you have a better idea to make implicit typing less error-prone.
IMHO we should focus on solutions instead of distorting the statements of the other party. This applies to both sides.

PS: conforming and non-conforming doesn't necessarily mean good and bad code.

@klausler
Copy link

I'd happily implement any "solution" that doesn't require modification to existing code or build systems; the compilers that I work on don't even have a -std= option. Standard-conforming or not, those codes will always continue to compile and run. I wish that this were negotiable, but I don't think that it is.

@FortranFan
Copy link
Member Author

Entirely unsurprisingly yet most disappointingly, a thundering "no" on this:
https://j3-fortran.org/doc/year/22/22-182.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Clause 8 Standard Clause 8: Attribute declarations and specifications
Projects
None yet
Development

No branches or pull requests

7 participants