# Default value for optional argument

**URL:** <https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490>\
**Category:** Uncategorized\
**Created:** [December 17, 2020, 1:02am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490 "2020-12-17T01:02:08Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [December 17, 2020, 1:02am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/1 "2020-12-17T01:02:08Z")

</div>

To provide a default value for an optional argument, Jannis Teunissen has [proposed](https://teunissen.net/wiki/doku.php?id=blog:fortran_improvements) the syntax

```
subroutine test(n)
integer, intent(in), optional :: n = 10 ! Default is 10

```

> Note that this syntax is also used to initialize variables with the ‘save’ attribute, but since that attribute does not apply to optional arguments it should be fine.

I think present(n) could be defined as .true. in this case, regardless of whether test was called with argument n. Currently my code is full of

```
subroutine test(n)
integer, intent(in), optional :: n
integer :: n_
n_ = default(10,n)

```

where default is a function I have defined with an optional 2nd argument. Often I forget to use n instead of n\_ later in the subroutine, causing a run-time error when the subroutine is called with argument n. The proposed syntax would be more concise and less error-prone.

---

<div class="post-metadata">

**Author:** ![rcs](https://avatars.discourse-cdn.com/v4/letter/r/d2c977/32.png) [@rcs](https://fortran-lang.discourse.group/u/rcs)\
**Post date:** [December 17, 2020, 1:16am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/2 "2020-12-17T01:16:37Z")

</div>

what happens then to this:

```auto
subroutine t_1(n)
  integer, intent(in), optional :: n = 10
  call t_2(n)

subroutine t_2(n)
  integer, intent(in), optional :: n
  if(present(n)) then
    write(*,*) "i am here"
  else
    write(*,*) "i am not here"
  endif

```

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [December 17, 2020, 1:22am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/3 "2020-12-17T01:22:06Z")

</div>

If, as I suggested, present(n) is .true. in subroutine t\_1, regardless of how the subroutine was called, then present(n) would also be .true. in suboutine t\_2, so “I am here” would be printed.

---

<div class="post-metadata">

**Author:** ![rcs](https://avatars.discourse-cdn.com/v4/letter/r/d2c977/32.png) [@rcs](https://fortran-lang.discourse.group/u/rcs)\
**Post date:** [December 17, 2020, 3:20am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/4 "2020-12-17T03:20:10Z")

</div>

precisely, and, imho, that would make the suggested syntax as bug prone as the current one. Even worse, the current implementation yields a segfault, whereas the suggested would yield a hard to track result deviation.

btw a maybe simpler solution to your problem might be:

```auto
subroutine test(n)
integer, intent(in), optional :: n
integer :: n_=10
if(present(n)) n_=n

```

same number of lines, but no necessity for function inlining or across file optimization if `default` is defined somewhere else.

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [December 17, 2020, 3:52am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/5 "2020-12-17T03:52:26Z")

</div>

A feature of Fortran is that In your code, n\_ has the SAVE attribute, which I do not want.

---

<div class="post-metadata">

**Author:** ![rcs](https://avatars.discourse-cdn.com/v4/letter/r/d2c977/32.png) [@rcs](https://fortran-lang.discourse.group/u/rcs)\
**Post date:** [December 17, 2020, 4:08am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/6 "2020-12-17T04:08:02Z")

</div>

sure you are right. However I still wouldn’t go the `default` way since

```auto
integer :: n_
n_=10;if(present(n)) n_=n

```

would do the trick … might be a matter of taste and whether you are chasing milliseconds.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [December 17, 2020, 8:15am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/7 "2020-12-17T08:15:49Z")

</div>

See the related discussion and proposal on the [j3-fortran](https://github.com/j3-fortran/fortran_proposals) GitHub page:

- [Allow setting default value for optional dummy argument #22](https://github.com/j3-fortran/fortran_proposals/issues/22)
- [Default optional arguments (proposal)](https://github.com/j3-fortran/fortran_proposals/blob/master/proposals/default_optional_arguments/proposal.txt)

I believe this is already under consideration for Fortran 202y.

---

<div class="post-metadata">

**Author:** ![jeremie.vandenplas](https://avatars.discourse-cdn.com/v4/letter/j/76d3ee/32.png) [@jeremie.vandenplas](https://fortran-lang.discourse.group/u/jeremie.vandenplas)\
**Post date:** [December 18, 2020, 8:50am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/8 "2020-12-18T08:50:31Z")

</div>

In addition to @ivanpribec 's comment, I would like to add the following (ongoing) proposal 's [revision](https://github.com/j3-fortran/fortran_proposals/pull/175), as welll as the function [`optval`](https://stdlib.fortran-lang.org/page/specs/stdlib_optval.html) implemented in `stdlib`. Here is an example on how it could be used:

```auto
program demo_optval
    use stdlib_optval, only: optval
    implicit none
    print *, root(64.0)
! 8.0
    print *, root(64.0, 3)
! 4.0
contains
    real function root(x, n)
        real, intent(in) :: x
        integer, intent(in), optional :: n
        root = x**(1.0/optval(n, 2))
    end function root
end program demo_optval

```

---

<div class="post-metadata">

**Author:** ![rcs](https://avatars.discourse-cdn.com/v4/letter/r/d2c977/32.png) [@rcs](https://fortran-lang.discourse.group/u/rcs)\
**Post date:** [December 18, 2020, 10:23am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/9 "2020-12-18T10:23:42Z")

</div>

The optval function is certainly not hpc compatible, but I presume you know that.

---

<div class="post-metadata">

**Author:** ![jeremie.vandenplas](https://avatars.discourse-cdn.com/v4/letter/j/76d3ee/32.png) [@jeremie.vandenplas](https://fortran-lang.discourse.group/u/jeremie.vandenplas)\
**Post date:** [December 18, 2020, 10:54am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/10 "2020-12-18T10:54:07Z")

</div>

My aim was mainly to complete the info provided by Ivan, since it was done around the J3 proposal led by @milancurcic . It also seems that `stdlib` `optval` is similar to @Beliavsky 's `default` function.  
I agree that having something in the standard would be useful. Meanwhile, any ideas how to improve such a function to be, e.g., hpc-compatible?

---

<div class="post-metadata">

**Author:** ![Federchen](https://avatars.discourse-cdn.com/v4/letter/f/ce7236/32.png) [@Federchen](https://fortran-lang.discourse.group/u/Federchen)\
**Post date:** [December 18, 2020, 12:34pm UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/11 "2020-12-18T12:34:05Z")

</div>

I would recommend to NOT use a default value with an optional argument at all; nor to do any calculation with optional arguments: the optional argument must be present to be allocated. Instead:

if (present(n)) then  
this % n = n  
else ! default:  
this % n = 10  
end if

---

<div class="post-metadata">

**Author:** ![nshaffer](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/nshaffer/32/161_2.png) [@nshaffer](https://fortran-lang.discourse.group/u/nshaffer)\
**Post date:** [December 18, 2020, 4:17pm UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/12 "2020-12-18T16:17:38Z")

</div>

Indeed, the initial proposal and implementation of `stdlib_optval` is based on a code snippet @Beliavsky posted to comp.lang.fortran some time ago in a thread very much like this one. It’s a smart use of the fact that the presence/absence of an optional argument propagates down the call stack.

---

<div class="post-metadata">

**Author:** ![nshaffer](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/nshaffer/32/161_2.png) [@nshaffer](https://fortran-lang.discourse.group/u/nshaffer)\
**Post date:** [December 18, 2020, 4:29pm UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/13 "2020-12-18T16:29:26Z")

</div>

What do you mean? I can see not wanting to stick `optval` calls deep in the innards of hot loops, etc. But is it much worse than using `optional` arguments at all in those contexts?

---

<div class="post-metadata">

**Author:** ![jeremie.vandenplas](https://avatars.discourse-cdn.com/v4/letter/j/76d3ee/32.png) [@jeremie.vandenplas](https://fortran-lang.discourse.group/u/jeremie.vandenplas)\
**Post date:** [December 18, 2020, 5:11pm UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/14 "2020-12-18T17:11:04Z")

</div>

> [@nshaffer](#):
>
> Indeed, the initial proposal and implementation of `stdlib_optval` is based on a code snippet @Beliavsky posted to comp.lang.fortran some time ago in a thread very much like this one. It’s a smart use of the fact that the presence/absence of an optional argument propagates down the call stack.

I wasn’t aware of that. Thank you for the information.

---

<div class="post-metadata">

**Author:** ![rcs](https://avatars.discourse-cdn.com/v4/letter/r/d2c977/32.png) [@rcs](https://fortran-lang.discourse.group/u/rcs)\
**Post date:** [December 19, 2020, 2:27am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/15 "2020-12-19T02:27:50Z")

</div>

Take the code block below, but put every code block INTO ITS OWN FILE.

```auto
module mod_1
contains
 function optval(x,y) result(z)
   real(kind=8), intent(in), optional :: x
   real(kind=8), intent(in) :: y
   real(kind=8) :: z
   if(present(x)) then
     z=x
   else
     z=y
   end if
 end function optval
end module mod_1

```

```auto
module mod_2
  use mod_1, only: optval
contains
  subroutine sub1(r2i,t,s)
    real(kind=8), intent(inout) :: r2i(:,:)
    real(kind=8), intent(in) :: t
    real(kind=8), intent(in), optional :: s
    integer :: i,j
    do i=1,size(r2i,2)
      do j=1,size(r2i,1)
        if(r2i(j,i)>t) r2i(j,i)=r2i(j,i)/optval(s,3.0D0)
      end do
    end do
  end subroutine sub1
  subroutine sub2(r2i,t,s)
    real(kind=8), intent(inout) :: r2i(:,:)
    real(kind=8), intent(in) :: t
    real(kind=8), intent(in), optional :: s
    integer :: i,j
    do i=1,size(r2i,2)
      do j=1,size(r2i,1)
        if(present(s)) then
          if(r2i(j,i)>t) r2i(j,i)=r2i(j,i)/s
        else
          if(r2i(j,i)>t) r2i(j,i)=r2i(j,i)/3.0D0
        end if
      end do
    end do
  end subroutine sub2
end module mod_2

```

and

```auto
program test
  use mod_2, only: sub1, sub2
  implicit none
  real(kind=8), allocatable :: x(:,:)
  real(kind=8) :: t1,t2
  integer :: i
  allocate(x(1000000,100))
  do i=1,4
    call random_number(x)
    call cpu_time(t1)
    call sub2(x,0.2D0)
    call cpu_time(t2)
    write(*,"(*(g0:"",""))") "t1: ", i, t2-t1
  end do
  do i=1,4
    call random_number(x)
    call cpu_time(t1)
    call sub1(x,0.2D0)
    call cpu_time(t2)
    write(*,"(*(g0:"",""))") "t2: ", i, t2-t1
  end do
end program test

```

compile with

```auto
#!/bin/bash
fc=ifort
$fc -O3 -c sub1.f90
$fc -O3 -c sub2.f90
$fc -O3 -c main.f90
$fc -O3 -o test main.o sub1.o sub2.o

```

and check what you get.

I got:

```auto
t1: ,1,.9718500000000008E-01
t1: ,2,.9703800000000018E-01
t1: ,3,.9721100000000016E-01
t1: ,4,.9707200000000027E-01
t2: ,1,.4253720000000003
t2: ,2,.4263209999999997
t2: ,3,.4262069999999998
t2: ,4,.4255380000000004

```

This is of course an oversimplified example and there are several fixes to this particular code of which some are trivial, others not.

However, in more complex examples or when functions like `optval` sit in large libraries there is no guarantee that these fixes works.

I understand that the `stdlib optval` functionality is meant to make fortran more handy. But an inexperienced programmer or somebody not familiar with 2500 pages of ifort manual may come to the conclusion that stdlib is anything else than hpc.

---

<div class="post-metadata">

**Author:** ![nshaffer](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/nshaffer/32/161_2.png) [@nshaffer](https://fortran-lang.discourse.group/u/nshaffer)\
**Post date:** [December 19, 2020, 5:52am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/16 "2020-12-19T05:52:19Z")

</div>

I wonder what this is measuring. I don’t have ifort in front of me right now to check, but I’d guess that optval should be getting inlined. Then the only difference would the order of the two if-tests. Or I could be dead wrong.

Note to self: look at the disassembly of sub1 versus sub2 when I get time

In any case, hopefully no one is silly enough to evaluate stdlib’s HPC suitability based on a convenience function. It’s documented as such. And there’s the silver lining that if someone does use it in a place that it gums up control flow, it will show up hot in a profiler. Whereas if you’d made that mistake by hand, it might be harder to find.

---

<div class="post-metadata">

**Author:** ![rcs](https://avatars.discourse-cdn.com/v4/letter/r/d2c977/32.png) [@rcs](https://fortran-lang.discourse.group/u/rcs)\
**Post date:** [December 19, 2020, 6:25am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/17 "2020-12-19T06:25:22Z")

</div>

It might be worth keeping in mind: [And with the modern Fortran dialects, it is even not too hard to make inefficient code](https://www.vortech.nl/en/fortran-is-alive/)

---

<div class="post-metadata">

**Author:** ![rcs](https://avatars.discourse-cdn.com/v4/letter/r/d2c977/32.png) [@rcs](https://fortran-lang.discourse.group/u/rcs)\
**Post date:** [December 19, 2020, 6:34am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/18 "2020-12-19T06:34:24Z")

</div>

> [@nshaffer](#):
>
> inlined

Thats were the problem is. You must switch on across file optimization explicitly. And I found often enough that it doesn’t change anything because doesn’t matter what flags you set in the end the compiler decides what to inline, and when `optval` sit in a large library the chance is rather high that it doesn’t get inlined.

---

<div class="post-metadata">

**Author:** ![nshaffer](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/nshaffer/32/161_2.png) [@nshaffer](https://fortran-lang.discourse.group/u/nshaffer)\
**Post date:** [December 19, 2020, 7:13am UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/19 "2020-12-19T07:13:59Z")

</div>

I don’t really want to digress too much further on this specific test, but the point is taken.

Bringing things back around the original topic: It seems to me like one benefit of having syntax for default values is that the compiler will always be able to see

```auto
integer, intent(in), optional :: n = 10

```

(or whatever syntax) and know the relationship between `n` and `10` explicitly, whereas with user-written approaches like `optval` or explicit `if (present(...))` checks, that special relationship has to be inferred and in practice seems not to come to light until run time.

As for syntax, it seems too similar to initializing (and SAVE’ing) local variables, even though the semantics are totally different. Not sure if these have been proposed already but:

jammed into `optional` attribute  
`integer, intent(in), optional(10) :: n`

as a new attribute  
`integer, intent(in), optional, default(10) :: n`

or F77-style statement, a la `PARAMETER`:

```auto
integer, intent(in), optional :: n
default (n=10)

```

The last two kind of make sense together. If the default value is brief to write, put it as an attribute. If it’s a longer expression, like an array constructor or a derived type constructor, use the statement form.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [December 19, 2020, 2:26pm UTC](https://fortran-lang.discourse.group/t/default-value-for-optional-argument/490/20 "2020-12-19T14:26:54Z")

</div>

> [@rcs](#):
>
> Take the code block below, but put every code block INTO ITS OWN FILE. …

@rcs,

Please note though what you show is not very reflective of situations in a HPC computing domain.

At the very least anyone looking at the code can retry with the following trivial changes and my hunch is no differences will be noticeable:

```Fortran
  subroutine sub1(r2i,t,s)
    real(kind=8), intent(inout) :: r2i(:,:)
    real(kind=8), intent(in) :: t
    real(kind=8), intent(in), optional :: s
    integer :: i,j
    associate ( s_ => optval(s, 3D0) )
        do i=1,size(r2i,2)
          do j=1,size(r2i,1)
              if(r2i(j,i)>t) r2i(j,i)=r2i(j,i)/s_
          end do
        end do
    end associate
  end subroutine sub1
  subroutine sub2(r2i,t,s)
    real(kind=8), intent(inout) :: r2i(:,:)
    real(kind=8), intent(in) :: t
    real(kind=8), intent(in), optional :: s
    integer :: i,j
    real(kind=kind(s)) :: s_
    s_ = 3.0D0 ; if ( present(s) ) s_ = s
    do i=1,size(r2i,2)
      do j=1,size(r2i,1)
        if(r2i(j,i)>t) r2i(j,i)=r2i(j,i)/s_
      end do
    end do
  end subroutine sub2

```

@nshaffer , @ivanpribec, et al.,

Please note if you’re keen on getting something into the language standard itself, far more convincing use cases will be needed. Almost anyone on a Fortran standard committee, particularly those with compiler implementation responsibilities, will likely find it unconvincing to add further semantics and syntax to the base language with the kind of examples that are given. The options already available in the language including with generic interfaces might come across as more than adequate for such cases.
