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

22-120r2 Generics formal requirements: usage/notional syntax? #72

Open
zjibben opened this issue Mar 3, 2022 · 4 comments
Open

22-120r2 Generics formal requirements: usage/notional syntax? #72

zjibben opened this issue Mar 3, 2022 · 4 comments

Comments

@zjibben
Copy link
Member

zjibben commented Mar 3, 2022

After yesterday's discussion on 22-120r2, I thought github issues would be a better vehicle for discussing different angles in parallel. I'll make a couple issues with some questions I have. First up:

E. A template shall be instantiated by specifying an actual parameter
for each dummy template parameter.
E1. A type-spec must be provided for a type name dummy template parameter.
E2. A const-expr must be provided for a value dummy template parameter.
E3. A procedure or a generic-spec must be provided for a
procedure dummy template parameter
E4. An operator must be provided for an operator dummy template parameter.
Notional syntax:
INSTANTIATE TMPL(INTEGER(KIND=INT32))
...
INTEGER(KIND=INT32) :: I, ARRAY(10)
...
I = GET_ITH(ARRAY, 3)

This is orthogonal to the requirement E, but the notional syntax has me thinking. Did I understood yesterdays discussion correctly, that usage might involve renames, and look something like:

instantiate tmpl(integer(kind=int32)), get_ith => get_ith_i4
instantiate tmpl(integer(kind=real64)), get_ith => get_ith_r8
instantiate tmpl(cats), get_ith => get_ith_cats
instantiate tmpl2(integer(kind=int32), integer(kind=int32)), map => map_i4_i4
instantiate tmpl2(cats, dogs), map => map_cats_dogs

integer(kind=int32) :: i, j, ints(10)
real(kind=real64) :: reals(10)
type(map_i4_i4) :: intmap
type(map_cats_dogs) :: catdog

i = get_ith_i4(ints, 3)
j = get_ith_r8(reals, i)
call intmap%xxx
call catdog%xxx
@tclune
Copy link
Member

tclune commented Mar 3, 2022

One problem is that the paper on GitHub is of necessity out of date now. Once the paper is on J3 there are intellectual property issues with putting it back on GitHub. (At least I think I've heard that in the past.)

But to the technical aspects of your issue: Yes. In the specs paper this is described. It did not seem appropriate for the REQUIREMENTS paper, as it is just a "make it work well" rather than any particular use case that is driving this.

But ... the best practice would instead be for TMPL to have something like this inside:

   TEMPLATE TMPL (...)
       INTERFACE  GET_ITH
            MODULE PROCEDURE GET_ITH_T
       END INTERFACE
       ...
     CONTAINS
         FUNCTION GET_ITH_T(...)
          

This would obviate the need for rename in this context. That would not solve all possible conflicts (esp. with derived types) of course. But a useful thing to mention.

@zjibben
Copy link
Member Author

zjibben commented Mar 3, 2022

One problem is that the paper on GitHub is of necessity out of date now. Once the paper is on J3 there are intellectual property issues with putting it back on GitHub. (At least I think I've heard that in the past.)

I didn't know that, thanks for the heads up! For what it's worth, I haven't read the version here on github more than was necessary to quote sections I had read from J3.

the best practice would instead be for TMPL to have something like this inside:

Ah, that's a big improvement to usability, compared to renaming. I think the renames would still be necessary for containers though. Not much way around that.

At first glance I was really irked by the need for a block of instantiate statements, instead of instantiating in-line with declarations and function calls. Bill sounded troubled by this as well. As I acclimate to it though, I'm not sure it's a terribly big difference to readability, especially once function calls are in an interface:

instantiate tmpl(integer(kind=int32))
instantiate tmpl(integer(kind=real64))
instantiate tmpl(cats)
instantiate tmpl2(integer(kind=int32), integer(kind=int32)), map => map_i4_i4
instantiate tmpl2(cats, dogs), map => map_cats_dogs

integer(kind=int32) :: i, j, ints(10)
real(kind=real64) :: reals(10)
type(map_i4_i4) :: intmap
type(map_cats_dogs) :: catdog

i = get_ith(ints, 3)
j = get_ith(reals, i)
call intmap%xxx
call catdog%xxx

vs

use tmpl
use tmpl2

integer(kind=int32) :: i, j, ints(10)
real(kind=real64) :: reals(10)
type(map<integer(kind=int32), integer(kind=int32)>) :: intmap
type(map<cats, dogs>) :: catdog

i = get_ith<integer(kind=int32)>(ints, 3)
j = get_ith(reals, i) ! Infer from arguments?
call intmap%xxx
call catdog%xxx

@tclune
Copy link
Member

tclune commented Mar 3, 2022

I too would prefer the inline notation, but subgroup so far has found that this would be very difficult to do.

But it would be a good time to re-examine this based upon our most recent work. When we rejected the above, it was when we were still looking at parameterized modules.

Being clunky is Fortranic. :-)

@zjibben
Copy link
Member Author

zjibben commented Mar 3, 2022

I can certainly imagine inline notation would involve far more and deeper changes to the standard...

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

2 participants