-
Notifications
You must be signed in to change notification settings - Fork 18
addition of present() #140
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
Conversation
The changes in the PR are fine. Regarding the question in the description, the argument is |
I think it should work in the same way for both |
@sblionel also supported this interpretation of I'd argue for the opposite:
This makes more sense to me. I always thought of There's also a technical argument:
subroutine simulate(a, b)
real, intent(in) :: a
real, intent(in), optional :: b = 1.234
if (present(b)) then
... ! expensive input validation here
end if
...
end subroutine simulate In this example, expensive input validation code would execute only if argument passed by the caller, which is otherwise not needed. In summary, |
From #137:
I mean, let's also include the text to be included in the standard, should this proposal be accepted. Which section of the standard should be edited and how? Should any text be removed? What should be added? Although this may be in the scope of the Committee, the more we can help the easier will a proposal be accepted and implemented. Let's help as much as we can and know. |
I don't think a default value for an But this does bring up the question of It would be my opinion that default values for optional arguments should only be allowed for
would be equivalent to
That simple transformation doesn't make any sense, and in fact causes a run time error for any other intent. I would be in favor of still allowing |
I was in favor of such a behaviour of It seems that most people would be in favor of |
Let's discuss pros and cons of both alternatives in the proposal. This will surely come up during a discussion at the committee, no matter which alternative we choose as the better one.
…On Tue, Jan 14, 2020, at 12:55 AM, Jeremie Vandenplas wrote:
>
> I would be in favor of still allowing `present` to return `.false.` for default values, as has already been explained to have a use case. I personally probably wouldn't use it that way, but it's not unreasonable to want to.
I was in favor of such a behaviour of `present` too, but I tried to
integrate @sblionel <https://github.com/sblionel> 's comment (see #137
<#137>). Such a
behavior (.false. or .true. independently of the initializer) would be
also in agreement with the function `optval`
<https://github.com/fortran-lang/stdlib/blob/f300f4a609ab02620b82ee2c79566361d84505c4/src/stdlib_experimental_optval.f90#L37> implemented in `stdlib`.
It seems that most people would be in favor of `present` returning
.false./.true. indepentely of the initializer. @milancurcic
<https://github.com/milancurcic>: I can modify my PR in that sense, and
add your use case as an example.
@sblionel <https://github.com/sblionel> what would be the issue of such
a behavior (in addition to its implementation in a compiler)?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#140?email_source=notifications&email_token=AAAFAWA4HS3BDT4YWB7FJZTQ5VVYLA5CNFSM4KGJMFM2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEI3U76I#issuecomment-574050297>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAAFAWGRUZMM2BQIM4ZC3GTQ5VVYLANCNFSM4KGJMFMQ>.
|
For integer function open(filename, mode, iostat) result(u)
character(*), intent(in) :: filename
character(*), intent(in), optional :: mode
integer, intent(out), optional :: iostat
character(3) :: mode_
character(:),allocatable :: action_, position_, status_, access_, form_
!some code
!....
if (present(iostat)) then
open(newunit=u, file=filename, &
action = action_, position = position_, status = status_, &
access = access_, form = form_, &
iostat = iostat)
else
open(newunit=u, file=filename, &
action = action_, position = position_, status = status_, &
access = access_, form = form_)
end if
end function which would become: integer function open(filename, mode, iostat) result(u)
character(*), intent(in) :: filename
character(*), intent(in), optional :: mode
integer, intent(out), optional :: iostat = 0
character(3) :: mode_
character(:),allocatable :: action_, position_, status_, access_, form_
!some code
!....
open(newunit=u, file=filename, &
action = action_, position = position_, status = status_, &
access = access_, form = form_, &
iostat = iostat)
end function In this use case, the function For subroutine simulate(a, b)
real, intent(in) :: a
real, intent(inout), optional :: b = 1.234
if (present(b)) then
... ! expensive input validation here
end if
!some computations with b
if (present(b)) then
!some expensive computations that modify b and return the newly computed b
end if
end subroutine simulate While this would probably be a poor design, it would be possible if default values are allowed for |
@certik I will push another version of a description of |
This is very interesting development. At first I wasn't considering subroutine simulate(a, rc)
real, intent(in) :: a
integer, intent(out), optional :: rc = 0 ! assume success
... ! simulation code
if (present(rc)) then
! test for simulation state
if (some_erroneous_condition) then
rc = 173 ! meaningful error code
return
end if
end if
... ! more simulation code
end subroutine simulate The only aspect that the default initializer helps here with is that we don't have to have a separate line at the top: Another technical argument for allowing default value for any |
Thanks everybody for brainstorming this. This is exactly the kind of work that needs to happen between Committee meetings that we can all do very efficiently at GitHub. So that by the time the Committee meets, the proposal is truly ready with all these "details" figured out. |
If there's not a technical reason for disallowing a default value for optional intent(out) arguments then I say it should be allowed. I can't think of a really compelling use case that needs it either, but we shouldn't be trying to anticipate what someone might find useful in this context. And I agree with @milancurcic it will be easier to write the specification if we don't add unnecessary constraints. |
@milancurcic , just for clarity, your suggestion is that a default value for
would be equivalent to
I would actually suggest something a bit different, which would then be coherent when combined for
would be equivalent to
Of course the actual implementation of a compiler would be smarter than having to insert that extra line before every return statement (one would hope). But this makes the following work as well.
would be equivalent to
And it would be exactly the same transformation if no intent is specified. This at least gives the feature a coherent idea that if you have a default value for an optional argument, you no longer need to check if it's present, no matter what it's intent is. But as has been mentioned, you might still want the ability to check if it's present, which my simple transformation would preclude. |
Did I understand you correctly, @everythingfunctional: The optional argument with an initializer will behave as a declared variable, with an initial value equal to the default value (initializer) (so, no need of
|
@jvdp1 , yes, those statements are true as I envisioned it. |
Exactly! While this was implied in the proposal, we didn't state it explicitly and we should: Using default value for an optional argument allows the programmer to safely reference it in expressions regardless of intent and whether the actual argument is present or not. |
Looks like there is agreement on this, so I am going to merge it. |
I missed seeing this earlier. If one was to allow
If you also allowed this for other than This interpretation would also complicate passing the argument to another routine. At present (!), "presentness" is passed on to other routines where the dummy is To me, this is awfully complicated and performance-inhibiting. I foresee a lot of opposition to such a thing. I still favor default values being supplied by the caller, in which case everything falls out without adding a layer of complexity. It is also far easier to explain (and implement.) In my experience, I have not seen default values combined with "did the caller really pass something?" This is not to say that there couldn't be a case for that, but it isn't compelling to me. |
@jvdp1 if you have time, would you mind capturing the rest of the discussion here, such a Steve's comment above, and send a new PR? |
@sblionel Thanks! Indeed, I didn't consider implementation it all, nor do I have experience with it. Your argument makes sense to me. |
I just added an example on how I think
present
may behave when an initializer is mentioned or not.I am just wondering what would happen in such a case:
What will happen with
foo
when it is called without providing an actual argument, sincepresent()
always returns.true.
. Probably it should not be a problem since value is already used.