# Simple Generics

**URL:** <https://fortran-lang.discourse.group/t/simple-generics/5973>\
**Category:** Uncategorized\
**Created:** [June 11, 2023, 5:54pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973 "2023-06-11T17:54:25Z")\
**Posts on this page:** 20\
**Page:** 1

<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:** [June 11, 2023, 5:54pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/1 "2023-06-11T17:54:25Z")

</div>

> [@Can floating point literals be adapted by the compiler to double precision variable?](https://fortran-lang.discourse.group/t/can-floating-point-literals-be-adapted-by-the-compiler-to-double-precision-variable/2034/79):
>
> … I think it would be helpful to make the precision “generic”, here is the proposal for this: [Allow an intent(out) argument to adopt the same kind as an input(in) argument · Issue #128 · j3-fortran/fortran\_proposals · GitHub](https://github.com/j3-fortran/fortran_proposals/issues/128)

Attention @everythingfunctional , in the context of this [**paper**](https://j3-fortran.org/doc/year/23/23-155.txt), can you please provide the proposed Fortran 202Y syntax for the simple case presented by @certik toward authoring a **generic** Fortran function that can take any `KIND` of a floating-type argument and define a function result of the same `KIND`?

Please see this [**link**](https://github.com/j3-fortran/fortran_proposals/issues/128) for reference to such a function and the discussion on it led by @certik.

Thanks,

---

<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:** [June 12, 2023, 7:10am UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/2 "2023-06-12T07:10:13Z")

</div>

The code from the referenced proposal would look like:

```auto
template log10_tmpl(k)
  integer, constant :: k
  private
  public :: log10
  interface log10
    procedure log10_local
  end interface
contains
  simple elemental function log10_local(x) result(r)
    real(k), intent(in) :: x
    real(k) :: r
    r = log(x) / log(10._k)
  end function
end template

```

You’d then call it like

```auto
use kinds_m, only: wp

instantiate log10_tmpl(wp)
real(wp) :: x, y
x = 42._wp
y = log10(x)

```

---

<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:** [June 12, 2023, 1:42pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/3 "2023-06-12T13:42:56Z")

</div>

> [@everythingfunctional](#):
>
> The code from the referenced proposal would look like:
> 
> ```auto
> template log10_tmpl(k)
> integer, constant :: k
> ..
> interface log10
> procedure log10_local
> end interface
> 
> ```

Thanks much @everythingfunctional .

Can you please explain what led to the need for an interface construct with the template construct even in such a simple case? Because what you show is likely to be seen as **more verbose than necessary** , it is likely to end up as being unwieldy for many Fortran coders.

What are the aspects the Generics subgroup think that would prevent a simple `TEMPLATE` that defines the `KART` i.e, kind, attribute, rank, and type characteristics of an entity and for the language to include templated module procedures which can then work off of the template entity, a la procedure interfaces now in the language? For example,

```auto
module m
   ..
   template T(k)
       use, intrinsic :: iso_fortran_env, only : real_kinds
       integer, kind :: k := real_kinds <-- some such syntax to indicate 'k' belongs to real kinds set
   end template
   ..
contains
    ..
    simple elemental function log10<T>(x) result(r) !<-- some compact syntax to indicate templated module procedure
        real(k), intent(in) :: x
        real(k) :: r
        r = log(x) / log(10._k)
     end function
    ..
end module

! caller
   use m, only : log10 !<-- this should suffice to `USE` log10 on the caller side
   use kinds_m, only : WP
   ..
   real(WP) :: x, y
   ..
   y = log10<WP>( x ) !<-- simple **in situ** compile-time instantiation

```

The points include:

1. building on current semantics to auto export interfaces whenever viable i.e., take advantage of what is built into the language with module procedures,
2. bringing in a new `integer, constant` aspect for `KIND` appears not needed. Why not reuse the `integer, kind` semantics with parameterirzed derived types when dealing with entities that indeed correspond to `KIND`s?
3. you will find coders will feedback that **in situ** compile-time instantiation of templated subprograms is a must e.g., `y = log10<WP>( x )` above.
4. if Fortran seeks **strong concepts** and I agree it’s right for Fortran to have this, then let it be **strong** : whether it’s `integer, constant :: k` or `integer, kind :: k`, the context here is a `KIND` for an intrinsic `REAL` type only and nothing else. Then there should be a way to strongly inform the processor the kind constant belongs to the `REAL_KINDS` set and nothing else. That way the template parameter of said template is only used to template the `KIND` of REAL types connected with the template and nothing else.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [June 12, 2023, 5:47pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/4 "2023-06-12T17:47:54Z")

</div>

Beautiful, thanks @everythingfunctional. I made an issue for LFortran to support this example:

[Generics: add example of any kind · Issue #1804 · lfortran/lfortran · GitHub](https://github.com/lfortran/lfortran/issues/1804)

@FortranFan I can imagine later adding some simpler syntax for this common case, such as the one from the J3 Fortran Proposals repository. The main issue for me is to ensure the feature is in. As I commented elsewhere, I strongly recommend the committee to later come back and iterate/simplify the surface level syntax where appropriate.

@RonShepard Yes. Do you have a better name than pedantic/strict? Other ideas I have are “safe”, “subset”, “simple”, but I don’t quite like any of them.

---

<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:** [June 12, 2023, 6:43pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/5 "2023-06-12T18:43:53Z")

</div>

> [@certik](#):
>
> … @FortranFan I can imagine later adding some simpler syntax for this common case, such as the one from the J3 Fortran Proposals repository. The main issue for me is to ensure the feature is in. …

@everythingfunctional , @certik:

Apologies: please note I miswrote above implying simpler syntax. Actually what I really meant was **simpler semantics**. Consider this simple case brought up by @certik: it is truly debatable whether the `TEMPLATE` construct, as per Fortran 202Y proposal, needs to define a “template” `INTERFACE` therein only to encapsulate what is a templated procedure in `log10_local`, as in the illustration by @everythingfunctional above.

Something seriously does **not** appear right here.

This requires serious thought and for various Fortran practitioners who are deeply interested in Generics such as @plevold and @shahmoradi et al. to think through this deeply and to give feedback which the Generics subgroup must review. If the underlying aspects such as these are not designed well, there will be **no** later simplification or enhancement viable, the feature will be doomed and a lot of practitioners will not use it. Fortran needs to get Generics right.

---

<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:** [June 12, 2023, 6:48pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/6 "2023-06-12T18:48:27Z")

</div>

I will bring up the possibility in subgroup tomorrow to suggest that “all procedures defined in a template are implied to be provided in a generic interface with their given name” (or something similar), but I am not yet certain that there aren’t potential complications. What if I’d rather provide it as an operator? Or put multiple of the procedures defined in a single template into a single generic interface? Or define a type and type-bound procedures? There’s multiple more complicated cases to think through than to just assume it will work.

---

<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:** [June 12, 2023, 7:07pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/7 "2023-06-12T19:07:18Z")

</div>

> [@everythingfunctional](#):
>
> I will bring up the possibility in subgroup tomorrow to suggest that “all procedures defined in a template are implied to be provided in a generic interface with their given name” (or something similar) …

Thank you, that will be very useful, I sincerely hope it gains traction with both the subgroup as well as the overall committee.

---

<div class="post-metadata">

**Author:** ![tyranids](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tyranids](https://fortran-lang.discourse.group/u/tyranids)\
**Post date:** [June 12, 2023, 7:13pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/8 "2023-06-12T19:13:33Z")

</div>

What do people think about comptime as Zig has implemented? It really seems like an amazing system that is powerful, expressive, and rather concise in notation. [Documentation - The Zig Programming Language](https://ziglang.org/documentation/master/#comptime)

Such a facility would allow generic programming, as well as better inform the compiler of calculations and constants that should be known at compile time. If they cannot be resolved, compilation error.

I’m a big fan of generics being added to Fortran, but think @FortranFan is dead on - if the capability is excessively verbose/complicated to use, or so convoluted that future changes are deemed impossible… that’s a major setback to generic programming in Fortran. We know if a half baked feature is added, then removal will be impossible (backwards compatibility), but fixing it may very well be impossible as well (backward compatibility)

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [June 12, 2023, 11:26pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/9 "2023-06-12T23:26:15Z")

</div>

@FortranFan yes, the simplification that you want is what I think of as “surface level language”. If we implement this “any kind” feature into LFortran, we can later use the simpler syntax and simpler surface level semantics and the compiler frontend generates the same intermediate representation. I think there is no door closed.

@tyranids yes, I am familiar with Zig’s style generics and have mentioned it to the Fortran Committee members. Roughly speaking there are two main approaches: generics (types) and metaprogramming. The current Fortran proposal is just generics, not metaprogramming (which however could be added later). Zig is an example of metaprogramming: executing code (in this case Zig code) at compile time that can operate on types. In order to ensure that the generics are not half-baked, we have implemented a compiler prototype and are asking for feedback. Before they get standardized, we should get enough experience with it to ensure that the feature truly fixes what users have been asking for, in a simple enough syntax with all the features in. Indeed, your concern is why I voted against many features that I considered half-baked, which might be impossible to get fixed later. Generics must be fully baked. 🙂

---

<div class="post-metadata">

**Author:** ![tyranids](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tyranids](https://fortran-lang.discourse.group/u/tyranids)\
**Post date:** [June 13, 2023, 2:22am UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/10 "2023-06-13T02:22:31Z")

</div>

> [@certik](#):
>
> @tyranids yes, I am familiar with Zig’s style generics and have mentioned it to the Fortran Committee members. Roughly speaking there are two main approaches: generics (types) and metaprogramming. The current Fortran proposal is just generics, not metaprogramming (which however could be added later). Zig is an example of metaprogramming: executing code (in this case Zig code) at compile time that can operate on types. In order to ensure that the generics are not half-baked, we have implemented a compiler prototype and are asking for feedback. Before they get standardized, we should get enough experience with it to ensure that the feature truly fixes what users have been asking for, in a simple enough syntax with all the features in. Indeed, your concern is why I voted against many features that I considered half-baked, which might be impossible to get fixed later. Generics must be fully baked. 🙂

I think the concept of ‘this value shall be known at compile time as constant, and if it’s not throw a compiler error’ is incredibly valuable. Fortran could start generics there, with the only ‘compile time known constants’ allowed in the first pass being `kind` parameters. That would allow one to write code like

```auto
pure function realsumplus2(xin<rk>) result(xout<rk>)
    integer, comptime :: rk !! this value is known at compile time to be a constant
                             !! and therefore can be substituted in source code as an integer parameter
    real(rk), intent(in) :: xin(:)
    real(rk) :: xout
    xout = sum(xin) + 2.0_rk
end function realsumplus2

```

This type of function definition inherently defines the interface as well: the input argument `xin` must be `real(kind=rk)`, and the corresponding output value `xout` is of type `real(kind=rk)`. To be fully transparent, my example syntax here is completely off the cuff and very well may be fatally flawed. However, I will maintain my original point: " I think the concept of ‘this value shall be known at compile time as constant, and if it’s not throw a compiler error’ is incredibly valuable. Fortran could start generics there, with the only ‘compile time known constants’ allowed in the first pass being `kind` parameters." The reason this is good is twofold: 1) it is immediately useful as my example above, and 2) it is not overly restrictive such that future expansion is pre-emptively made impossible.

---

<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:** [June 13, 2023, 2:45am UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/11 "2023-06-13T02:45:50Z")

</div>

> [@tyranids](#):
>
> `integer, comptime :: rk`

The standard only includes the semantics of a processor constant (“compile time” in ordinary parlance) with the `KIND` clause to the integer type e.g.,

```fortran
integer, kind :: k

```

There is really no need to invent `constant` or `comptime` or any other term to signify the same.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [June 13, 2023, 3:51am UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/12 "2023-06-13T03:51:58Z")

</div>

@tyranids do you want to help prototype this in LFortran? I think we have all the pieces in place already and I can help you. If we can have more people pushing these generics, it would be incredibly helpful.

---

<div class="post-metadata">

**Author:** ![tyranids](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tyranids](https://fortran-lang.discourse.group/u/tyranids)\
**Post date:** [June 13, 2023, 4:30am UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/13 "2023-06-13T04:30:56Z")

</div>

> [@Can floating point literals be adapted by the compiler to double precision variable?](https://fortran-lang.discourse.group/t/can-floating-point-literals-be-adapted-by-the-compiler-to-double-precision-variable/2034/112):
>
> > [@tyranids](#):
> >
> > `integer, comptime :: rk`
> 
> The standard only includes the semantics of a processor constant (“compile time” in ordinary parlance) with the `KIND` clause to the integer type e.g.,
> 
> ```auto
> integer, kind :: k
> 
> ```
> 
> There is really no need to invent `constant` or `comptime` or any other term to signify the same.

I would be happy to have ‘integer, kind’ extended to somehow indicate a variable-in-source-but-known-as-constant-at-compile-time value. It’s very reasonable to not want new keywords for every new feature, but I am not sure how to go about that really in a way that won’t draw ire from the (majority?, at least) many champions of backwards compatibility. If existing keywords and syntax is somehow repurposed or changed in functionality, how does that not break somebody’s code, somewhere?

> [@Can floating point literals be adapted by the compiler to double precision variable?](https://fortran-lang.discourse.group/t/can-floating-point-literals-be-adapted-by-the-compiler-to-double-precision-variable/2034/113):
>
> @tyranids do you want to help prototype this in LFortran? I think we have all the pieces in place already and I can help you. If we can have more people pushing these generics, it would be incredibly helpful.

Let’s discuss this further. I am coming around on personally contributing to some FOSS Fortran compilers. If everyone says “not me,” then who will?

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [June 13, 2023, 9:27am UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/14 "2023-06-13T09:27:23Z")

</div>

> [@FortranFan](#):
>
> `integer, kind :: k`

I could imagine this kind of declaration might be written in an extended way as

```auto
integer(kind=kind(j)), kind :: k

```

To my eye, those three different uses of “kind” in the declaration look clear and unambiguous. However, if there is some kind of syntax ambiguity here, then it should be addressed early. If necessary, perhaps the KIND of `k` could be restricted to only the default integer kind?

---

<div class="post-metadata">

**Author:** ![tyranids](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tyranids](https://fortran-lang.discourse.group/u/tyranids)\
**Post date:** [June 13, 2023, 10:33am UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/15 "2023-06-13T10:33:03Z")

</div>

I think part of the key is somehow indicating that `integer, kind :: k` is a “compile-time input argument that must be unambiguously known for each entry to this scope.” I think the syntax suggested earlier like `function<WP>(args)` is good, as the different type of bracketing on `<WP>` indicates that this is still a potential list of values, but they are somehow different from `(args)`. Perhaps `k` would be declared as `integer, intent(comptime), kind :: k`, to indicate its value belongs in the `<brackets>` of function calls.

As I type the above, I am still not seeing why this need be restricted to `kind` values. The value of `k` is known at compile time to be constant, if the compiler cannot verify this - compilation error. Next, for each unique `k` in all references to `function<k>(args)`, compile a separate version of `function`, with the value of `k` propagated throughout `function`’s source. If this were a Fortran-language level task, a human programmer should find/replace all instances of `k` in `function`’s scope with the compile-time known constant to achieve the desired effect.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [June 13, 2023, 10:49am UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/16 "2023-06-13T10:49:32Z")

</div>

> [@tyranids](#):
>
> As I type the above, I am still not seeing why this need be restricted to `kind` values.

In a PDT, an integer with the KIND attribute can be used in other ways, such as for array lengths. The KIND attribute means that the value is known by the compiler at compile time, unlike the LEN attribute which might be known only at run time. An integer with the LEN attribute cannot be used to specify KIND values. I think both can be used in expressions, for example to initialize component values. As I’ve said before, I have wanted to use the PDT feature many times over the last 20 years, but there have always been compiler bugs in some of the compilers that I use that have prevented that widespread use. I hope that same thing does not happen for this template feature.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [June 13, 2023, 1:24pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/17 "2023-06-13T13:24:04Z")

</div>

> [@tyranids](#):
>
> Let’s discuss this further. I am coming around on personally contributing to some FOSS Fortran compilers. If everyone says “not me,” then who will?

Awesome! If you choose to contribute to LFortran, you can sign up at [https://lfortran.zulipchat.com/](https://lfortran.zulipchat.com/) and I am happy to get you started.

---

<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:** [June 13, 2023, 2:12pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/18 "2023-06-13T14:12:54Z")

</div>

> [@certik](#):
>
> @FortranFan yes, the simplification that you want is what I think of as “surface level language”.

@certik, as you will note, in the context of Fortran and especially its standard, there is no such thing as a “surface level language”.

You can view things however, but that is largely immaterial: what really matters is

- first, what the implications are for the practitioners of Fortran. If even for the simple case you present, if the practitioners are required to needlessly set up `INTERFACE` constructs and whatever while giving the appearance of “strong concepts” but not having all the guardrails for it, then again the facility will be **half-baked** for practice and lead to great consternation and disuse,
- second, how the larger set of implementors manage with the new facility. If the LLVM-based processors and IBM Fortran and `gfortran` and NAG and Intel, etc. are unable to navigate the complexity whereas it’s a breeze for `LFortran` or other newer better-designed processors from the ground-up, it still is a massive problem.

Thus `KISS` should apply and a simple measure of it is whether for simple cases, the facility for the practitioners first and the implementors next is simple enough. I am not seeing that at the moment and that’s my concern.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [June 13, 2023, 2:32pm UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/19 "2023-06-13T14:32:12Z")

</div>

@FortranFan my point is that I think you can get what you want and I am hoping @tyranids will implement it. 🙂

---

<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:** [June 14, 2023, 6:54am UTC](https://fortran-lang.discourse.group/t/simple-generics/5973/20 "2023-06-14T06:54:12Z")

</div>

> [@everythingfunctional](#):
>
> I will bring up the possibility in subgroup tomorrow to suggest that “all procedures defined in a template are implied to be provided in a generic interface with their given name” (or something similar), but I am not yet certain that there aren’t potential complications. What if I’d rather provide it as an operator? Or put multiple of the procedures defined in a single template into a single generic interface? Or define a type and type-bound procedures? There’s multiple more complicated cases to think through than to just assume it will work.

I did bring up this aspect at the meeting. The general sentiment was that phrases/behaviors that are “implied,” “as-if,” or “automatic” are not really “Fortranic.” Not to mention that it potentially closes the door on other use cases, or at least makes the standard and implementations much more difficult. I.e. the template writer wants to put several of the procedures in a template behind a single interface (a la `findloc`). You can’t put generic names into a separate generic interface. You also can’t specify generic names as type-bound procedures. So procedure names defined in a template automatically being generic names did not seem popular, and seems to cause more problems than it solves. Sorry, the extra line in templates is likely to be necessary for the spelled out version.

FYI, I have submitted a paper to pursue a “shorthand” form for simpler cases, where this could be the case: [https://j3-fortran.org/doc/year/23/23-187.txt](https://j3-fortran.org/doc/year/23/23-187.txt)

[Next page](https://fortran-lang.discourse.group/t/simple-generics/5973.md?page=2)
