-
Notifications
You must be signed in to change notification settings - Fork 16
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
Language version keyword #83
Comments
@aradi , please see this thread at comp,lang.fortran where a similar idea re: a 'version specifier' was posted. While I am personally not sold yet on the specific keyword idea (I wonder if a simpler semantic alternative might be attainable for the same), I wholeheartedly agree with and support your sentiment you express, particularly in your last bullet, toward Fortran language. The relevance of Fortran in scientific and technical programming is profound and hope it can remain as such, its strength lies in both in its legacy but more importantly with the potential for the future that can allow scientists and technologists to focus almost exclusively on their domain expertise and their computations without having to get their hands "dirty" with the nitty-gritty details and artifacts of computer engineering (pointers, LValue/Rvalue, etc.) |
@FortranFan Thanks for the link, I was not aware of that discussion. By looking at it, I could not find any serious counter arguments, why this idea can not be or should not be done. As for the keyword itself: If there is any other superior semantic solution, we should go with that then. For me, it is only important that we can adapt the language to current programming customs faster. While every programming language has its own peculiarities, those peculiarities should have a good justification other than we always did this way. As I mentioned on the other issue here, I am often feeling ashamed, when explaining to students that they must put |
I don't have strong feelings one way or another about the general idea, but I will caution that standardizing keywords such as standard version numbers is fraught with risk for compiler developers and users. Consider that the name of Fortran 2018 changed in the year or so before publication. What you would end up with is either vendors having to support multiple, synonymous keywords (some of which would not be conforming in the new standard), or delaying support until the standard is published meaning a delay before programmers could use them. There is also the issue of incomplete implementations and TSes, assuming a TS changed the meaning of a past standard (unlikely but it could happen.) See also my 2013 thoughts on a related topic. |
Available optionsIn Fortran, we do not break old code (#79), so the only way to introduce a breaking feature is to signal to the compiler that the given source file is using the new feature, and by default no signalling is done, so the old feature is being used. So the only question is how to signal to the compiler. Here are the options that I have seen proposed:
Is there fundamentally any other way to consider? AnalysisThe option 1. does not seem to be a good way as @sblionel explained here, and I agree. The option 2. is already used in compilers such as gfortran, but my understanding is that the standard does not enforce new features, so even with the latest
That leaves options 3. and 5., both of which one can use today, but the problem with these is that as more and more optional features are added, it will be more and more painful to be always explicitly enabling them at the beginning of each module, such as:
The objection from Steve regarding the fact that the name of the standard changes until it is released is easily fixed by simply using the placeholder So the main issue that I can see in here is that some future standard, say 202y will introduce a breaking change such as enabling Update: added option 6. |
@certik That's a nice summary on the possible options, thanks! One note on the topic, whether to realize it via compiler option or language construct: I think, a programming language should be self-contained. A compiler should be able to generate correctly behaving code (and stop on standard violation) just by reading the source code itself without the need of any additional hints in form of command line options. Latter should in my opinion only serve 'fine-tuning' purposes instead of being indispensable for the correctness of the generated code. |
And yes, I would vote for breaking backwards compatibility in newer standards for the sake of simplicity and code robustness, provided a standardized language construct ensures that old code can be still compiled without the necessity of using extra (vendor dependent!) compiler options. |
@aradi so let's discuss some of the breaking features that could be considered:
Anything else? Because if it's just these, then there might be a way to achieve what we want without breaking backwards compatibility (for example #40 can be fixed by changing "implicit none" to "explicit all" or something like that --- still just one line to be added to every module), so we do not need the feature discussed in this issue. |
I will be the devils advocate here, since I am usually the hater on the old code, but I will argue that this solution is inherently dangerous. First, let me prefice that with what I consider the absolutely basic design feature I expect Fortran to have: prevent silent errors. So ugly syntax or not, what I personally get paid for is to get good numeric results. Consider the very root of such solutions, which probably is the familiar line implicit none The implicit typing feature was deemed to be unsafe and thus new, stricter rules for typing can be enabled with this switch. Please notice:
Reading the code mid-file, you don't need to check the top of the file to see the Now consider the proposed switch (let's stick to my favorite implicit save). For example:
If you do that, the behavior of the code will change violently in a completely non-distinguishable way. Whenever you see:
you have no idea whether Now when you work with different files, some of them written in 1980s, other in 2010s, you cannot just write right Fortran: you have to keep in mind which typing/saving/... rules are in place. Which is exactly the reason why implicit typing was deemed unsafe! As much as I hate and despise this feature, I think we cannot provoke such situations. It must be clear looking at the code whether the variable is
Any solution must be nice to type. This keyword/syntax will be used a lot. So I personally would prefer some operator-based syntax because having Now this ended up being an implicit save post which I didn't intend but I did not know how to split it so maybe I will post exactly the same thing in the other place. |
@gronki thank you. These are precisely the kinds of arguments that we have to have. I commented at #40 (comment) with my proposal there. |
That list could be a lot longer. All "deleted" and most "obsolescent" features could finally be disabled (e.g., Syntactically, this sort of thing might look best as a prefix on the |
@klausler, that's a great idea. Perhaps the standard can simply declare some features as "obsolescent", and those would work by default, but if you use One problem that I can see is that when a future standard makes something "obsolescent" and you happen to use that feature in your |
@gronki I think the point you raise is absolutely right. Having a language version keyword would indeed make the behavior of certain constructs "context-dependent". Actually, we have that already in the language, since
triggers LHS reallocation depending whether you stick with Fortran 95 or 2003. And, which one of the both is used, depends on the compiler options you use for compilation. There is no way to tell it by looking at the source code alone. The language keyword would at least let you know it by declaring the standard conformance at the beginning of your scope. |
@klausler Thanks, indeed the list could be considerably longer. And I agree that it is a good idea to encode the standard compliance already into the |
@aradi I would argue that this is an unfortunate exception from the past which should not be a reason to introduce even more unfortunate exceptions like this. It is not a problem anymore since f2003+ compliant compilers are available for free so there is no reason to use f95 compiler anymore. The time to version Fortran was in 1990: it was great moment to fork the language and make it independent of F77 pains. This was not done and now with F2018 this is far too late. Please also keep in mind that not everyone using the Fortran language is as passionate as us to remember which year number will enable which behavior. This is also an important factor. It's about making programming simpler, not harder. |
See Annex B, especially B.3. |
@gronki You are right, we definitely should not expect Fortran practitioners to be language history experts. I think, we have to differentiate between different kind of backwards compatibility breaks:
The acceptable frequency for those two categories is clearly different. For the first one, I would wish that nearly each standard would deprecate old eventually harmful features, when new more robust alternatives had been introduces. Semantic changes on the other hand should be as rare as possible. For me, having 1-2 changes every 20-25 years would be acceptable (max. 2 changes during my entire professional career from writing the first code as student till being retired at the age of 67), but of course your opinion may differ on this. When we had a language version keyword, it would cover both kind of changes. If semantic changes happen only every 2 or 3 decades, Fortran practitioners would not have to be language history experts, because a given code line would be warranted to keep its exact meaning/behavior for at least that amount of time. But if such a change happens, the explicit language keyword at the top of the module would make sure, that it still compiles (and behaves) as before without the necessity of vendor dependent compiler switches. Additionally, by specifying the language version at the top of your modules, beginners looking at your modern Fortran projects could immediately realize, that the language constructs used in that code are still considered to be good practice. Having something like |
@certik wrote:
Why not allow the nearly 30 years of usage to be of guidance in some matters at least such as the IMPLICIT problem in Fortran? What I mean by this is take advantage of the built-in "signaling" in the language with free-form source and how this option is being used by the practitioners. Can anyone point to any code-base using free-form source where "implicit typing" is employed per code design? Code after code that uses free-form source tries to have the "IMPLICIT NONE" line in all the scopes yet end up with embarrassment and grief and anger at the Fortran standard when this line is omitted unintentionally with some disastrous consequences in a scope e.g., INTERFACE block which does not inherit the "IMPLICIT NONE" from the host. Similarly, can anyone point to any code-base that explicitly relies on implied SAVE in its code design? What the discussion here and elsewhere show is there are no perfect solutions to this pernicious IMPLICIT problem, both with types and the SAVE attribute. The situation is akin to the legendary Gordian knot. Why not then take an obvious solution from history which is to simply cut the damn thing out? As is, there are crucial differences in syntax (and by extension, I would argue, in semantics) between free-form and fixed source. So what breaking impact and damage is expected if both IMPLICIT typing and implied SAVE are deleted altogether from free-form source? |
While I hate implicit typing as much as any of you, it is such an integral part of the language I don't see having it off by default being taken seriously. ("God is real, unless declared integer") I would also not be in favor of tying this to source form - the whole idea is that the source forms are equivalent. Users have learned to account for implicit typing with coding and usage standards (requiring use of compiler options that turn it off, for example). I don't see it worthwhile spending time arguing this after so long. Implicit save is harder - the posts here have focused on initialization in declarations, but that is a recent (!) addition to the language, supplanting |
Jokes apart, "implicit typing" only belongs to the past history of this language. It's not "integral" in any way; every scope of a Fortran unit one see out there strives to negate it. There is so much time and energy wasted to inform coders to avoid it (an example here) and there is so much loss of goodwill toward Fortran on account of this 'feature', Fortran is seriously hurting itself by retaining this aspect.
The two source forms are not equivalent, one only has to look at the syntax and semantics of line continuation which is so important given the restrictions of fixed-form source.
No, many a new user does not learn to accept this and that's the point. Trying to get new coders to work on Fortran codes, particularly in industry, is a huge challenge. Few join with any background in Fortran, few schools teach Fortran. Then one loses them at 'hello' itself, meaning at the very beginning stage when one stresses to them the need to type 'implicit none' in every scope.
To reiterate, both implicit typing and implied save introduce 'silent errors' (to borrow the term by @gronki), these two aspects are pernicious, they bring tremendous vulnerabilities to Fortran code. To argue they are integral to the language in year 2019 conveys an entirely wrong message about Fortran. Separately, the added risk that will get introduced with yet another addition to the IMPLICIT statement was mentioned upthread just yesterday by @gronki. That's what made me think further about using the source form itself has a signal to the compiler. I inquire again of the several questions in #83 (comment).
|
Any Fortran program can be represented in both source forms without differing in their semantics as the term is otherwise universally understood. Altering the language so that source form affects semantics is a non-starter. |
@FortranFan People use implied I am sure there are tons of other places. Looking at this particular code, I do wonder if it's intended, or if it's a bug. |
@certik wrote:
Thanks much, I've contacted ABINIT to find out whom I can reach out to learn about this particular section of their code. My hunch looking at that code is their intent is different and it's not a significant use of implied SAVE, but I hope to find out more. |
It would be extremely ironic if, contrary to all the fears about backwards compatibility, silently removing "implicit save" would fix more codes than it would break. ;) |
I must say I am leaning towards @FortranFan's idea of simply removing implied save, exactly as I initially proposed in #40. I posted there a comment how it can be done: #40 (comment). What I like about #40 is that we actually very conservatively discuss the various pros and cons, and breaking backwards compatibility is a huge con that we all agree on, and we try to figure out how to best proceed. But the pros are very compelling and in the end, if done right, might outweigh the con. (With a backwards compatibility breakage like this, we absolutely need to have a prior compiler implementation and actually test it on real production codes. And we need automatic facility to find implicit save usage in codes and fix it, automatically. That's a given requirement.) |
This would be quite easy to write. We wouldn't even need a full parser. All that would be necessary is the ability to:
FORD already does essentially all of this just with regular expressions, although the way it manipulates the source code internally means it would not be suitable for performing the fixes. However, I reckon I could write a single file script along these lines in about a week if I could devote the time to it. |
@cmacmackin yes, it's absolutely doable. All I am saying we have to do it, test it with real codes, and provide good guidelines how to upgrade, as part of any such change. |
@certik, I'm currently inclined to think the authors of ABINIT meant for that variable to be an entity of the module rather than a local in that procedure, so I'm unsure as to whether I can accept ABINIT is a code-base that explicitly relies on implied SAVE in its code design.
And I'm not convinced the Alexandrian measure of removing implied SAVE from the language will 'break' ABINIT: with such a change in the language and with current ABINIT code remaining as-is. a local variable ndtpawuj will come into existence with a value of 4 and with a TARGET attribute each time the procedure 'pawuj_drive' is invoked and that's all ABINIT might care about. I will be really surprised to find FOSS-type of code on GitHub, SourceForge, etc. rely on implied SAVE, or if they do, anyone throwing a fit about refactoring to include the explicit SAVE attribute with variable declarations. It's a matter of mindset, a certain openness to adopt FOSS which also enables good sense to be explicit in everything in order to maximize clarity for the widest audience of one's code. The issue is with unverifiable claims about code held privately. Now I happen to work with a lot of teams in industry who have such 'private/proprietary' code. If there is one thing I know for sure it is that none of the critical 'private/proprietary' code are going to remain in Fortran for long unless this language keeps apace fully with modern trends and truly enhances type safety and reduces code vulnerabilities, particularly as cloud and parallel computing come to the fore. Imagine one line somewhere hidden with an implied SAVE also has the potential to cause data race conditions or lock scenarios with the risk of rendering a Fortran library not thread-safe and thus unfit for consumption in a cloud service. I too can attest and that is to so many code-bases moving away Fortran permanently. An initiative such as #40 by @certik et al. can be a truly positive intent to help reduce this 'bleeding'. |
@FortranFan what we absolutely have to prevent is the Python 3 fiasco (e.g., just saw this: https://stackoverflow.blog/2019/11/14/why-is-the-migration-to-python-3-taking-so-long/), when Python 3 was released 11 years ago, and there are still many huge code bases in Python 2 that just cannot upgrade, and the amount of effort it took Facebook, Dropbox, etc. to port is just unbelievable, and all pretty much for nothing. At the same time, I agree with you, we want to fix some of these things. We just need to figure out how to do it carefully. |
I personally very dislike this idea. To sum up my voice:
- keyword is removed and the code works the same: I'm happy
- keyword is removed and the code doesn't compile: I'm happy
- keyword is removed and code behavior changes quietly: this is a disaster
If there's a keyword, it can remove features or enable new ones. Never
change behavior. Ever.
There should be one language. Not ten variants configurable by different
switches. This introduced confusion and is not a very classy solution. If
implicit save was an infection, that solution would be like spreading it
further. Or rubbing your eyes when they itch which only makes them itch
more. It only aggravates the problem we have now and creates dozen of other
problems. This is a can of worms. I'd rather live with implicit save. At
least there's one way how things work even if not intuitive and very
annoying. And I think this should be the paradigm that is strictly followed
in all future design decisions.
pt., 13 gru 2019, 17:33 użytkownik Peter Klausler <[email protected]>
napisał:
… I think that there's two features being discussed here under the same
heading. One would *disable* some features (e.g., generate an error if an
ASSIGN statement appears). Another would *imply* some features (viz., IMPLICIT
NONE, implicit SAVE, &c.). These two concepts don't have to use the same
keyword.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#83?email_source=notifications&email_token=AC4NA3LYHCXZ2HBSFDWYKJDQYO2MRA5CNFSM4JMWOOT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG2PVNY#issuecomment-565508791>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AC4NA3P3WNDD7OZ2XEVO7IDQYO2MRANCNFSM4JMWOOTQ>
.
|
Fortran is used by plenty of scientists who can't code and aren't Fortran
passionates (barely users) so they don't keep up with language versioning.
Having worked with my collaborators for years I know they will never ever
remember such a subtle details as which version number induces which
behavior. Please think about scientists. One Fortran for all.
😅
pt., 13 gru 2019, 17:44 użytkownik Bálint Aradi <[email protected]>
napisał:
… @gronki <https://github.com/gronki> Can you maybe explain more in detail,
why you think the idea is "catastrophic"?
I would like to "get rid" of old ballasts, like having to specify implicit
none, having to check for implicit save in subroutines etc. (It is
embarassing to explain Fortran newcommers, why they should never write integer
:: a = 5 within a subroutine.) To make sure, we won't break old code,
however, the new default should come with a new global keyword specified
somewhere in the code.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#83?email_source=notifications&email_token=AC4NA3OY2O3JEVNFG4FKNZTQYO3VZA5CNFSM4JMWOOT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG2QCGY#issuecomment-565510427>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AC4NA3LOHCTZ6QQSIOM3Q7LQYO3VZANCNFSM4JMWOOTQ>
.
|
So would you also disapprove of an |
With all my hate for implicit save, yes. 😢 Unless it would just ban using
the feature altogether (so saved variable declarations would just require
explicit save keyword). But that's just my opinion.
pt., 13 gru 2019, 18:15 użytkownik Peter Klausler <[email protected]>
napisał:
… So would you also disapprove of an IMPLICIT NOSAVE statement?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#83?email_source=notifications&email_token=AC4NA3MFLYCANX3TAWSXQ5DQYO7KRA5CNFSM4JMWOOT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG2TCNY#issuecomment-565522743>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AC4NA3LTVYXLZHVXXUJNY2DQYO7KRANCNFSM4JMWOOTQ>
.
|
Could you be placated if the syntax for a non- |
See #40 (comment) Per the syntax adopted by the standard since 2008 revision, one would think it would be implicit none (save) ! Given the standard has gone with implicit none (type/external) Short of deleting certain pernicious features such as implicit typing and implied save in one strong Alexandrian cut of this Gordian knot of an issue in Fortran, I still prefer as I suggested earlier: explicit all |
I am with @gronki on "one language". How about |
I like I also like I'm not looking forward to having to type |
I am not sure if in this thread but I feel we discussed it somwhere. I
think := syntax was proposed as an alternative.
So then IMPLICIT NO SAVE or STRICT would make these two valid
INTEGER :: I := 5
INTEGER,SAVE :: J = 8
but the following would fail to compile
INTEGER :: K = 4
Do any of my arguments make sense?
pt., 13 gru 2019, 18:24 użytkownik Peter Klausler <[email protected]>
napisał:
… Could you be placated if the syntax for a non-SAVE (C-like)
initialization expression syntax were distinct from the current = expr
and the STRICT keyword had the effect of disabling the current syntax?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#83?email_source=notifications&email_token=AC4NA3OTGUGMUBKVTB3OX63QYPAMPA5CNFSM4JMWOOT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG2UYSA#issuecomment-565529672>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AC4NA3OVNWH4YFXF2VII5BTQYPAMPANCNFSM4JMWOOTQ>
.
|
I could leave with both, Let's assume, the keyword is introduced into the language. What would the processor then do with
@gronki I develop a quantum mechanical simulation package in Fortran and also teach Fortran to students, so I know what you're talking about. Still, I prefer a language, where teaching does not have to start with teaching work-arounds due to historical heritage. |
@certik commented on Nov 14, 2019:
@certik, as I had mentioned in #83 (comment), I'd contacted ABINIT team about this. Their software engineering support contact has gotten back to me the Fortran developer for their PAW component (you'll know m_gstate.F90 is part of this) is going to look into making that variable a module-level entity with an explicit SAVE attribute to make the intent clear for readers. |
In language version keyword is an excellent idea, and one I hope to see added to future Fortran standards. We should not have to rely on vendor specific compiler flags, which also complicates build systems for large + long history code bases. |
I don't if this topic had some advances, but I really think that something should be planned for F202Y. Among the options listed by @certik, the language version keywords looks the most appealing to me, even if not perfect. And I also agree with @gronki, in that changing the version keyword should not change the behavior of a code that compiles. One should try listing the possible objections and drawbacks to this system, and how it can be improved. @sblionel has cited two possible issues:
One question would be the minimal scope of the version keyword: routine/function? Source file? Module? How objects compiled with different versions would works together? For instance would a (The latter example is purely rhetorical, as I think that the first and only keyword version that should be introduced in 202Y is |
Some random thoughts.
|
@sblionel I'm a bit surprised, because some time ago in this discussion you were apparently not opposed to such a proposal. And you even proposed something somehow similar in #280 ... I definitely do not think either that the compability with obsolescent features is the main obstacle to new features. Nonetheless it can happen in some cases, for instance: the idea of turning every control structure into an implicit And I don't see that as "punishing existing users". There would be absolutely no change to bring to existing codes, even not adding a version keyword, as long as they are not modified to use new features of F202Y. And if they are, 99.9% of the times it would be just adding something like |
@PierUgit the proposal you link to is different, though I'm unsure I would still support it. Can you tell me of another popular programming language that has this notion of syntax to identify language revision? I don't know of any. |
@sblionel It's different, yet similar. Both aim at disallowing the simultaneous use of obsolescent and new features in a given scope (to be determined). Rust has such a system to identify the langage revision, although not in the source code itself (but I find the source code a better place for that, actually). I would argue also that among the popular languages I don't know any where there is the same strong emphasis on the backward compatibility as in Fortran (apart waht is claimed in Rust, but it's a very recent language). I like that, and I don't want the backward compatibility to be thrown out, but the language version specification looks to me an interesting approach: no feature has to be deleted, actually. |
In a way Python does it too: you specify which exact Python version you depend on, the biggest difference of course Python 3 and 2, but there are actually slight backward incompatibilities in corner cases even in versions like from 3.10 to 3.11 and so on. In both Rust and Python you specify which exact version you want in the configuration files, not the source code. Compilers however already allow to be backwards incompatible via compiler options (for example almost all compilers allow disabling implicit typing), so we can already create tools that specify backwards incompatible features via configure files. |
As a practical matter I don't think that a language extension to disable older features is warranted -- you can just not use those features, and depend on options or tools to ensure that you're not using them. But a language extension to disable newer semantics might be useful when the standard changes in such a way as to silently alter the behavior of conformant code (F'2023) or to add behavior that induced run-time overhead on conformant code (F'2003). I put a warning message into Flang for the F'2023 case, and programmers have learned to work around the older one. so the need for a new language extension to protect compatibility against future standard changes depends on how likely you think they are going to be in the future. (And the odds of getting the committee to approve a language extension like that are extremely low.) |
Indeed, compiler warnings are extremely effective. We put warnings of the type "style suggestion: Use '>=' instead of '.ge.'" into LFortran and it makes users update their codes. So with proper tooling, one can facilitate modernization and avoiding many pitfalls. |
It's beyond that. I would allow deleting from a revision some obsolete features that are an obstacle to some useful new features, or features that are widely considered harmful (like the implied save). But these features would still be officially part of the standard, using previous revisions. e.g.
would still compile
would fail compiling
would compile Some safeguards would be needed:
|
@PierUgit for this case, LFortran does the following:
Which is enough I think to catch this common mistake for newcomers. In "pedantic" mode we can even turn all such warnings into errors. For legacy codes you use some compiler options to compile them without warnings. Let me know if you think this completely fixes this particular problem. You can then suggest another issue and we can explore a solution using a compiler or tooling. |
There are several features in Fortran many of us wish to see changed / deprecated in order to support and enforce modern programming practices (see for example . Unfortunately doing so would break backwards compatibility of the language, which would sacrifice one of Fortrans advantages.
What about adding a keyword to the language, which indicates the language version of the code in a given unit (module). Something like:
All module files without explicit language version keyword would be treated as having code complying to the last standard without this keyword (e.g 2018). All module files with the language version keyword would be treated accordingly to the specified version.
Advantages:
-assume realloc_lhs
or similar). Especially, if you have source files with different language standards in a project (no nice, but can happen), you won't need to fiddle with the compilation options for each file individually.The text was updated successfully, but these errors were encountered: