j3-fortran / fortran_proposals

Proposals for the Fortran Standard Committee
178 stars 15 forks source link

October 2020 WG5/J3 meeting #185

Open certik opened 3 years ago

certik commented 3 years ago

Zach and I will use this issue to keep the community updated on the work of the WG5 and J3 Committees at the October 2020 (virtual) meeting.

The documents for this meeting are here.

Monday 10/12/2020

JoR:

Data:

HPC:

Tuesday (10/13/2020)

Generics:

JoR:

Wednesday (10/14/2020)

Interp:

Edit:

HPC:

Generics:

JoR:

Data:

klausler commented 3 years ago

What was the outcome of the discussion on 20-135?

certik commented 3 years ago

@klausler I just updated it, sorry about that.

klausler commented 3 years ago

@klausler I just updated it, sorry about that.

Thanks. But 20-135 and 20-144 still seem weird to me. Are there any use cases yet for these features?

certik commented 3 years ago

Thanks. But 20-135 and 20-144 still seem weird to me. Are there any use cases yet for these features?

There were no new use cases presented. I raised the issue that there are objections against these features from the community, that it would be nice to address and resolve them.

gklimowicz commented 3 years ago

Not actually solving a problem using them. Just example fragments.

klausler commented 3 years ago

Anything decided on Wednesday?

zjibben commented 3 years ago

@klausler I just updated with Wednesday's results.

mleair commented 3 years ago

With regard to 20-135 and 20-144, @tclune provided this use case:

Consider a situation where a developer needs to pad arrays of various ranks (1-3) with halo (or guard) cells in each direction with a specified width and an optional pad value. The logic is nearly identical in each case except that it is otherwise awkward to declare the arrays and reference sections and such. The example implementation below is less than ideal because one still must resort to a clunky mechanism to create specific names for the otherwise overloaded interface. In practice, I would use FPP/CPP #include and macros to create unique names through token concatenation.

There are 2 files below. The include file with most of the meat and the module file that includes it 3 times.

file 'pad.inc':

  REAL, RANK(N), INTENT(IN) :: ARRAY
  INTEGER, INTENT(IN) :: WIDTH
  REAL, OPTIONAL, INTENT(IN) :: PAD_VALUE
  REAL, BOUNDS(1-WIDTH:SHAPE(ARRAY)+WIDTH),  :: PAD_ARRAY

  IF (PRESENT(PAD_VALUE)) PAD_ARRAY = PAD_VALUE
  PAD_ARRAY(@:SHAPE(ARRAY)) = ARRAY

file pad_mod.F90:

MODULE PAD_MOD
   IMPLICIT NONE
   INTERFACE PAD_ARRAY
      MODULE PROCEDURE :: PAD_ARRAY_1D
      MODULE PROCEDURE :: PAD_ARRAY_2D
      MODULE PROCEDURE :: PAD_ARRAY_3D
   END INTERFACE PAD_ARRAY

CONTAINS

   FUNCTION PAD_ARRAY_1D(ARRAY, WIDTH, PAD_VALUE)
      INTEGER, PARAMETER :: N = 1
      INCLUDE 'PAD_INC'
   END FUNCTION PAD_ARRAY_1D

   FUNCTION PAD_ARRAY_2D(ARRAY, WIDTH, PAD_VALUE)
      INTEGER, PARAMETER :: N = 2
      INCLUDE 'PAD_INC'
   END FUNCTION PAD_ARRAY_2D

   FUNCTION PAD_ARRAY_3D(ARRAY, WIDTH, PAD_VALUE)
      INTEGER, PARAMETER :: N = 3
      INCLUDE 'PAD_INC'
   END FUNCTION PAD_ARRAY_3D

END MODULE PAD_MOD
certik commented 3 years ago

This is a great example of why I think this feature does not go far enough. I would like this to just be:

MODULE PAD_MOD
   IMPLICIT NONE

CONTAINS

   FUNCTION PAD_ARRAY(ARRAY, WIDTH, PAD_VALUE)
      INTEGER, PARAMETER :: N = RANK(ARRAY)
      REAL, RANK(N), INTENT(IN) :: ARRAY
      INTEGER, INTENT(IN) :: WIDTH
      REAL, OPTIONAL, INTENT(IN) :: PAD_VALUE
      REAL, BOUNDS(1-WIDTH:SHAPE(ARRAY)+WIDTH),  :: PAD_ARRAY

     IF (PRESENT(PAD_VALUE)) PAD_ARRAY = PAD_VALUE
     PAD_ARRAY(@:SHAPE(ARRAY)) = ARRAY
   END FUNCTION

END MODULE PAD_MOD

Would this work, and if not, why not?

Well, I think it would not work because the rank is only known either at runtime, or at the point where this function is called. So this is in some sense a "generic interface". But I would like to be able to write code in Fortran like this, with no pre-processor, no include files. Just code that works for arrays of any rank.

An interesting question then is: is this a runtime or compile time polymorphism? Well, I think it can be both, with the same syntax. The compiler can choose to generate just one subroutine, that operates on the array descriptor at runtime appropriately. Or it can choose to "instantiate" this for whatever rank you actually use it for (say 1D and 3D only) and generate an efficient code just for this rank.

tclune commented 3 years ago

You cannot have circularly defined arguments:

      INTEGER, PARAMETER :: N = RANK(ARRAY)
      REAL, RANK(N), INTENT(IN) :: ARRAY

The solution is to have N come in by other means. (E.g., a template parameter.)

So in that I agree the existing feature does not go far enough. But having a template parameter, we would still need the current feature to implement what you wrote.

klausler commented 3 years ago

Is there any other use case? This halo example would be easy to write without using this feature.

tclune commented 3 years ago

Yes. I'm working on a couple more for which I've shown how I would implement the use case in each revision from F2008 to F202y.

The example above was merely to show that the feature could be used in a generic context. Daniel could not see that aspect from the examples in the paper which were just to demonstrate the syntax. The real win is when we can combine this feature with something like template parameters.

mleair commented 3 years ago

To address the comment by @tclune, perhaps the array in the parameter statement is the "template parameter". For example, using parameterized modules with modules pseudocode:

MODULE MOD_RANK_2
  REAL :: TARRAY(10, 10)
END MODULE MOD_RANK_2

MODULE MOD (T)
  USE T
  CONTAINS

  FUNCTION PAD_ARRAY(ARRAY, WIDTH, PAD_VALUE)
    INTEGER, PARAMETER :: N = RANK(TARRAY)
    REAL, RANK(N), INTENT(IN) :: ARRAY
     :
  END FUNCTION PAD_ARRAY
END MODULE MOD

PROGRAM P
  USE MOD(MOD_RANK_2)
END

The above example could also be written in a template syntax if that's the direction we go. Also, I imagine a concepts syntax could also be introduced to require that the above module parameter incudes a TARRAY object.

certik commented 3 years ago

I thought the way to do it is using the .. rank:

   FUNCTION PAD_ARRAY(ARRAY, WIDTH, PAD_VALUE)
      REAL, INTENT(IN) :: ARRAY(..)
      INTEGER, INTENT(IN) :: WIDTH
      REAL, OPTIONAL, INTENT(IN) :: PAD_VALUE
      REAL, BOUNDS(1-WIDTH:SHAPE(ARRAY)+WIDTH),  :: PAD_ARRAY

     IF (PRESENT(PAD_VALUE)) PAD_ARRAY = PAD_VALUE
     PAD_ARRAY(@:SHAPE(ARRAY)) = ARRAY
   END FUNCTION

I guess you don't even need the N parameter in this case.

P.S. We should be discussing this at #157.

tclune commented 3 years ago

The 2nd executable statement above won't work. ARRAY can only be referenced (in a useful manner) within a SELECT RANK if it is of assumed rank.

Like wise, the declaration of PAD_ARRAY cannot work like that. The compiler needs to know the rank at compile time. It's also not clear to me if it is legal to use SHAPE(ARRAY) in the declaration since ARRAY is assumed rank. That seems like it ought to be able to work but I could not immediately spot wording in the standard that makes this clear. Probably a Malcolm question in the near future, but we (generic subgroup) should at least make an effort to find words in the standard.

klausler commented 3 years ago

16.9.172. SHAPE(A) works for any array A except an assumed-size array, including assumed-rank, (and oddly enough, an assumed-rank array associated with an assumed-size array).

tclune commented 3 years ago

@klausler Thanks - that was what I was hoping for SHAPE.

The declaration of PAD_ARRAY is still illegal though. The constraint added in the BOUNDS paper is:

C821b shall be a rank one integer array with constant size.

Because ARRAY is assumed-rank, SHAPE(ARRAY) is not of constant size.

klausler commented 3 years ago

That's a surprising restriction for a feature that is intended to be useful in rank-independent programming, and it should be easy to fix. The language has assumed-rank dummy arguments already, and could accommodate other objects with unknown rank.

tclune commented 3 years ago

There is a difference between rank-independent and rank-agnostic. (Well, I'm tired now, but I think there is a distinction to be made.)

Regardless, I agree that it is at least a bit surprising at first blush this this is forbidden, but I disagree that it would be easy to fix. The rank of PAD_ARRAY is not known at compile time. Deferred-rank has been suggested and discussed (briefly) several times is recent years, and it would be considered a major new feature.

"Unknown rank" for deferred-rank dummy arguments is possible because the dope vector can be found in the associated actual argument. Very little can be done with them outside of a SELECT RANK statement which allows the compiler a place to generate the rank-dependent code.

tclune commented 3 years ago

After I walked away, I realized a simple example should crystalize why this is not easy to fix. Should the compiler be able to diagnose whether any of the assignment statements below are legal? We usually expect the compiler to diagnose when an array reference uses an incorrect number of simple subscripts.

subroutine s(a, b)
   real, intent(in) :: a(..) ! assumed-rank
   real, bounds(shape(a)) :: b 

   b(1) = 1
   b(1,1) = 1
   b(1,1,1) = 1

end subroutine s

This restriction is relaxed a bit for the proposed @ syntax, where only run-time checking is possible, but the intent with BOUNDS and RANK was not to introduce a new type of array or to change the rules for existing mechanisms for accessing elements and array sections.

klausler commented 3 years ago

None of those assignments would be allowed if 'b' were an assumed-rank dummy argument either. The situation would be similar in the event that BOUNDS had an argument of unknown length, as in your example.

tclune commented 3 years ago

I might not oppose a change to extend BOUNDS to declare two different types of arrays. When the length is fixed, then array references can be made without the protection of SELECT RANK. When the length is not fixed then the array could only be referenced (with the obvious exceptions) inside of SELECT RANK. I think it could be confusing at times, as it may not always be easy for the user to tell whether or not the length is fixed. More examples where it provides value might be useful to aid in the evaluation.

I would be opposed to a change that ends up forcing even those cases with fixed size to be accessed within SELECT RANK clauses.

A related thought: SELECT RANK is not so bad when there is only one assumed-rank array involved. Once there are multiple such arrays and even if you know they are all the same rank, you end up being forced to nest multiple select ranks. E.g., consider the case where I have 3 such dummy arguments b1, b2, b3 and as a final step I want to add them and store the result back into b1. Maybe they can only be rank 2 and 3 to keep this "simple". To do this with the suggested extension of BOUNDS:

real, bounds(shape(a)) :: b1
real, bounds(shape(a)) :: b2
real, bounds(shape(a)) :: b3

select rank (b1)
rank (2)
   select rank(b2)
   rank (2)
      select rank(b3)
      rank(2)
           b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b2(@:shape(b3))
      rank(3)
           b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b2(@:shape(b3))
      end select
   rank (3)
      select rank(b3)
      rank(2)
           b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b2(@:shape(b3))
      rank(3)
           b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b2(@:shape(b3))
      end select
rank (3)
   select rank(b2)
   rank (2)
      select rank(b3)
      rank(2)
           b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b2(@:shape(b3))
      rank(3)
           b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b2(@:shape(b3))
      end select
   rank (3)
      select rank(b3)
      rank(2)
           b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b2(@:shape(b3))
      rank(3)
           b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b2(@:shape(b3))
      end select
   end select
end select

It would be much better if we could somehow enable such assignment statements to be moved out of the SELECT RANK block. Maybe if all the subscripts are multi-subscripts (i.e., those with the @) we could remove the constraint. We would need some very solid use cases, and recognize up front that this is a big enough change that other generic capabilities in F202y may be sacrificed in the process.

tclune commented 3 years ago

Thinking about it some more my last statement is not very useful. Using the @ does not change the fact that the intermediate expressions are of unknown rank at compile time. There would need to be a general facility in the language for handling expressions of unknown rank for something along the lines to work.

mleair commented 3 years ago

Tom,

Would a select rank that can take more than one array be useful in general? That is, the select rank would evaluate all the arrays in the list. If they are all the same rank, then execution branches to that rank case. Otherwise, execution branches to RANK DEFAULT (if provided) or to the end of the select rank construct. If RANK DEFAULT is provided, then the programmer could provide either a nested select rank or do something else (e.g., issue an error and abort).

Your example using the extension:

real, bounds(shape(a)) :: b1
real, bounds(shape(a)) :: b2
real, bounds(shape(a)) :: b3

select rank (b1, b2, b3)
rank (2)
  b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b3(@:shape(b3))
rank (3)
  b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b3(@:shape(b3))
rank default
  stop 'Unexpected Rank in b1, b2, and/or b3'
end select
klausler commented 3 years ago

Tom,

Would a select rank that can take more than one array be useful in general? That is, the select rank would evaluate all the arrays in the list. If they are all the same rank, then execution branches to that rank case. Otherwise, execution branches to RANK_DEFAULT (if provided) or to the end of the select rank construct. If RANK_DEFAULT is provided, then the programmer could provide either a nested select rank or do something else (e.g., issue an error and abort).

Your example using the extension:

real, bounds(shape(a)) :: b1
real, bounds(shape(a)) :: b2
real, bounds(shape(a)) :: b3

select rank (b1, b2, b3)
rank (2)
  b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b3(@:shape(b3))
rank (3)
  b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b3(@:shape(b3))
rank_default
  stop 'Unexpected Rank in b1, b2, and/or b3'
end select

Since the rank is a known constant in each RANK case, the @ notation doesn't seem necessary.

real, bounds(shape(a)) :: b1, b2, b3
select rank (b1, b2, b3)
rank (2)
  b1 = b1 + b2 + b3
rank (3)
  b1 = b1 + b2 + b3
rank default
  error stop 'you lose'
end select

or even

real, bounds(shape(a)) :: b1, b2, b3
select rank (b1, b2, b3)
rank (2:3)
  b1 = b1 + b2 + b3
rank default
  error stop 'you lose'
end select

which seems pretty elegant to me.

certik commented 3 years ago

That is my point, the whole select rank does not seem necessary.

real, bounds(shape(a)) :: b1
real, bounds(shape(a)) :: b2
real, bounds(shape(a)) :: b3

b1(@:shape(b1)) = b1(@:shape(b1)) + b2(@:shape(b2)) + b2(@:shape(b3))

The @ notation would imply select rank.

tclune commented 3 years ago

@klausler Right - in this particular case, whole arrays are appropriate and I was blinded by the details. But there are certainly still fixed-rank cases where eg., some other aspect of the rank handling can take useful advantage of the @ notation. The gather example I posted for instance.

@certik Conceptually, you are correct. There is absolutely no reason for SELECT RANK from the user perspective - one can work out at run time everything that should happen. From the compiler perspective, I am assured that it matters a great deal. Not only are there various constraints that would need to be loosened, but I'm certain that there are a number of optimizations that are also lost in the general case. It is quite possible that we can have the best of both worlds - "potentially unoptimized" if one uses @ and fully constrained if one does not. But it is a funny situation, and I fully expect vendors to push back with cases we have not yet considered; saying that this is all a bridge too far.

On a related front, should we then allow:

type foo
    real, allocatable :: arr(..)
end type

After all, the references can all be checked at run time to be certain that they are correct, and we now have syntax for allocating such arrays.

tclune commented 3 years ago

I should also say that when debating SELECT RANK, I did suggest an amendment that would allow

SELECT RANK (arr)
RANK (2:4)
      CALL SUB(arr)
END SELECT RANK

where SUB is suitable overloaded for the relevant ranks. Or more generally any expression which is sensible for the specified ranks. After all, it is fairly straightforward to preprocess this back into a fine-grained list of RANK clauses. Vendors in the room quickly shot it down as being unworkable. I cannot defend there statements, and it would be nice if a vendor could chime in here to provide some background on where the tradeoffs are here.

klausler commented 3 years ago

Fortran already has assumed rank ALLOCATABLE dummy arguments; deferred rank ALLOCATABLE variables and components would be easy to support. More edits to the document than lines of code, I think.

I don't know why a range of ranks would be considered difficult to implement, given a working implementation of the current SELECT RANK. Error messages for anything in the contained statements might be hard to contextualize in a useful way with the value of the rank that leads to a particular error, but that's a quality of implementation concern.

tclune commented 3 years ago

Well, as someone who has wanted deferred rank for a very long time, I find these statements encouraging. And I am somewhat amused that my current role makes me the voice of caution.

klausler commented 3 years ago

To be clear, "easy to support" does not mean "easy to accomplish in J3". Or vice versa.

tclune commented 3 years ago

Certainly. But I can only see as far as what is hard to change in the text. I rely on vendors to tell me what is hard to implement. At least one vendor (will not name publicly) has indicated to me that it may well make sense to support deferred rank arrays at some point but that it would be a major feature. I did not press them to what degree it was because of the document or because of implementation. I was just ecstatic that it was not immediately shot down as without merit.

klausler commented 3 years ago

Deferred rank array variables and components, in general, might have pitfalls; deferred rank ALLOCATABLE and POINTER arrays, on the other hand, would be pretty much the same thing as assumed rank dummy arguments.

certik commented 3 years ago

@tclune this is the kind of discussion we have to have, let's keep it going. Together with a prototype compiler implementation, which I volunteer to attempt for promising proposals and I am hoping @klausler will also. :)

klausler commented 3 years ago

@tclune this is the kind of discussion we have to have, let's keep it going. Together with a prototype compiler implementation, which I volunteer to attempt for promising proposals and I am hoping @klausler will also. :)

Well, maybe. I'm not on J3 and I'm somewhat less concerned with advocating for new standard features than I am about trying to keep more poorly designed features like DO CONCURRENT from being mandated, and I don't see how prototyping would help much with that goal.

certik commented 3 years ago

Here is a great idea proposed by @longb:

template subroutine add(b1, b2, b3)
  real,intent(inout) :: b1(..)
  real,intent(in) :: b2(..)
  real,intent(in) :: b3(..)

  b1 = b1 + b2 + b3

end subroutine add

I wonder if the template modifier before subroutine (which I initially missed) is needed? As a user I wouldn't mind writing it without it. But I think the idea is that it explicitly states that the compiler will be "instantiating" this at the call site by mangling the subroutine name internally. I think that's fine.

mleair commented 3 years ago

@certik As someone who is just getting back into J3 Committee work, I need to ask. Is the proposed template syntax written up somewhere? Or was it first mentioned just now on the J3 email list?

certik commented 3 years ago

@mleair this is the first time I saw it.

mleair commented 3 years ago

OK. Thanks!

klausler commented 3 years ago

Here is a great idea proposed by @longb:

template subroutine add(b1, b2, b3)
  real,intent(inout) :: b1(..)
  real,intent(in) :: b2(..)
  real,intent(in) :: b3(..)

  b1 = b1 + b2 + b3

end subroutine add

I wonder if the template modifier before subroutine (which I initially missed) is needed? As a user I wouldn't mind writing it without it. But I think the idea is that it explicitly states that the compiler will be "instantiating" this at the call site by mangling the subroutine name internally. I think that's fine.

How would the interface of that procedure declare that the ranks of the dummy arguments were either identical or (for b2 and b3) scalar?

longb commented 3 years ago

Hi Mark,

The 202X feature list is in WG5 paper N2165 - worth a read.

The last templates paper was from Meeting 217; paper 18-281r1

Cheers, BIll

On Oct 20, 2020, at 2:47 PM, mleair notifications@github.com wrote:

@certik As someone who is just getting back into J3 Committee work, I need to ask. Is the proposed templay syntax written up soemwhere? Or was it first mentioned just now on the J3 email list?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

Bill Long longb@hpe.com Engineer/Master , Fortran Technical Support & voice: 651-605-9024 Bioinformatics Software Development fax: 651-605-9143 Hewlett Packard Enterprise/ 2131 Lindau Lane/ Suite 1000/ Bloomington, MN 55425

certik commented 3 years ago

How would the interface of that procedure declare that the ranks of the dummy arguments were either identical or (for b2 and b3) scalar?

Good point. Following the "strong concepts" idea (that we seem to agree in the generics subgroup is the way to go), if the compiler compiles this routine and does not report an error, it should mean there is no problem with this code.

This means that the compiler must generate the compatible ranks as part of the function signature, and then at the call site if the user passes incompatible ranks, it must generate a nice message, without having to go over the code of add to determine that.

So the question is, whether the compiler can generate the list of compatible ranks (in this case it seems the requirement is that they either have to have the same rank, or some of them can be scalars). If the compiler cannot do that automatically, then I think the path is to require the user to specify that explicitly using some variation of the syntax proposed by @tclune.

certik commented 3 years ago

Ok, so the paper 18-281r1 that @longb suggested above explains the template prefix proposal. One of the examples in the paper allows to write a procedure that works for any real kind, which seems to be exactly the issue #128.

longb commented 3 years ago

On Oct 20, 2020, at 2:53 PM, Peter Klausler notifications@github.com wrote:

Here is a great idea proposed by @longb:

template subroutine add(b1, b2, b3 )

real,intent(inout) :: b1(..)

real,intent(in) :: b2(..)

real,intent(in) :: b3(..)

b1 = b1 + b2 + b3

end subroutine add I wonder if the template modifier before subroutine (which I initially missed) is needed? As a user I wouldn't mind writing it without it.

The word “template” is just an addition to the current list of prefix modifiers (elemental, pure, impure, recursive, non_recursive). It is a signal to the compiler that declaration usage in the subprogram is outside the restrictions for non-template subprograms. IT is easier in the standard to have words like “it template does not appear…”. An underlying motivation for the template proposal is to leverage already existing ideas. For example, assumed-kind would be allowed, as in

real(*),intent(in) :: b2(..)

with the KIND value assumed from the actual argument.

But I think the idea is that it explicitly states that the compiler will be "instantiating" this at the call site by mangling the subroutine name internally. I think that's fine.

How would the interface of that procedure declare that the ranks of the dummy arguments were either identical or (for b2 and b3) scalar?

Good question. The DATA and GENERIC subgroups have been busy coming up with ways in declarations to say “same-{shape | type | class} -as” . As a practical matter, when the compiler attempts the instantiation you will get an error if the assignment or additions are not legal.

Cheers, Bill

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

Bill Long longb@hpe.com Engineer/Master , Fortran Technical Support & voice: 651-605-9024 Bioinformatics Software Development fax: 651-605-9143 Hewlett Packard Enterprise/ 2131 Lindau Lane/ Suite 1000/ Bloomington, MN 55425

certik commented 3 years ago

Good question. The DATA and GENERIC subgroups have been busy coming up with ways in declarations to say “same-{shape | type | class} -as” . As a practical matter, when the compiler attempts the instantiation you will get an error if the assignment or additions are not legal.

I want to bring an important distinction here:

At the generic subcommittee, we currently want to do "strong concepts", for the advantages stated above.

tclune commented 3 years ago

Good question. The DATA and GENERIC subgroups have been busy coming up with ways in declarations to say “same-{shape | type | class} -as” . As a practical matter, when the compiler attempts the instantiation you will get an error if the assignment or additions are not legal.

Even with the proposed implicit rank and kind, one would still need the new F202x syntax for any local variables that needed to vary in the same manner.

tclune commented 3 years ago

The syntax that @longb suggests in this thread is intriguing due to its simplicity. I'm fairly convinced that the approach is ultimately limited on several fronts. First, and perhaps foremost is the strong concepts concern that @certik raised. There is also the concern that Van Snyder raised in the J3 thread that it really does not address the issue of parameters for derived types.

It is possible that we end up wanting a bit of both. E.g., Magne Haveraaen has argued that real world complexities can be reduced if one allows parameters on methods (type-bound procedures) that extend the parameters of the type to which they are bound. Possibly the syntax suggested by @longb could be part of this broader approach. I had envisioned something a bit more explicit, and it is definitely too early to start debating the differences with any seriousness.

We need use cases, lots of use cases, with which variant approaches can be assessed. The big near-term challenge that I see is how to isolate, categorize, and ultimately prioritize "micro" use cases that are extracted from broader use cases. And at this point, the thread should really be on the generics sister project.

certik commented 3 years ago

I agree. Tom, you work on use cases, I am working on language comparisons, and I also volunteer to start a document that captures our discussions and how our ideas evolve, so that others can get up to speed quickly.

Let's use the generics repository from now on.

On Wed, Oct 21, 2020, at 7:30 AM, Tom Clune wrote:

The syntax that @longb https://github.com/longb suggests in this thread is intriguing due to its simplicity. I'm fairly convinced that the approach is ultimately limited on several fronts. First, and perhaps foremost is the strong concepts concern that @certik https://github.com/certik raised. There is also the concern that Van Snyder raised in the J3 thread that it really does not address the issue of parameters for derived types.

It is possible that we end up wanting a bit of both. E.g., Magne Haveraaen has argued that real world complexities can be reduced if one allows parameters on methods (type-bound procedures) that extend the parameters of the type to which they are bound. Possibly the syntax suggested by @longb https://github.com/longb could be part of this broader approach. I had envisioned something a bit more explicit, and it is definitely too early to start debating the differences with any seriousness.

We need use cases, lots of use cases, with which variant approaches can be assessed. The big near-term challenge that I see is how to isolate, categorize, and ultimately prioritize "micro" use cases that are extracted from broader use cases. And at this point, the thread should really be on the generics sister project.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/185#issuecomment-713575192, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAFAWFHCUFLISPD5PLRIZTSL3O7VANCNFSM4SNKWX4Q.

wclodius2 commented 3 years ago

Maybe what would be useful are RANKOF and SHAPEOF specifiers similar in spirit to the TYPEOF and CLASSOF specifiers of 202X.

longb commented 3 years ago

On Oct 22, 2020, at 10:45 PM, William B. Clodius notifications@github.com wrote:

Maybe what would be useful are RANKOF and SHAPEOF specifiers similar in spirit to the TYPEOF and CLASSOF specifiers of 202X.

There are already proposals for RANK and BOUNDS attributes. RANK confusingly has the same spelling as the RANK intrinsic, so instead of RANKOF(X) we now have RANK(RANK(X)), I think your proposed spellings are better.

Cheers, BIll

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

Bill Long longb@hpe.com Engineer/Master , Fortran Technical Support & voice: 651-605-9024 Bioinformatics Software Development fax: 651-605-9143 Hewlett Packard Enterprise/ 2131 Lindau Lane/ Suite 1000/ Bloomington, MN 55425