Skip to content
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

optval example #95

Open
ivan-pi opened this issue Aug 26, 2022 · 0 comments
Open

optval example #95

ivan-pi opened this issue Aug 26, 2022 · 0 comments

Comments

@ivan-pi
Copy link

ivan-pi commented Aug 26, 2022

The Fortran-lang stdlib defines a function optval that can be used to define provide a fallback value for an optional argument.

The function is currently implemented with the help of the fypp preprocessor, by looping through all the desired types and kinds:

  #:for k1, t1 in KINDS_TYPES
    pure elemental function optval_${t1[0]}$${k1}$(x, default) result(y)
    ${t1}$, intent(in), optional :: x
    ${t1}$, intent(in) :: default
    ${t1}$ :: y

    if (present(x)) then
       y = x
    else
       y = default
    end if
  end function optval_${t1[0]}$${k1}$
  #:endfor

Without generics, a Fortran programmer could also resort to using a preprocessor directly, such as with the following fypp macro:

#:def optval(lhs,opt,default)
  if (present(${opt}$)) then
    ${lhs}$ = ${opt}$
  else
    ${lhs}$ = ${default}$
  end if
#:enddef

This macro however cannot be used in expressions. With Fortran 202X the new ternary if operator will make this possible using the following fypp macro:

#:def optval(opt,default)
present(${opt}$)) ? ${opt}$ : ${default}$
#:enddef

or its cpp/fpp equivalent:

#define optval(opt,value) present(opt) ? (opt) : (value)

Using the Fortran 2018 enhanced C interoperability features, it is possible to interoperate optional arguments with C, where a null pointer means the argument is not present. A Fortran procedure interface could be provided behind the scenes by a procedure in C++ with an extern "C" interface. In C++ a function template is an elegant and type-sage solution for this usage case:

template<typename T>
inline T optval(const T* opt, T value) {
    T r = value;
    if (opt) r = *opt;
    return r;
}

What would the Fortran solution with the generics look like? Would this be a good example to motivate the generics proposals?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant