# Optional argument style

**URL:** <https://fortran-lang.discourse.group/t/optional-argument-style/8607>\
**Category:** Uncategorized\
**Created:** [September 16, 2024, 8:22pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607 "2024-09-16T20:22:16Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![kimala](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/kimala/32/2707_2.png) [@kimala](https://fortran-lang.discourse.group/u/kimala)\
**Post date:** [September 16, 2024, 8:22pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/1 "2024-09-16T20:22:16Z")

</div>

Hi everyone, I have a quick question: How do you use optional arguments?

I often have the following pattern, I have an optional argument, that if not present is taken as some default value. But how do you usually implement this mechanism? I give you the two options below

```fortran
subroutine some_sub(arg1, arg2)
   integer :: arg1
   integer, optional :: arg2
   integer :: arg_int
      
   !> Option 1
   arg_int = 1
   if (present(arg2)) arg_int = arg2 ! here potentially move_alloc for big arrays

   !> Option 2 
   if (present(arg2)) then
      arg_int = arg2 ! here potentially move_alloc for big arrays
   else
      arg_int = 1
   end if
   ! Rest of the code
   ! [...]
end subroutine

```

Clearly, this example has only scalars involved, so I doubt the two options have differences. However, if you have big arrays the two might differ, because option one would fill the array the first just to re-fill it.

What’s your best-practice/experience?

Cheers, Francesco

---

<div class="post-metadata">

**Author:** ![egio](https://avatars.discourse-cdn.com/v4/letter/e/dbc845/32.png) [@egio](https://fortran-lang.discourse.group/u/egio)\
**Post date:** [September 16, 2024, 8:46pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/2 "2024-09-16T20:46:13Z")

</div>

I prefer to write a routine like:

```fortran
subroutine some_sub(arg1, arg2, arg3)
   integer :: arg1
   integer, optional :: arg2, arg3
   integer :: arg2_int, arg3_int
      
   arg2_int = default_int(1, arg2)
   arg3_int = default_int(10, arg3) 
  ...
end subroutine
integer function default_int(val, opt) result (r) 
  integer :: val
  integer, optional :: opt
  if (present (opt)) then 
      r = opt
  else
      r = val
  endif
end function 

```

For large arrays you can use pointers, so you don’t copy anything

---

<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:** [September 16, 2024, 9:06pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/3 "2024-09-16T21:06:02Z")

</div>

This is such a common need that stdlib has an [optval](https://stdlib.fortran-lang.org/page/specs/stdlib_optval.html) function.

> ## `optval` - fallback value for optional arguments
> 
> ### Status
> 
> Experimental
> 
> ### Description
> 
> Returns `x` if it is present, otherwise `default`.
> 
> This function is intended to be called in a procedure with one or more `optional` arguments, in order to conveniently fall back to a default value if an `optional` argument is not present.
> 
> ### Syntax
> 
> `result =` [optval](https://stdlib.fortran-lang.org/interface/optval.html) `(x, default)`
> 
> ### Arguments
> 
> `x`: Shall be of type `integer`, `real`, `complex`, or `logical`, or a scalar of type `character`.
> 
> `default`: Shall have the same type, kind, and rank as `x`.
> 
> ### Return value
> 
> If `x` is present, the result is `x`, otherwise the result is `default`.

---

<div class="post-metadata">

**Author:** ![shahmoradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/shahmoradi/32/3151_2.png) [@shahmoradi](https://fortran-lang.discourse.group/u/shahmoradi)\
**Post date:** [September 17, 2024, 12:48am UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/4 "2024-09-17T00:48:59Z")

</div>

I remember, about ten years ago, I used to see slightly better performance in benchmarks for a large petroleum industry code with “Option 1” in your sample code (using intel `ifort`). I do not trust that observation today since compilers have dramatically improved, and I do not remember the exact circumstances around those options. Instead, I frequently choose “option 2” in your code because it better indicates the purpose.

If performance is irrelevant to the code section, I try the flexible route others have suggested (through an auxiliary function). But keep in mind that the use of auxiliary functions to handle default values for optional arguments can be [orders of magnitude more expensive](https://www.cdslab.org/paramonte/fortran/2/interfacepm__option_1_1getOption.html#moralb-getOption_vs_direct) than a simple if block. The best approach to handling optional arguments is the latest “conditional expression” syntax in Fortran 2023.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [September 17, 2024, 8:24am UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/5 "2024-09-17T08:24:43Z")

</div>

With the new F2023 conditional expressions, it can be:

```fortran
arg_int = ( present(arg2) ? arg2 : 1 )

```

---

<div class="post-metadata">

**Author:** ![egio](https://avatars.discourse-cdn.com/v4/letter/e/dbc845/32.png) [@egio](https://fortran-lang.discourse.group/u/egio)\
**Post date:** [September 17, 2024, 8:44am UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/6 "2024-09-17T08:44:23Z")

</div>

I hope to see it supported by compilers not too far in the future.

---

<div class="post-metadata">

**Author:** ![kimala](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/kimala/32/2707_2.png) [@kimala](https://fortran-lang.discourse.group/u/kimala)\
**Post date:** [September 17, 2024, 9:00am UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/7 "2024-09-17T09:00:15Z")

</div>

Why would the “conditional expression” be the best option for such a case?

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [September 17, 2024, 9:51am UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/8 "2024-09-17T09:51:17Z")

</div>

It’s simple, compact, and relatively clear.

Although I would have prefered a more fortranic syntax rather than just copying the C syntax… e.g.  
`arg_int = if (present(arg2)) then arg2 else 1`

---

<div class="post-metadata">

**Author:** ![kimala](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/kimala/32/2707_2.png) [@kimala](https://fortran-lang.discourse.group/u/kimala)\
**Post date:** [September 17, 2024, 10:12am UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/9 "2024-09-17T10:12:24Z")

</div>

I was wondering if there were performance arguments behind the “best approach” statement. To be fair, the fact that it is “clear” is arguable, I’m pretty sure I will have to write it on a sticky note on my monitor to remember how to use it, I like my programming languages to be really similar to my natural languages.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [September 17, 2024, 10:38am UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/10 "2024-09-17T10:38:30Z")

</div>

You can define macros to have a more natural syntax 😉

```auto
#define IF_
#define THEN_ ?
#define ELSE_ :

arg_int = IF_ present(arg2) THEN_ arg2 ELSE_ 1

```

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [September 17, 2024, 12:13pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/11 "2024-09-17T12:13:45Z")

</div>

Almost, but the parenthesis are actually required. I.e.

```auto
#define IF_ (
#define THEN_ ?
#define ELSE_ :

arg_int = IF_ present(arg2) THEN_ arg2 ELSE_ 1 )

```

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [September 17, 2024, 12:29pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/12 "2024-09-17T12:29:03Z")

</div>

For completeness, let’s close it properly 🙂

```auto
#define IF_ (
#define THEN_ ?
#define ELSE_ :
#define ENDIF_ )

arg_int = IF_ present(arg2) THEN_ arg2 ELSE_ 1 ENDIF_

```

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [September 17, 2024, 1:05pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/13 "2024-09-17T13:05:25Z")

</div>

The conditional expression short-circuits. You might assume something like this already exists in statements such as

```fortran
value=merge(arg2,100.0,present(arg2))

```

and as long as you do not use an expression with arg2 it might work as expected, but it is not a good idea. It is clearer if arg2 is used in an expression:

```fortran
value=merge(abs(arg2)*2.0,100.0,present(arg2))

```

without short-circuiting the expression is allowed to be evaluated regardless of whether arg2 is present or not, so it would be using an undefined variable when arg2 is not present.

I thought making present() take additional arguments or make a short-circuiting merge() would have been nice, like

```fortran
value=present(arg2,100.0) ! return a non-logical value as long as arg2 and the value are the same type

```

or allowing defaults to be specified when declaring something optional. If C did not exist I suspect that conditional expression syntax would not have been even thought of; and even a good number of C programmers seem to not like it; but it finally gives Fortran a compact expression that short-circuits and can be passed as an argument.

PS,

In a little language of my own all the logical expressions are actually functions (if,eq,le,…)  
that short-circuit so you could do something like

```fortran
value=if(present(arg2),arg2,100.0) 

```

where it is IF(logical\_expression,eval\_and\_return\_if\_true,eval\_and\_return\_if\_false)

it is like algebraic versus Polish notation, some people like it a lot and others do not. Essentially everything is a function, and you name blocks of commands and then execute  
them like functions as well with the execute() function. (like “execute(if(eq(a,b),blocka,blockb)” means if A==B execute commands in BLOCKA else execute BLOCKB. That is only relevant in that instead of the C-like expression I thought something like making IF into a Fortran function would have been more “Fortranik”…

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [September 17, 2024, 1:51pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/14 "2024-09-17T13:51:09Z")

</div>

Regarding the original question, I generally eschew using semi-colons  
but if I have a lot of optional arguments I either make a contained  
procedure like the getopts function described by later replies or use either of the syntaxes  
described but on one line:

```fortran
arg2_ = 1;if (present(arg2)) arg2_ = arg2
arg3_ = 1;if (present(arg3)) arg3_ = arg3
arg4_ = 1;if (present(arg4)) arg4_ = arg4

if (present(arg2)) then; arg2_ = arg2 ; else; arg2_ = 1; endif
if (present(arg3)) then; arg3_ = arg3 ; else; arg3_ = 1; endif
if (present(arg4)) then; arg4_ = arg4 ; else; arg4_ = 1; endif
if (present(arg5)) then; arg5_ = arg5 ; else; arg5_ = 1; endif

```

it just gets too lengthy and repetitive otherwise.

And I usually name the local variable the same as the actual argument with an underscore following it. Just personal style though. No real functionality to doing that.

---

<div class="post-metadata">

**Author:** ![wspector](https://avatars.discourse-cdn.com/v4/letter/w/47e85d/32.png) [@wspector](https://fortran-lang.discourse.group/u/wspector)\
**Post date:** [September 17, 2024, 6:02pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/15 "2024-09-17T18:02:03Z")

</div>

> [@urbanjost](#):
>
> The conditional expression short-circuits. You might assume something like this already exists in statements such as
> 
> ```auto
> value=merge(arg2,100.0,present(arg2))
> 
> ```
> 
> and as long as you do not use an expression with arg2 it might work as expected, but it is not a good idea. It is clearer if arg2 is used in an expression:
> 
> ```auto
> value=merge(abs(arg2)*2.0,100.0,present(arg2))
> 
> ```
> 
> without short-circuiting the expression is allowed to be evaluated regardless of whether arg2 is present or not, so it would be using an undefined variable when arg2 is not present.

Just to be clear: it is never a good idea to use the `merge` intrinsic for this - as all three expressions are always evaluated. This will cause an abend when the optional argument is not present.

The C-like `?:` operator is different in that the conditional portion is evaluated first, then only one or the other expression is evaluated.

---

<div class="post-metadata">

**Author:** ![johnalx](https://avatars.discourse-cdn.com/v4/letter/j/b38774/32.png) [@johnalx](https://fortran-lang.discourse.group/u/johnalx)\
**Post date:** [September 18, 2024, 12:42pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/16 "2024-09-18T12:42:30Z")

</div>

This is a good use case for Fortran to support generics. So you won’t have to write a `deault_int` and a `default_real` and a `default_logical` etc etc

---

<div class="post-metadata">

**Author:** ![egio](https://avatars.discourse-cdn.com/v4/letter/e/dbc845/32.png) [@egio](https://fortran-lang.discourse.group/u/egio)\
**Post date:** [September 18, 2024, 1:07pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/17 "2024-09-18T13:07:37Z")

</div>

Yes, of course, I didn’t want to complicate things in the post for the actual standard. Waiting for the future generics… 🙂

---

<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:** [September 18, 2024, 1:10pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/18 "2024-09-18T13:10:53Z")

</div>

You don’t need to wait. This case is covered by existing generic interfaces. For instance in [stdlib](https://github.com/fortran-lang/stdlib/blob/master/src/stdlib_optval.fypp):

```fortran
  interface optval
    !! Fallback value for optional arguments
    !! ([Specification](../page/specs/stdlib_optval.html#description))
    #:for k1, t1 in KINDS_TYPES
      module procedure optval_${t1[0]}$${k1}$
    #:endfor
    module procedure optval_character
  end interface optval

```

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [September 18, 2024, 1:11pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/19 "2024-09-18T13:11:53Z")

</div>

In my case I’ve been using good old CPP macro…

```fortran
#ifdef __GFORTRAN__
#define _setopt_(x,val) x = val; if (present(x/**/_)) x = x/**/_
#else
#define _setopt_(x,val) x = val; if (present(x##_)) x = x##_
#endif

```

(My naming convention is opposite to that of Urbanjost, i.e. the dummy argument is with underscore, while the corresponding local variable is no underscore, because I want to use the latter on the same footing as other local variables (w/o remembering which is optional or not).

---

<div class="post-metadata">

**Author:** ![egio](https://avatars.discourse-cdn.com/v4/letter/e/dbc845/32.png) [@egio](https://fortran-lang.discourse.group/u/egio)\
**Post date:** [September 18, 2024, 1:22pm UTC](https://fortran-lang.discourse.group/t/optional-argument-style/8607/20 "2024-09-18T13:22:00Z")

</div>

You are right, I’m saying that I’m waiting the new Fortran generics that will be available in 202y.

I wrote some default\_real, default\_int, etc. some time ago before those appeared in the stdlib (or at least, before I realized they were present in stdlib).

I really appreciate the work done in stdlib, and I always suggest colleagues to have a look at stdlib and fpm.  
🙂
