-
Notifications
You must be signed in to change notification settings - Fork 15
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
Allow ASSOCIATE to reference previous names in the same ASSOCIATE constuct, e.g. ASSOCIATE(b=>a, c=>b) #321
Comments
J3 definitely got this case wrong, but it's too late to change the scoping of
The construct entity |
I missed that case :/ So in the end, an extension of associate would be more problematic than expected after all. However. It raises a bit the question of whether "reusing a name in As I understand, the standard says that Using
This inconsistency hints at real-world programs already having to avoid this scenario, if they want to work with an Intel compiler. By contrast,
Possible solutionThe behavior of Intel (albeit apparently unintended) hints at a possible solution of backwards compatibility.
Precedent for backwards-incompatible changesNote that changing the behavior of pre-existing code is already not new to Fortran.
Using
Arguably, the old behavior is unsafe, as it allows assignments between different-size arrays, that are quite possibly unintended, with neither compile-time nor run-time warning or error. The “realloc lhs” behavior already changes the behavior of existing statements. (Though honestly, I consider that to be an issue, as it can change the behavior of a program without proper warning, so I'd rather be in favor of not changing the behavior of previously standard-conforming programs.) |
Fortran doesn't require any declaration or use of a name in an outer scope to make that name exist in that scope. This already comes up in the context of module & inner procedures. But even if that were not a concern, the change you suggest would present a danger to code that might declare a name in the other scope later. The F'2003 semantics for assignments to allocatables did not invalidate any working conforming code. (F'2023 has a regrettable change that does change behavior in working conforming code, but that is a mistake.) |
@kbauer commented Nov. 21, 2023 03:43 AM EST:
@kbauer , I generally support the sentiment behind your request for an enhancement to the As noted, what you suggest in the original post here, if left as is, will most likely be DoA with the standard committee. So why don't you then consider adapting to the situation, say you propose some clause(s) to go with integer :: foo = 1, bar = 2
associate ( chain=yes ) ( foo => bar, baz => foo )
print *, baz
end associate
end So then with the clause as in The employment of such a clause is one way I can think of to get around the problematic situation due to existing semantics. Those with Fortran compiler development background and experience might be able to come up with better alternatives. The key is the mindset, how to develop solutions that enhance the practice of Fortran: an improved |
I suggest this for the new semantics:
That is, the selectors in a parenthesized associate-list can reference names defined in earlier lists. Also, it would be helpful for compilers to warn about the original |
This comment was marked as spam.
This comment was marked as spam.
This code was invalid and with an undefined behavior before Fortran 2003 (incompatible shapes of lhs and rhs) |
I like this one above. It's not verbose and it has a clear interpretation, i.e. equivalent to
|
It also works well with continuation lines.
|
There is a world of difference between a change that only affects buggy non-conforming code and.a change that alters the behavior of correct conforming code. The F'03 change to assignment to allocatables affecting existing applications mildly -- some code slowed down until |
I fully agree, and this was actually my point in the message you have quoted.
Which one ? |
This comment was marked as spam.
This comment was marked as spam.
Honestly, I was simply not aware, that the old behavior was not standard-conforming. It seems to have been implemented by at least Intel Fortran and GFortran in this manner though. |
Very clean and definetely useful! Fortran needs solutions to help reduce nesting dozens of |
I have just been bitten by ifort/ifx, which does chain the associations:
it prints |
The
ASSOCIATE
construct is useful to introduce names for expressions in a scoped manner, but its utility is limited the frequent use for nesting. Utility would be significantly improved, if referencing previously associated names in the sameASSOCIATE
block would be allowed, i.e.and similar.
1. Related suggestions
1.1. LET semantics
There are suggestions for a more general construct, usually referring to the concept as
let
, e.g. “A shorthand for immutability #221” and “LET statement concept #279”.If such suggestions would gain traction, they would cover this use-case.
However, they are much larger in scale. Extending the standard-compliant behavior of the
ASSOCIATE
construct seems more likely to be accepted into the standard:1.2. Variable initialization without SAVE attribute
A similar purpose with more explicit typing would be fulfilled by “Syntax to initialize variables in declarations without SAVE #234” and “Deprecate and remove implicit save behavior #40”.
This suggestion still has the advantage of being independent of backward-compatibility considerations such as arise with disabling the implicit
SAVE
attribute.Compared to #234, this suggestion allows a more terse syntax, where types are inferred, using an already-existing mechanism.
2. Real world example
For example, the following block-construct is an anonymized version of code I wrote in my workplace project:
Ideally, this BLOCK could be replaced with
This is allowed by Intel Fortran, with the expected behavior. It is rejected by, for instance,
gfortran
, and does indeed not seem to be standard conforming. See e.g. discussion in this stackoverflow.com post.In order to be allowed across compilers, currently nesting is
required, where each associate construct can only see names associated
in an outer scope.
The increase in nesting level hinders code readability and effectively discourages use of the
ASSOCIATE
construct.In practice most code in the project does not use either
BLOCK
orASSOCIATE
, and instead defines all local variables at the subroutine level, which leads to problems with refactoring, as values assigned in one section of large subroutines by default leak to the next section, regardless of whether the value, or only the variable name, is reused.3. Limitations
Between this suggestion and those linked in “1. Related Suggestions”, none address the very much real-world scenario of needing to explicitly declare output variables for subroutines.
Since there is currently no efficient way of returning large data structures (vectors, matrices, ...) from a function, and due to the use of long-existing APIs like
LAPACK
, it is common in Fortran to see results returned by output parameters.For these, more convenient declaration of variables close to the code line, where they are first needed, would be discussed, e.g. implicit blocks, where
would be equivalent to
The text was updated successfully, but these errors were encountered: