Skip to content

Allow setting default value for optional dummy argument #22

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

Open
milancurcic opened this issue Oct 18, 2019 · 47 comments
Open

Allow setting default value for optional dummy argument #22

milancurcic opened this issue Oct 18, 2019 · 47 comments
Labels
Clause 8 Standard Clause 8: Attribute declarations and specifications Fortran 202y Proposals targeting the standard after F2023 under consideration Has been submitted to the committee

Comments

@milancurcic
Copy link
Member

Problem

Currently, Fortran doesn't allow setting a default value for optional dummy arguments. If declaring a dummy argument as optional, the user must:

  1. Manually make appropriate checks about whether the actual argument is provided by the caller;
  2. Use a separate variable inside the procedure because the code must not reference the optional dummy argument if not present.

Example

Example of a quadratic function that optionally allows evaluation of its linear form:

real function quadratic(x, a, b, c)  
  ! returns a + b * x + c * x**2 if c is present and a + b * x otherwise
  real, intent(in) :: x, a, b
  real, intent(in), optional :: c
  real :: c_tmp ! use separate variable to avoid referencing non-present arg
  if (present(c)) then
    c_tmp = c
  else
    c_tmp = 0 ! default value if c is not present
  end if
  quadratic = a + b * x + c_tmp * x**2
end function quadratic

Checking for presence of the optional argument and using a temporary variable is cumbersome and error-prone, and it is even more so if the same needs to be done for many optional arguments.

Solution

Allow setting the default value of the optional argument in the function (or subroutine) statement by using the assignment operator =:

real function quadratic(x, a, b, c=0)
  ! returns a + b * x + c * x**2 if c is present and a + b * x otherwise
  real, intent(in) :: x, a, b
  real, intent(in), optional :: c
  quadratic = a + b * x + c * x**2
end function quadratic

This is similar to how Python keyword arguments are defined.

Comments

  • The proposed syntax is complementary to the existing syntax, that is, it doesn't break existing code;
  • Its style is more or less Fortranic and consistent with other syntax elements;
  • Same syntax as Python keyword args, so it would be intuitive to Python developers learning Fortran;
  • Could be implemented completely as a pre-processor, for a proof-of-concept.
@certik
Copy link
Member

certik commented Oct 18, 2019

Yes, great idea. I usually do it like this:

real function quadratic(x, a, b, c)  
  ! returns a + b * x + c * x**2 if c is present and a + b * x otherwise
  real, intent(in) :: x, a, b
  real, intent(in), optional :: c
  real :: c_
  c_ = 0
  if (present(c)) c_ = c
  quadratic = a + b * x + c_ * x**2
end function quadratic

Which is simpler than your original code, but it's still cumbersome to always introduce the local variable and do the present(c) check.

Does Fortran support default non-optional arguments? My only suggestion would be to perhaps introduce default values for any arguments, not just optional.

@milancurcic
Copy link
Member Author

What is the meaning of default non-optional arguments? If an argument is required, where does its default value come into play?

@certik
Copy link
Member

certik commented Oct 18, 2019

What is the meaning of default non-optional arguments? If an argument is required, where does its default value come into play?

My bad, I think you are right. It only makes sense for optional arguments.

@certik
Copy link
Member

certik commented Oct 18, 2019

The other suggestion I have is that in Fortran one specifies all argument things in the declaration, not in the argument list so perhaps something like this:

real function quadratic(x, a, b, c)
  ! returns a + b * x + c * x**2 if c is present and a + b * x otherwise
  real, intent(in) :: x, a, b
  real, intent(in), optional, default :: c = 0
  quadratic = a + b * x + c * x**2
end function quadratic

Would be more consistent with Fortran conventions.

The new default attribute would specify that the = 0 does not imply the save attribute. The default attribute can then be used with any variable, not just arguments, like this:

integer, default :: n = 5

Perhaps one could use init, or initialize instead of default.

@milancurcic
Copy link
Member Author

I like the default attribute. Less Pythonic, but more Fortranic for sure.

Of course, I had to use the more verbose variant to better sell the proposal. :D

@certik certik added Fortran 202y Proposals targeting the standard after F2023 unsubmitted Has not been submitted to the committee yet labels Oct 18, 2019
@certik
Copy link
Member

certik commented Oct 18, 2019

I like the default attribute. Less Pythonic, but more Fortranic for sure.

The proposal can have both options, and the community and committee can discuss pros and cons of both, and then pick one.

Of course, I had to use the more verbose variant to better sell the proposal. :D

I would suggest you change it to the shorter version, as we want to compare against the best current practice, not a longer variant.

@milancurcic
Copy link
Member Author

I'd be happy to prepare the first draft of the proposal, and you can take it from there. Does target for meeting #221 (February 2020) make sense?

@certik
Copy link
Member

certik commented Oct 18, 2019

I'd be happy to prepare the first draft of the proposal, and you can take it from there. Does target for meeting #221 (February 2020) make sense?

Yes! The October Committee Meeting ended, and what I would like to do differently than what the committee has been doing so far, is to prepare a very good proposal collaboratively on GitHub. Send a PR once you have a draft, let's work on it together and with others. And then once a good initial proposal is ready, I'll pitch it to the j3-members committee mailinglist, to get feedback from the committee, and that way we have a very solid proposal when the committee meets the next time and we'll take it from there. Finally, I would reiterate my invitation for you to join the committee. We need help.

@certik
Copy link
Member

certik commented Jan 3, 2020

This should be implemented in the language. It's a simple change and it would go a long way. In the meantime, we will implement a helper function in stdlib: fortran-lang/stdlib#62, here is a preliminary implementation: fortran-lang/stdlib#73. The above example would look:

real function quadratic(x, a, b, c)  
  ! returns a + b * x + c * x**2 if c is present and a + b * x otherwise
  real, intent(in) :: x, a, b
  real, intent(in), optional :: c
  real :: c_
  c_ = optval(c, 0.)
  quadratic = a + b * x + c_ * x**2
end function quadratic

Which is not bad, but not as nice as having it in the language:

real function quadratic(x, a, b, c)
  ! returns a + b * x + c * x**2 if c is present and a + b * x otherwise
  real, intent(in) :: x, a, b
  real, intent(in), optional, default :: c = 0
  quadratic = a + b * x + c * x**2
end function quadratic

Note: in this particular case, since we need c exactly once, one can simplify it with stdlib to just:

real function quadratic(x, a, b, c)  
  ! returns a + b * x + c * x**2 if c is present and a + b * x otherwise
  real, intent(in) :: x, a, b
  real, intent(in), optional :: c
  quadratic = a + b * x + optval(c, 0.) * x**2
end function quadratic

but this does not work well if c is needed more than once.

@sblionel
Copy link
Member

sblionel commented Jan 5, 2020

This proposal got some votes in the user survey for 202X, and it is one I personally like. It appeared on Data subgroup's wishlist at meeting 215 (see https://j3-fortran.org/doc/year/18/18-122r1.txt) https://j3-fortran.org/doc/year/18/18-136r1.txt with "use cases" was passed at meeting 216, but it didn't make it onto the "official" US request list - it's not clear to me if this was an oversight or the lack of a formal proposal. In either case, I would support this for 202Y.

@zbeekman
Copy link

zbeekman commented Jan 6, 2020

I too support this.

@certik
Copy link
Member

certik commented Jan 6, 2020

Ok, let's write a good proposal for this and submit for the February meeting (#122) to get initial feedback from the committee. As indicated at #122, the following people listed this proposal in their top 5:
@milancurcic, @epagone, @zjibben, @qolin1. The following people mentioned it that they like it to be pursued: @jvdp1, @marshallward. And there are people who expressed support here directly, such as @zbeekman and others who liked the issue.

@milancurcic would you be able to take a lead on writing a proposal for this? The others listed in this comment, if you could help Milan write it, that would be very helpful. (I'll try to help too, but there are other proposals that I want to help with also.)

@qolin1
Copy link

qolin1 commented Jan 7, 2020

Yes I am in.

While we are here, I have some questions & comments...

Firstly, why should the DEFAULT keyword be needed? Seems to me that the mere presence of an equated value after the variable name will be sufficient, as in:

real function quadratic(x, a, b, c)
! returns a + b * x + c * x2 if c is present and a + b * x otherwise
real, intent(in) :: x, a, b
real, intent(in), optional :: c = 0
quadratic = a + b * x + c * x2
end function quadratic

As far as I am aware, there is currently no way the language will allow an equated value for a variable declared as a dummy argument, so this seems sufficient to me. Also, providing a new keyword like DEFAULT might mislead folk into trying to put it on non-optional arguments and other (local variable) declarations. (If the intention is to distinguish this from the implicit save problem, then the name DEFAULT is not a good one, because it doesn't really mean "do not save". And I think we should keep this proposal well clear of any argument about implicit save.) Also also, when 2 or more arguments are declared in one statement, we would not wish to require them all to be given a default value, or none of them; this would be the implication of the presence of the DEFAULT keyword.

Second: do we allow the default value to change a simple variable into an array? Eg:

Subroutine fred(a,b)
real, intent(in) :: a
real, intent(in), optional :: b = [1d0,2d0]

Note that, absent the default, there is nothing in the declaration of B that makes it an array. IMO this should not be allowed, explicit shape information or the DIMENSION keyword should be required.

Third: should the feature work for UDTs? Eg:


type t_stuff
real :: a = 22
real :: b = 33
real :: c = 44
end type
subroutine uu(ff, st)
real, intent(in) :: ff
real, optional :: st = t_stuff(66,c=88)

Fourth: should it work on an OPTIONAL statement? eg:

Subroutine fred(a,b)
real, intent(in) :: a, b
optional :: b = [1d0,2d0]

Fifth: what about allocatables? eg:

Subroutine fred(a,b)
real, intent(in) :: a
real, intent(in), allocatable, optional :: b(:) = [1d0,2d0]

This creates a default allocated array with 2 elements. I can't, however, see an obvious way to get an unallocated array as a default. Maybe it could be done by combining with the next one...

Sixth: should it allow initialization to a non-constant expression? eg:

module jimmy
real :: ddd(100)
end module
! ...lots of lines of code later, after ddd has been set
subroutine billy(aaa,bbb)
use jimmy
real, intent(inout) :: aaa(20)
real, intent(inout), optional :: bbb(:) = ddd

...That's probably more than enough for the moment.

@milancurcic
Copy link
Member Author

@milancurcic would you be able to take a lead on writing a proposal for this? The others listed in this comment, if you could help Milan write it, that would be very helpful. (I'll try to help too, but there are other proposals that I want to help with also.)

Sure, I will submit an initial draft in a PR later this week and we can iterate on it together.

@certik
Copy link
Member

certik commented Jan 7, 2020

@qolin1 thanks a lot for the feedback. Excellent ideas. Here are my comments.

  1. I think you are right, we don't need the default. Yes, I put it there to ensure no save, but as you said, the save would not be implied in this case anyway. I really like just this, exactly as you suggested:
real function quadratic(x, a, b, c)
! returns a + b * x + c * x2 if c is present and a + b * x otherwise
real, intent(in) :: x, a, b
real, intent(in), optional :: c = 0
quadratic = a + b * x + c * x2
end function quadratic
  1. No.

  2. Yes.

  3. Yes. I didn't even know about an optional statement.

  4. Yes.

  5. I would say to start with requiring the expression to be constant. We can brainstorm if it makes sense for it to be variable. It seems it could create more confusion than it is worth it.

@epagone
Copy link

epagone commented Jan 7, 2020

@qolin1 these are my thoughts.

  1. I agree with you and @certik on this one but I already hear the objection that the same syntax in different scoping units meaning different things (i.e. implicit save in some contexts and optional default values in this case) should not be allowed. My best reply would be to deprecate in parallel implicit save with proposal Deprecate and remove implicit save behavior #40. However, this carries the risk that if Deprecate and remove implicit save behavior #40 is shot down, then also this one can be refused, so maybe a better strategy to respond to this objection must be thought...

  2. Should not be allowed, as you suggest.

  3. Yes.

  4. Yes.

  5. I don't fully understand what is the problem you're discussing here. I think

Subroutine fred(a,b)
real, intent(in) :: a
real, intent(in), allocatable, optional :: b(:) = [1d0,2d0]

should be allowed with b allocated by default to [1d0,2d0] but it would be possible to set in subroutine fred b = [1d0,2d0,3d0,4d0,5d0] (i.e. fixed shape but any size, since b is an allocatable array).

  1. I understand @certik 's concerns about this but I think it should be allowed.

@certik
Copy link
Member

certik commented Jan 7, 2020

Regarding 1.: Note that, as I mention in #40, that "One can apparently use integer :: a, b, c = 2 in the main program, in module variable and in derived types already, and it will not imply save." So this proposal #22 just adds another case: "in optional arguments it will also not imply save". So it's not unprecedented even if #40 is not (immediately) accepted.

P.S. @milancurcic make sure you use this argument in the proposal.

@epagone
Copy link

epagone commented Jan 7, 2020

@certik I was looking for the fingers crossed emoji to be added next to the thumb up as a reaction to your post, but it's not available on GitHub... 😜

@sblionel
Copy link
Member

sblionel commented Jan 7, 2020

Any proposal should specify whether the default value may be a specification expression or must be a constant expression. The latter would be consistent with initialization, but the former would be more useful. Note that the rules for specification expressions already prohibit an object designator with OPTIONAL or INTENT(OUT).

Since a default value would be allowed only for optional arguments, that implies an explicit interface requirement.

@qolin1
Copy link

qolin1 commented Jan 7, 2020

Um Steve, Please clarify for us what is meant by an "object designator". If we have an example default initialization such as:

real, intent(out), optional :: aa = b+c*d

My understanding is that b, c and d are object designators, but aa is not. Please correct me.

@sblionel
Copy link
Member

sblionel commented Jan 7, 2020

Sorry, was quoting the standard regarding specification expressions. In your example, b, c and d are the object designators in question. The issue is what is allowed to appear in the default value expression. If it's a specification expression, it can reference things such as other dummy arguments and module variables. If it's a constant expression, it is restricted to only those things that can be evaluated at compile-time, which is the case for initialization. (Indeed these used to be called "initialization expressions".)

The more details worked out in advance for a proposal, the better chance it has to move forward. One can even propose edits (ideally including complete new wording to make it easier to understand and read.)

What I envision for this is that the caller could evaluate and pass the default values, since it already needs to know how to do this for some specification expressions.

@certik
Copy link
Member

certik commented Feb 26, 2020

This proposal was discussed on Tuesday Feb 25 in the morning, I set the timer for 5 minutes, @zjibben gave an overview for about 3 minutes and then we discussed for about 20 minutes at the plenary. We took notes of the feedback and I summarized it below.

Overall, we got excellent highly detailed feedback, and I would say the committee was generally positive about the idea. The approach suggested might not work directly, but the committee suggested an alternative approach that might work. Also lots of details must be figured out and fleshed out, and the proposal must be rewritten / improved accordingly.

Here is the detailed feedback. I tried to summarize it first, but not all the comments are necessarily consistent, so I simply present the comments:

  • what if the optional argument has the TARGET attribute?
  • consider VOLATILE and ASYNCHRONOUS attributes of dummy arguments
  • concerns with the paper
    • syntax: doesn't like assignment form
    • consider other syntax using keywords e.g., DEFAULT (0)
    • PRESENT should continue to work
  • retain semantics in chain of
    • INTENT IN, OUT same semantics?
    • paper needs to be rewritten
  • feature with no applicability
    • achieves little for the complexibility
    • adds no new capability
    • adding new ATTRIBUTE e.g., DEFAULT rather than OPTIONAL
  • retain PRESENT semantics
    • conditional expressions proposal offers option here with reducing code
      verbosity
  • PRESENT semantics must be retained
    • this paper has a lot of appeal to coders
  • concerns with the paper
    • assignment (=) syntax a non-starter, makes it more confusing
    • PRESENT semantics if retained this paper will add little value
    • However it's too risky to change PRESENT
    • nested subroutines with OPTIONAL will become confusing e.g., 4 levels lose track of what is actually present
    • The proposal for Fortran 202X had also failed because impact on PRESENT semantics was unclear
  • pushes responsibility on the compiler to introduce the equivalent of
    local temp variable, can impact performance
  • idea:
    • caller provides default
    • agrees on the DEFAULT
  • comments:
    • use cases can be supported by VALUE attribute
    • but most other committee members disagreed stating VALUE semantics has other implications
      such as copy-in, copy-out

To summarize, the issue is that we do not want to change the behavior of present(). But then the issue is that it becomes really complicated if the user provides the value high in the call chain, then the nested subroutines might change how they behave, thus potentially creating performance bottlenecks.

The best way forward seems to be not to tie the default value with optional arguments. Rather, to introduce “initial” (or “default”) attribute that can be applied to both local variables, as well as dummy variables. If applied to dummy variables, it would have no change in the subroutine itself --- the dummy argument would always be provided. However, at the call site, the compiler would put in the default value if the user does not provide it. That way there is no performance hit, and from the user perspective it achieves the same.

@milancurcic
Copy link
Member Author

Amazing, this is great feedback, I didn't expect that we'd get this much. Thanks @certik and @zjibben.

I think we can work with this. I will take some time to digest and write what I think.

@zjibben
Copy link
Member

zjibben commented Feb 26, 2020

Thanks for polishing the notes and posting @certik!

@certik
Copy link
Member

certik commented Feb 26, 2020

@milancurcic indeed, it went really well. We have done another one (#1) today, and in general I think we will be doing this from now on. So this is a great avenue how to have a discussion with the wider community and how the community can propose ideas for the language.

@jvdp1
Copy link
Contributor

jvdp1 commented Feb 26, 2020

Thanks @certik and @zjibben for presenting and leading the discussion, and reporting back the discussion. It is really encouraging.

@wclodius2
Copy link
Contributor

I have written a revision of the paper by @milancurcic, @jvdp1, and @zjibben that attempts to address most of the issues raised at the Feb. 25 meeting, and a few other issues that have come to my mind. The paper differs from the original primarily by:

  1. Restricting optional arguments to arguments with the INTENT(IN), VALUE, or no intent attributes.

  2. Requiring arguments with a default assignment to be explicitly given the DEFAULT attribute.

  3. Forbidding arguments from having both the DEFAULT and OPTIONAL attributes so that the PRESENT function retains its semantics.

  4. Allowing the expression on the right of the default assignment be a restricted expression and not just a constant expression.

  5. Strongly encouraging that the default assignment be in the FUNCTION or SUBROUTINE statement (and not the TYPE declaration statement) as probably being easier to parse.

  6. Discussing the implications of the constraints on intrinsic assignment, 10.2.1.2, their interpretation, 10.2.1.3, and the constraints on defined assignment, 10.2.1.4, and their interpretation, 10.2.1.5 on default array assignments.

  7. Briefly discussing the implications of an argument with the DEFAULT attribute also having any one of the POINTER, VOLATILE, ASYNCHRONOUS, or TARGET attributes.

@sblionel
Copy link
Member

This sounds great - when can we see the paper? The changes you propose are all those I support.

@wclodius2
Copy link
Contributor

I am a novice to GitHub. The introductory material on GitHub does a good job of telling me how to start my own project, but not how to participate in someone else's project. What steps do I need to take to upload the paper named revised_proposal.txt?

@milancurcic
Copy link
Member Author

William, great. If you navigate here:

https://github.com/j3-fortran/fortran_proposals/blob/master/proposals/default_optional_arguments/proposal.txt

In the upper right corner of the UI there is an "Edit" button. If you click on it, it will take you to an editor which you can use to replace the existing paper with yours. Submitting the change will open a new Pull Request in which we will then discuss and edit the revised version.

The above flow assumes that we edit existing proposal txt files. @certik @zjibben should we instead keep the old versions as separate files and add the new one in its own file (like J3 does)?

@wclodius2
Copy link
Contributor

wclodius2 commented Jul 10, 2020 via email

@wclodius2
Copy link
Contributor

FWIW trying to add a file at https://github.com/j3-fortran/fortran_proposals/tree/master/proposals/default_optional_arguments
gives the message: Uploads are disabled.
File uploads require push access to this repository.

@certik
Copy link
Member

certik commented Jul 11, 2020 via email

@wclodius2
Copy link
Contributor

You already have such a directory
https://github.com/j3-fortran/fortran_proposals/tree/master/proposals/default_optional_arguments
the one I need push access to

@milancurcic
Copy link
Member Author

milancurcic commented Jul 11, 2020

William, here's what you need to do:

  1. Fork this repository by navigating to https://github.com/j3-fortran/fortran_proposals and clicking on "Fork" in the upper-right corner.
  2. You now have a fork here: https://github.com/wclodius2/fortran_proposals. Add your paper here: https://github.com/wclodius2/fortran_proposals/tree/master/proposals/default_optional_arguments (you will have push access to your fork of this repo).
  3. Now navigate back to https://github.com/j3-fortran/fortran_proposals. Near the top of the page there will be a UI element asking if you want to submit a Pull Request with the changes in your fork. Click on it, edit if needed, and click on "open pull request" (or similar, I forget the exact words).

@wclodius2
Copy link
Contributor

The revised_proposal.txt has been checked into the repository.

@everythingfunctional
Copy link
Member

Just a comment. Keeping old files around with a naming convention for revisions kind of misses the point of having a version control system (the old versions can still be accessed if desired). But since not everyone interested in the project will be familiar with git, it's probably best to do it anyway.

@certik
Copy link
Member

certik commented Jul 13, 2020

@everythingfunctional I think we should work on just one file and add changes to it (e.g. in #175), but once we submit it to the J3 meeting for consideration, I think it's good to keep a copy around, so that you don't have to go into git history all the time to see what the original was that the J3 discussion is based upon.

@wclodius2
Copy link
Contributor

FWIW I have changed how the proposal discusses arguments with no intent. Instead of assuming that such arguments will be treated the same as INTENT(IN) or VALUE, I call no intent out separately and note how the wording in the standard should be phrased to either treat them the same as INTENT(IN) or VALUE or treat them like INTENT(INOUT) or INTENT(OUT).

@wclodius2
Copy link
Contributor

wclodius2 commented Jul 26, 2020 via email

@jvdp1
Copy link
Contributor

jvdp1 commented Jan 20, 2021

Just to remember that a revised version of the proposal is in the MR: #175 . It doesn't appear clearly in this thread...

@vansnyder
Copy link

During the development of Fortran 90, back when it was still called Fortran 8x, there was a proposal for an AUTOMATIC attribute. When RECURSIVE was added, the argument was that every variable that isn't SAVE is automatic. The standard's definition of "automatic variable" was needlessly narrowed to one that used a variable to specify a bound or length parameter. I no longer have records from that time; I sent them to the Computer History Museum. Loren Meissner is the curator for them.

Had the AUTOMATIC attribute been retained, an obvious definition of AUTOMATIC with initialization would have meant automatic initialization, not SAVE. Specifying the AUTOMATIC attribute without initialization would simply confirm what we already say now. Explicitly specifying AUTOMATIC and SAVE for a particular variable should be prohibited. Explicitly specified AUTOMATIC would override default SAVE. AUTOMATIC would naturally be prohibited for storage-associated variables.

Once AUTOMATIC is defined that way, all that is necessary to provide default values for absent optional arguments is to define an absent OPTIONAL argument that has initialization to be a local automatic variable.

The PRESENT intrinsic should still be available to inquire whether there was an associated actual argument. Even if there's a value for a local variable acting in lieu of the absent dummy argument, it's still useful to know whether the actual argument was present.

@Youjunhu
Copy link

"Same syntax as Python keyword args, so it would be intuitive to Python developers learning Fortran;"

"keyword argument" is only relevant when you call a function.
The definition of a function does not care which argument will be called with the arg=value style.
The correct word should be "default argument".

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

ivan-pi commented Aug 26, 2022

C++17 has introduced a class template std::optional that can be used to pass or return optional values and obeys value semantics.

An example of passing an optional value to a subroutine looks as follows:

#include <iostream>
#include <optional>

void display(std::optional<int> opt_a) {
    if (opt_a) {
        std::cout << "a is present with value " << *opt_a << '\n';
    } else {
        std::cout << "a is not present" << '\n';
    }
}

int main() {
    
    auto a = std::make_optional<int>(42);
    display(a);
    display({});

    return 0;
}

To supply a default non-null value you could modify the prototype:

void display(std::optional<int> a = {42})

The class template also has an accessor method value_or which can be used to return the contained value if available and another value otherwise, e.g.

int a = opt_a.value_or(42)

This is kind of similar to the the Fortran-lang stdlib function optval. An attempt to define a Fortran operator in similar spirit called .presentOr., that could be used as

integer :: c_
c_ = c .presentOr. 42.   ! present(c) ? c : 42

fails since the argument of an operator interface cannot be optional.

@Sandwich-X
Copy link

variants:

real, intent(in), optional, default(0.0) :: c
real, intent(in), optional(0.0) :: c

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 Fortran 202y Proposals targeting the standard after F2023 under consideration Has been submitted to the committee
Projects
None yet
Development

No branches or pull requests