Skip to content

Commit 62282eb

Browse files
authored
Merge pull request #137 from milancurcic/default_optional_arguments
proposal for setting default values of optional arguments
2 parents 2018d3e + 95af140 commit 62282eb

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
To: J3 J3/XX-XXX
2+
From: Milan Curcic
3+
Subject: Default value for optional arguments
4+
Date: 2020-January-10
5+
6+
Proposal for Fortran Standard: 202y (NOT 202x)
7+
8+
9+
Prior art: https://j3-fortran.org/doc/year/18/18-136r1.txt
10+
11+
12+
1. Problem
13+
14+
Currently, standard Fortran does not allow setting a default value
15+
for optional arguments. Default value of an optional argument is
16+
the value that the dummy argument would take if the corresponding
17+
actual argument is not present. If declaring a dummy argument as
18+
optional, the user must:
19+
20+
* Explicitly test for the presence of the actual argument using
21+
the intrinsic function present();
22+
* Use a separate variable inside the procedure to assign the value
23+
because the optional dummy argument that is not present must not
24+
be referenced in expressions other than as actual argument to
25+
the intrinsic function present().
26+
27+
This example function illustrates the problem:
28+
29+
real function quadratic(x, a, b, c)
30+
! returns a + b * x + c * x**2 if c is present
31+
! and a + b * x otherwise
32+
real, intent(in) :: x, a, b
33+
real, intent(in), optional :: c
34+
real :: c_tmp ! use another var. to reference the missing arg
35+
c_tmp = 0 ! default value if c is not present
36+
if (present(c)) c_tmp = c
37+
quadratic = a + b * x + c_tmp * x**2
38+
end function quadratic
39+
40+
For any dummy argument with the optional attribute, the programmer
41+
must use the intrinsic function present() to check for the presence
42+
of the argument. Furthermore, if the optional dummy argument is
43+
meant to be used in multiple places in the procedure, the programmer
44+
is likely to use the pattern from the example above, where a
45+
"temporary" variable is declared and used in place of the dummy
46+
argument, which disconnects the implementation from the user
47+
interface. Furthermore, this requires at least 3 lines of code
48+
(declaration of c_tmp, initialization of c_tmp, and testing for the
49+
presence of c) only to handle the scenario of a missing optional
50+
argument.
51+
52+
This proposal seeks to address the issue that explicitly checking
53+
for presence of the optional dummy argument and using a helper
54+
variable is cumbersome and error-prone. The primary benefit of this
55+
feature is the reduction in source code needed to handle optional
56+
arguments. This benefit is even greater in scenarios where the
57+
optional argument is used in many places in the procedure, and a
58+
helper variable is used for its value instead. Reduction in needed
59+
source code would result in more readable and more correct programs.
60+
The secondary benefit of this is programmer happiness, as working
61+
with optional arguments would require less typing.
62+
63+
2. Proposed solution
64+
65+
As suggested by Van Snyder in 18-136r1, the problem could be solved
66+
by allowing an optional argument to be initialized using a constant
67+
expression. The optional argument would then only be initialized if
68+
the corresponding actual argument is not provided by the caller.
69+
Example:
70+
71+
real function quadratic(x, a, b, c)
72+
! returns a + b * x + c * x**2 if c is present
73+
! and a + b * x otherwise
74+
real, intent(in) :: x, a, b
75+
real, intent(in), optional :: c = 0
76+
quadratic = a + b * x + c * x**2
77+
end function quadratic
78+
79+
In this snippet, we use the assignment operator (=) to specify the
80+
default value of the optional dummy argument.
81+
82+
Like initializer, the optional argument can be assigned any constant
83+
expression, as defined in Section 10.1.12 of 18-007r1.
84+
85+
While there may be concerns that the same syntax is used to
86+
implicitly set the save attribute for variables in procedures, there
87+
is no conflict because the language prohibits dummy arguments
88+
from having an initializer, or the save attribute. The change to the
89+
standard to allow this feature would thus be to allow an optional
90+
dummy argument to have an initializer, which would be triggered only
91+
when corresponding actual argument is not passed by the caller.
92+
93+
This improvement has already been suggested by Van Snyder in
94+
18-136r1, has received votes in the user survey for 202X (see
95+
https://isotc.iso.org/livelink/livelink?func=ll&objId=19530634&objAction=Open&viewType=1),
96+
and appeared on Data subgroup's wishlist at meeting 215 (see
97+
https://j3-fortran.org/doc/year/18/18-122r1.txt).
98+
99+
3. Backward compatibility
100+
101+
This addition to the language would not break any existing standard
102+
conforming Fortran program, and thus preserves Fortran's backward
103+
compatibility.
104+
105+
4. Further discussion
106+
107+
Online discussion that led to this proposal can be found at
108+
https://github.com/j3-fortran/fortran_proposals/issue/22.

0 commit comments

Comments
 (0)