Open aradi opened 5 years ago
@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 implicit none
in every module (especially if their project should pass the exam :laughing: ).
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.
In 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:
File suffix specifying a version (.f90
, .f03
, .f08
, .f18
, .f2x
, .f2y
)
Compiler option for the version (-std=f95
, -std=f18
, -std=f2x
)
Compiler option for a feature (-frealloc-lhs
, -fimplicit-none
, ...)
Keyword for the version (this issue #83)
Keyword for a specific feature (implicit none
, implicit save off
(see #40), ...)
Keyword for modern (modern module X
) which would not use obsolete features (features can become obsolete in the future and one would need to update the code)
Is there fundamentally any other way to consider?
The 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 -std=f18
, the feature implicit none
is not enabled unless explicitly told so. In other words, the newest standard does not break old code. So the options 1., 2., and 4. actually cannot impose implicit none
, unless F202x or F202y introduces a breaking change of enabling implicit none
by default, and historically this is not how we have done things. But unless that is changed, you would still have to do:
language_version 202x
implicit none(type, external)
implicit save off
short_circuiting on
...
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:
implicit none(type, external)
implicit save off
short_circuiting on
...
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 -std=f2x
, until F202X is released and then changing it to -std=f23
(for X=3). That's how C++ does it and f2x
just becomes an alias for f23
. I think that's not a problem in practice.
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 implicit none
by default. And if you tell the compiler (no matter whether using an option -std=f2y
, or by using a keyword language_version 2y
), then the new feature will be used by default. That is a fundamentally different way of doing it --- and that's what we should discuss if we want that.
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:
.andthen
will be introduced which is not a breaking feature)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:
implicit none
, the functionality of the code will not change-fimplicit-none
(or equivalent) switch, the functionality of the code will not changeReading the code mid-file, you don't need to check the top of the file to see the implicit none
. You just use the implicit typing and whether this mode is enabled or not, you will be good. Now if you start using implicit typing and implicit none
was in effect, you will get a compiler error. All good.
Now consider the proposed switch (let's stick to my favorite implicit save). For example:
implicit nosave
If you do that, the behavior of the code will change violently in a completely non-distinguishable way. Whenever you see:
integer :: i = 0
you have no idea whether i
will be zero on each call or not. And worst of all, if you make a mistake, you will not be warned.
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 save
or not. A couple of solutions have been proposed:
integer, nosave :: i = 0
-- IMO pain to typeinteger, init :: i = 0
-- nicer to type on QWERTY keyboardinteger :: i := 0
-- or some other operator, such as =>
. The good side is that there are no keywords that clutter the code.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 nosave
every 3 lines would cause a lot of clutter, especially in editors with syntax highlighting. But the worst case init
would be not that much pain.
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 https://github.com/j3-fortran/fortran_proposals/issues/40#issuecomment-553520071 with my proposal there.
@aradi so let's discuss some of the breaking features that could be considered:
40
19 (however it seems it won't pass, and instead
.andthen
will be introduced which is not a breaking feature)- realloc LHS
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.
That list could be a lot longer. All "deleted" and most "obsolescent" features could finally be disabled (e.g., EQUIVALENCE
, Hollerith, extensions like STRUCTURE
) in a program unit that declares itself to be "modern".
Syntactically, this sort of thing might look best as a prefix on the MODULE
statement, i.e. MODERN MODULE FOO
. And it should be inherited and enforced in submodules.
@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 modern module foo
, all "obsolescent" features will get disabled.
One problem that I can see is that when a future standard makes something "obsolescent" and you happen to use that feature in your modern module foo
, your code will break. And you cannot just remove modern
, because you use some other "modern" features, so your code will simply stop working until you fix it. I think that's a problem.
@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
integer, allocatable :: a(:), b(:)
...
a = b
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 module
statement. However, I'd suggest to keep it general with possibilities for future adjustments, so using something more specific as modern
, e.g.
module, language(f2008) :: my_module
or something similar.
@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.
@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
modern module foo
, all "obsolescent" features will get disabled.
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:
Features becoming deprecated/obsolete/deleted because they are considered harmful and newer constructs allow more robust implementation of the same or similar functionality (e.g. GOTO
EQUIVALENCE
, common blocks, etc.)
Semantic changes, where the same code behaves differently dependent which version of the standard one adheres to (e.g. automatic LHS-reallocation, a possible redefinition of assignment on declaration, etc.)
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 module, language(f2018) :: my_module
would ensure, no language construct has been used, which the Fortran committee considered harmful or obsolete in the year 2018.
@certik wrote:
Available options
In 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:
- File suffix specifying a version (
.f90
,.f03
,.f08
,.f18
,.f2x
,.f2y
)- Compiler option for the version (
-std=f95
,-std=f18
,-std=f2x
)- Compiler option for a feature (
-frealloc-lhs
,-fimplicit-none
, ...)- Keyword for the version (this issue #83)
- Keyword for a specific feature (
implicit none
,implicit save off
(see #40), ...)Is there fundamentally any other way to consider? ..
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 DATA
, where a large body of code expects SAVE
semantics and breaks if that doesn't occur. Again, this is an integral aspect to the language and I don't see changing it worthwhile. I'd be in favor of adding IMPLICIT (NOSAVE)
.
.. implicit typing .. 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")
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.
I would also not be in favor of tying this to source form - the whole idea is that the source forms are equivalent.
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.
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.
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.
Implicit save is harder - .. this is an integral aspect to the language and I don't see changing it worthwhile. I'd be in favor of adding
IMPLICIT (NOSAVE)
.
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 https://github.com/j3-fortran/fortran_proposals/issues/83#issuecomment-553914150.
I would also not be in favor of tying this to source form - the whole idea is that the source forms are equivalent.
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.
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 save
unfortunately. For example here:
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:
@FortranFan People use implied
save
unfortunately. For example here: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.
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: https://github.com/j3-fortran/fortran_proposals/issues/40#issuecomment-554108654. 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.)
And we need automatic facility to find implicit save usage in codes and fix it, automatically.
This would be quite easy to write. We wouldn't even need a full parser. All that would be necessary is the ability to:
SAVE ::
statementsFORD 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.
@FortranFan People use implied
save
unfortunately. For example here: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, 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.
module m_gstate
...
integer, target, protected, save :: ndtpawuj = 4
..
contains
...
subroutine subroutine pawuj_drive( ..
...
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.
@sblionel I think, we have to balance between not making to much trouble to existing Fortran projects and keeping Fortran appealing enough for new projects. The long term survival of the language may depend even more on new projects than on existing ones. And when the decision for the programming language in a new scientific / numeric project is made, Fortran has to compete mostly with Python, Julia and C++, so the competition is quite strong. While you can bring rational pro and con arguments for all those languages, the appeal of the language will also play a major role. And implicit none
for example is definitely not sexy.
@certik The comparison with the Python 2 / Python 3 framework holds only partially. By introducing for example a language keyword (OT of this issue :wink: ), all projects would be warranted to compile unchanged till the end of times, as the language keyword (or its absence) would let the compiler know, which backwards incompatible changes it is allowed to consider and which ones not.
I am not advocating the language keyword as the ultimate solution (explicit all
as suggested in #40 would solve several our current issues as well). But I think it demonstrates very well, that we could have ways to improve on the language, retire constructs which did not prove to be useful and make it more appealing for new projects without affecting existing projects.
@klausler wrote:
.. 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.
Semantics in programming language theory begins with the evaluation of syntactically valid tokens in a language and when a token itself is syntactically invalid in one form in Fortran e.g., P R I N T
versus another, the argument the two source forms are semantically equivalent is totally bogus
P R I N T *, "Hello there, the differences between free source for
1m and fixed form in Fortran are in the gray area between syntax an
2d semantics, particularly with the significance or lack thereof wi
3th blanks in statements and with line continuation in character co
4ntext"
END
@FortranFan If possible, please give @klausler some benefits of the doubt. My own understanding is also that the semantics of fixed form and free form are indeed identical. What I mean by that is that once you do the parsing (one way or another) and represent the syntax using Abstract Syntax Tree (AST), the AST nodes are identical, as far as I can tell so far. The example you gave would have the same AST node (Print
), and it would have an argument of type string, that is properly processed. Then when you add the semantics (types), it should still be identical. I think there are some differences that you pointed out, but they do not seem to translate to any differences on the AST level.
@certik wrote:
.. I think there are some differences that you pointed out, but they do not seem to translate to any differences on the AST level.
I really don't think how a parser might represent some source in AST or whatever format has anything to do with semantics at the most basic level. For a given programming language, semantics would allow instructions to be evaluated based on some rules in a completely independent manner by anyone or anything, it can be a group of faithful after a Sunday service or 'Despicable Me' minions or whatever that can strictly follow the rules.
Under the circumstances, the shortest (perhaps) of a complete fixed-form source E N D
cannot evaluated at all under the rules of free-form source and thus the argument the 2 forms are equivalent semantically or otherwise becomes entirely moot.
C:\temp>type p.for
E N D
C:\temp>gfortran -c p.for
C:\temp>type p.f90
E N D
C:\temp>gfortran -c p.f90
p.f90:1:6:
E N D
1
Error: Unclassifiable statement at (1)
C:\temp>
Sure, the source can be modified syntactically to remove the 2 offending blanks and the processor for free-form can then translate it into something that will be the same as with fixed-form. The entire premise of viewing the two as same resides on trivializing the action behind the removal of 2 blanks.
But the bothersome aspect here is there is no consistency in such 'courtesy': should one have to port some implicitly typed code in fixed-form to free-form, why not be totally open-minded to the need to perform an 'action' like explicitly declare the variable when one is open to do the same with the supposedly insignificant blanks in one's fixed-form source anyway? Once such an action is taken, both forms would output the same AST nodes.
C:\temp>type p.for
I = 42
END
C:\temp>gfortran -c p.for
C:\temp>type p.f90
I = 42
END
C:\temp>gfortran -c -fimplicit-none p.f90 !<-- simulate 'new' default with -f switch
p.f90:1:7:
I = 42
1
Error: Symbol 'i' at (1) has no IMPLICIT type
C:\temp>type p.f90
INTEGER I
I = 42
END
C:\temp>gfortran -c p.f90
C:\temp>
I think that I'm wasting my time here.
@klausler, @FortranFan We should come back to the original topic: is it desirable to have a keyword which allows to deprecate harmful features without breaking backwards compatibility? Therefore, we are talking about an explicit new keyword, not about existing source code format. Currently, this could help us to deprecate:
equivalence
, entry
, etc.)All those deprecations would be backwards compatible in the sense that all codes not specifying this keyword (or specifying an old language version) would behave as ever. Only new codes explicitely declaring being modern Fortran would be affected.
The first two items could be equivalently realized in a backwards compatible way by implicit none (type, external, save)
or by the much shorter and in my opinion much more appealing explicit all
as suggested by @FortranFan.
So the the question really is, whether the possibility of deprecating all other constructs and the possibility of being able to handle future deprecations on the same foot (by using a language version identifier) are worth to introduce a new keyword in the language. And whether the concerns raised so far (e.g. by @gronki ) are severe enough we dispose the idea (and close this issue).
Are there any other commonly used programming languages that have such a concept, and if so, what does it look like?
I get the desire for disabling some of the older features, and a coding standard (organization imposed) that might require same, but I'm struggling to see how this feature helps with existing code or would make life easier for new development. The changes to IMPLICIT
allow the compiler to detect missing types or external attributes, but disabling implicit SAVE
is not something a compiler could reliably detect a violation of.
I'll note that obsolescent and deleted features (EQUIVALENCE
, ENTRY
, etc.) are already easily called out simply by asking the compiler to issue standards warnings, though I often heard from users that they would like this to be finer grained (VAX FORTRAN allowed you to say that tab source form was ok, but not other standards violations, for example.)
There have been attempts before (F, ELF) to trim down the language to "only the new stuff", and they were roundly ignored. Once you start down this road, where do you stop? Does every Fortran program need an associated XML document enabling or disabling hundreds of language features? Is that Fortran anymore?
I agree 100% that some of these ancient features are responsible for subtle errors in applications - I sure saw enough of them in my decades of doing Fortran user support. I'm just having a hard time with the idea of versioning the language.
@aradi wrote:
.. @FortranFan We should come back to the original topic: is it desirable to have a keyword which allows to deprecate harmful features without breaking backwards compatibility? .. ..
@aradi with respect to the issues at hand with implicit typing and implied save, trying to retain backwards compatibility in the standard itself is a severely limiting constraint that will likely lead to highly suboptimal solution(s).
And it also appears an exercise in futility since almost all the processors figure out other ways to continue supporting the removed features any way..
Thus with implicit typing and implied save, I prefer to see the language just delete them outright.
Such a move can be a boon for vendors who will then invent ways their processors can avoid the breaking of old code that rely on these 2 aspects, should there be such code-bases out there at all.
But everyone else will be freed up once and for all to cleanly work with a modern, type-safe Fortran that perhaps will also allow in situ variable declarations and initialization.
The other 2 categories are not of much concern:
external procedures are mostly a thing of the past, at least in the few codes that are in Fortran in the teams I work with; unlike implicit typing and implied save, we don't worry about hidden traps involving them especially because the few new coders are more than happy to develop CONTAINed procedures in MODULEs and SUBMODULEs.
same with old features such as EQUIVALENCE, ENTRY, etc. or constructs such as arithmetic GOTO - there is hardly any risk of inadvertent usage of these things since no one I know who wants to use these facilities.
Thus I feel the language version keyword is not needed.
Javascript also has use strict
: https://www.w3schools.com/js/js_strict.asp
@sblionel No, I don't know any languages having this kind of versioning, so maybe it is not a very good idea at all. Still, I see it as a good compromise since it would allow to deprecate bad practices without breaking backwards compatibility. (In this point I disagree with @FortranFan as I still think that keeping backwards compatibility is important for a serious programming language.) It should not be an individual choice, allowing each one to cherry-pick his favourite features / deprecations (as you suggest with the XML-file approach). This you can do by using appropriate compiler flags anyway already. It would rather offer a standardized (compiler vendor independent) way for a programmer to make sure, she/he complies with those coding practices, which the Fortran standard committee has found advisable at the time of a given standard.
I think that some form of "hardening" keyword is perharps the golden solution as long as, similarly to "implicit none", it prohibits obsolete programming style (implicit typing, implicit save without explicit "save" keyword, etc.) and does not change behavior of already conforming codes. Which means when if removed the program will behave exactly the same.
Perhaps a keyword like "strict" could be introduced (or, proposed by someone, "modern") that would enable "implicit none" and keep strict prohibition of features marked as "obsolete" in the standard. At the same time, programs with that keyword would not be guaranteed to be standard-conforming indefinitely. If you want your software to run for the next 50 yrs unchanged (for example, because of certification issues), just comment/remove that line in the code you deliver to the customer.
What do you think about this approach?
wt., 19 lis 2019 o 16:43 Bálint Aradi notifications@github.com napisał(a):
@sblionel https://github.com/sblionel No, I don't know any languages having this kind of versioning, so maybe it is not a very good idea at all. Still, I see it as a good compromise since it would allow to deprecate bad practices without breaking backwards compatibility. (In this point I disagree with @FortranFan https://github.com/FortranFan as I still think that keeping backwards compatibility is important for a serious programming language.) It should not be an individual choice, allowing each one to cherry-pick his favourite features / deprecations (as you suggest with the XML-file approach). This you can do by using appropriate compiler flags anyway already. It would rather offer a standardized (compiler vendor independent) way for a programmer to make sure, she/he complies with those coding practices, which the Fortran standard committee has found advisable at the time of a given standard.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/83?email_source=notifications&email_token=AC4NA3OCHJRSE6YEUXMG5ILQUQCT7A5CNFSM4JMWOOT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEOUMXA#issuecomment-555566684, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4NA3KG35U5JMUD2M5GJ3LQUQCT7ANCNFSM4JMWOOTQ .
And the reason that I propose this as a part of the language (and not a compiler switch) is that I think standard should be more enforcing about not using old features. Just because implicit typing is in the standard for backwards compatibility, nobody seriously considers it a legitimate of the language in 2019. For now, I feel the standarization entities are too passive about letting people still use this features.
wt., 19 lis 2019 o 17:35 Dominik Gronkiewicz gronki@gmail.com napisał(a):
I think that some form of "hardening" keyword is perharps the golden solution as long as, similarly to "implicit none", it prohibits obsolete programming style (implicit typing, implicit save without explicit "save" keyword, etc.) and does not change behavior of already conforming codes. Which means when if removed the program will behave exactly the same.
Perhaps a keyword like "strict" could be introduced (or, proposed by someone, "modern") that would enable "implicit none" and keep strict prohibition of features marked as "obsolete" in the standard. At the same time, programs with that keyword would not be guaranteed to be standard-conforming indefinitely. If you want your software to run for the next 50 yrs unchanged (for example, because of certification issues), just comment/remove that line in the code you deliver to the customer.
What do you think about this approach?
wt., 19 lis 2019 o 16:43 Bálint Aradi notifications@github.com napisał(a):
@sblionel https://github.com/sblionel No, I don't know any languages having this kind of versioning, so maybe it is not a very good idea at all. Still, I see it as a good compromise since it would allow to deprecate bad practices without breaking backwards compatibility. (In this point I disagree with @FortranFan https://github.com/FortranFan as I still think that keeping backwards compatibility is important for a serious programming language.) It should not be an individual choice, allowing each one to cherry-pick his favourite features / deprecations (as you suggest with the XML-file approach). This you can do by using appropriate compiler flags anyway already. It would rather offer a standardized (compiler vendor independent) way for a programmer to make sure, she/he complies with those coding practices, which the Fortran standard committee has found advisable at the time of a given standard.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/83?email_source=notifications&email_token=AC4NA3OCHJRSE6YEUXMG5ILQUQCT7A5CNFSM4JMWOOT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEOUMXA#issuecomment-555566684, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4NA3KG35U5JMUD2M5GJ3LQUQCT7ANCNFSM4JMWOOTQ .
I think this modern
(or strict
) keyword is another way, so I added it to my list above: https://github.com/j3-fortran/fortran_proposals/issues/83#issuecomment-553481507.
@aradi wrote:
.. In this point I disagree with @FortranFan as I still think that keeping backwards compatibility is important for a serious programming language.) ..
@aradi , please note I'm not against backwards compatibility in a general sense, I'm completely for a thorough consideration always to "do no harm" a la Hippocratic oath when it comes to introducing new features in the language. But I do think implicit typing and implied save are so harmful to Fortran's well-being, these two are so gangrenous that I now believe they need to be amputated.
@certik wrote:
I think this
modern
(orstrict
) keyword is another way, so I added it to my list above: #83 (comment).
Sometimes I wonder, for how long will we the current Fortran be "modern". I imagine future Fortranners will laugh back at us Fortran 2018 people at some point too. If I can remember correctly, there are some books that referred to even Fortran 77 (or perhaps 90) as "modern" Fortran (in comparison to Fortran IV).
@gronki wrote:
And the reason that I propose this as a part of the language (and not a compiler switch) is that I think standard should be more enforcing about not using old features.
I don't see why the standard should be more enforcing. Aren't we all responsible users? Most modern ;) Fortran books mark these features as obsolescent, meaning that as long as programmers are up to date with the current language standard (much easier with Fortran, than any other programming language I know), these features should not appear in any newly developed codes. If you depend on some old codes you can always use one of the automatic tools to convert it to Fortran 90, or perhaps even refactor it.
Now, to comment on the actual issue. Something which I find vaguely similar to the proposed language version keyword is the way one can specify the file encoding in Python: https://www.python.org/dev/peps/pep-0263/#defining-the-encoding
A simple way to get the desired effect would be to have a similar thing, e.g.
!!! -*- version: Fortran 2060 -*-
program main
! no implicit none needed because explicit typing is now default ;)
...
end program
The way I see it the compiler would then just turn the right language subset compilation flags on and voila.
@ivan-pi I absolutely agree, a term like modern
has a very short half-life. This is why I proposed explicitly using the standard publication year. As for the format: one could also make it a special comment instead of a language keyword, then probably more similar how OMP-comments work, e.g. !$FLANG VERSION(2028)
, but that is only a technical question. The big question is, whether the syntax should be specified by the standard or not. If it is not specified by the standard, then different compiler would probably use a different syntax (similar how different compiler use different flags to enforce certain language features), which would be not really helpful.
@septcolor Yes, one could make it at the module level also in Fortran, as I suggested above (module, language(f2035) :: my_module
). The slight issue is, that module level modifiers (e.g. implicit none
, private
, etc.) in Fortran usually come after the module level imports via use
statement, although, I am not sure about the exact reasons.
Do we all agree that the "strict" keyword will only disable obsolescent features and not change the behavior of the existing features?
czw., 12 gru 2019 o 11:10 Bálint Aradi notifications@github.com napisał(a):
@ivan-pi https://github.com/ivan-pi I absolutely agree, a term like modern has a very short half-life. This is why I proposed explicitly using the standard publication year. As for the format: one could also make it a special comment instead of a language keyword, then probably more similar how OMP-comments work, e.g. !$FLANG VERSION(2028), but that is only a technical question. The big question is, whether the syntax should be specified by the standard or not. If it is not specified by the standard, then different compiler would probably use a different syntax (similar how different compiler use different flags to enforce certain language features), which would be not really helpful.
@septcolor https://github.com/septcolor Yes, one could make it at the module level also in Fortran, as I suggested above (module, language(f2035) :: my_module). The slight issue is, that module level modifiers (e.g. implicit none, private, etc.) in Fortran usually come after the module level imports via use statement, although, I am not sure about the exact reasons.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/83?email_source=notifications&email_token=AC4NA3IBHSBGUBNS2HSGIXDQYIEZPA5CNFSM4JMWOOT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGWEYAA#issuecomment-564939776, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4NA3NZVI2XZDGPE3ZSP7LQYIEZPANCNFSM4JMWOOTQ .
Do we all agree that the "strict" keyword will only disable obsolescent features and not change the behavior of the existing features?
No, we don't. It's the opposite, at least when it comes to implicit SAVE
from object initializers.
I agree to @klausler. The idea (at least what I had in my mind) is exaclty the opposite. A language version keyword would allow us to change the default behaviour of Fortran (requiring explicit declarations, explicit save
attributes, etc.) in new codes specifying that keyword and without affecting existing codes where the keyword is not specified. So we want to introduce a gentle backwards incompatibility without affecting existing codes.
Then I disagree. This idea is absolutely catastrophic. Under no circumstance should the code behavior change after removing the language version modifier.
pt., 13 gru 2019, 17:22 użytkownik Bálint Aradi notifications@github.com napisał:
I agree to @klausler https://github.com/klausler. The idea (at least what I had in my mind) is exaclty the opposite. A language version keyword would allow us to change the default behaviour of Fortran (requiring explicit declarations, explicit save attributes, etc.) in new codes specifying that keyword and without affecting existing codes where the keyword is not specified. So we want to introduce a gentle backwards incompatibility without affecting existing codes.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/83?email_source=notifications&email_token=AC4NA3O42AWHNSKZZVYTBA3QYOZEXA5CNFSM4JMWOOT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG2O3YY#issuecomment-565505507, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4NA3LPS6ZGTWTYGJ6ZQ2LQYOZEXANCNFSM4JMWOOTQ .
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.
@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.
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.one would just write
to profit from all the features / requirements a given Fortran standard offers / enforces.