# User defined functions in constant expressions

**URL:** <https://fortran-lang.discourse.group/t/user-defined-functions-in-constant-expressions/1509>\
**Category:** Uncategorized\
**Created:** [July 4, 2021, 5:03am UTC](https://fortran-lang.discourse.group/t/user-defined-functions-in-constant-expressions/1509 "2021-07-04T05:03:50Z")\
**Posts on this page:** 1\
**Showing post:** 2

<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:** [July 4, 2021, 3:44pm UTC](https://fortran-lang.discourse.group/t/user-defined-functions-in-constant-expressions/1509/2 "2021-07-04T15:44:16Z")

</div>

> [@mfurquan](#):
>
> Currently, Fortran standard only allows intrinsic functions in a constant expression. In past, have used unwieldy, may be creative, combinations of intrinsics and constructors to initialize parameters. Even then, the scope remains limited, and the code quickly becomes unintelligible. Some languages, like C++ and nim, allow functions with suitable restrictions to be used in constant expressions. Is this my fetish with compile time evaluations that I desire such feature in Fortran, or others too see a requirement. As far as resulting savings at runtime are concerned: (a) usually they are not going to be huge and (b) perhaps compilers are smart enough to see through them without requiring explicit declaration.
> 
> Looking for feedback before adding feature request.
> 
> PS- If you are desirous of seeing the kind of gymanstics I do with constant expressions using instrinsics see (especially the evaluation of derivatives of Lagrange polynomials):

@mfurquan ,

I strongly encourage you to develop your ideas, collaborate with the Fortran Community as you deem appropriate, research options/solutions, and develop proposal(s) toward this. You may know of GitHub Fortran proposals site, you may want to consider at site for this:

> **[GitHub - j3-fortran/fortran\_proposals: Proposals for the Fortran Standard...](https://github.com/j3-fortran/fortran_proposals)**
>
> Proposals for the Fortran Standard Committee. Contribute to j3-fortran/fortran\_proposals development by creating an account on GitHub.

“ **Constexpr as much as possible** ” or in other words, utilize as much compile-time computing as viable is a mantra that’s increasingly becoming important in many modern codes based on C++17 (and later revisions) toward scientific and technical computing in industry, especially in process simulations and modeling.

Improved `constexpr` in C++17 is particularly valuable when one needs to construct large named constants arrays for use in simulations based on other constants (e.g., coefficients in engineering correlations, results from prior simulation runs, results from first-principles models to be applied in reduced-order models, etc.). These are all use cases that are rather similar to the one you show well with the derivatives of Lagrange polynomials.

Sometime ago a team I was working with had to reuse certain case-based logic to construct some data in engineering calculations and they wanted to set it all up just as the libraries were loaded (c.f. Windows DLLs). It was a real pain in Fortran but a breeze with C++17 (supported well by Microsoft C++ processor). I even put together a MWE, ostensibly silly, for what they were trying to do having removed all their business logic of course:

```C++
// Example # : MWE-9.F202Y.003
// Author : FortranFan
// Reference : CONSTEXPR precedures
//
// Description:
// An example in C++17 of constexpr functions that help with
// case-based logic to generate constant arrays at compile-time

#include <array>
#include <iostream>
using namespace std;

// Some base data
constexpr int N = 3;
constexpr std::array<int, N> vals = { 1, 2, 3 };
constexpr std::array<double, N> base_data = { 1.0, -2.0, 3.0 };

// Calculation from base data
constexpr int M = 5;
constexpr std::array<int, M> idx = { vals[2], vals[0], vals[1], vals[0], vals[1] };
// Some user function 1 
constexpr double user_func1(int n) {
   switch ( idx[n-1] )
   {
       case vals[0] : return base_data[0] + 2.0; break;
       case vals[1] : return base_data[1] - base_data[2]; break;
       case vals[2] : return 0.0; break;
       default : return -1.0; break;
   }
}
// Load data at compile-time using user function 2
constexpr std::array<double, M> user_func2{ user_func1(1), user_func1(2), user_func1(3),
   user_func1(4), user_func1(5) };

int main() {
   for (int i = 0; i < M; i++) {
      std::cout << "user_func2[" << i << "] = " << user_func2[i] << "\n";
   }
   return 0;
}

```

> C:\temp\>cl /EHsc ce.cpp  
> Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29112 for x64  
> Copyright (C) Microsoft Corporation. All rights reserved.
> 
> ce.cpp  
> Microsoft (R) Incremental Linker Version 14.27.29112.0  
> Copyright (C) Microsoft Corporation. All rights reserved.
> 
> /out:ce.exe  
> ce.obj
> 
> C:\temp\>ce.exe  
> user\_func2[0] = 0  
> user\_func2[1] = 3  
> user\_func2[2] = -5  
> user\_func2[3] = 3  
> user\_func2[4] = -5
> 
> C:\temp\>

The ability to have nonintrinsic i.e., user-defined functions that are of, say, **CONSTEXPR** `prefix-spec` in Fortran will be entirely consistent, in my opinion, with the evolution path of Fortran with `PURE/ELEMENTAL` procedures in Fortran 95 to [**SIMPLE**](https://j3-fortran.org/doc/year/19/19-201r1.txt) procedures in Fortran 202X. Most of the semantics are already there in Fortran, I personally think it merely needs some adjustments to the language standard (tightening of requirements in some places, some loosening elsewhere).

So my suggestion to the Fortran committee and the Community will be to consider a new procedure `prefix-spec` **CONSTEXPR** that not only requires the procedure to be `SIMPLE` (the above-mentioned new Fortran 202X feature) but that each instruction in such a procedure either be `constant expression` or involve a **CONSTEXPR** procedure. Of course, the details are yet to be fully fleshed out.

The introduction of such a **CONSTEXPR** procedure in a future Fortran standard, say 202Y, will greatly enhance compile-time computing facilities in Fortran and I have no doubt that will be of great benefit in scientific and technical computing.

Kudos to you for bringing this up here.

---

_[View the full topic](https://fortran-lang.discourse.group/t/user-defined-functions-in-constant-expressions/1509)._
