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

Constant Expression Value Arguments for Generic Resolution #320

Open
everythingfunctional opened this issue Nov 1, 2023 · 11 comments
Open

Comments

@everythingfunctional
Copy link
Member

everythingfunctional commented Nov 1, 2023

It has so far been impossible to write user defined functions that can mimic the behavior of various intrinsic functions. I.e.

function real(A, KIND)
  real, intent(in) :: A
  integer, intent(in) :: KIND
  real(KIND) :: real
end function

But if we had some mechanism to define a constant expression value that must be one of the arguments we could do it. I.e. some suggestive syntax

interface real
  module function str_to_real128(A, KIND, STAT)
    character(len=*), intent(in) :: A
    integer, parameter, intent(in) :: KIND = real128
    integer, intent(out), optional :: STAT
    real(real128) :: str_to_real128
  end function
  ...
end interface
...
real(real128) :: my_val
my_val = real("1.234", KIND=real128)
@certik
Copy link
Member

certik commented Nov 1, 2023

Nice idea. I modified your example to say interface str instead of interface real, since I think that's what you meant.

@everythingfunctional
Copy link
Member Author

Actually I did mean real. The example is intending to extend the real intrinsic to work for converting strings to real numbers.

@jacobwilliams
Copy link

Same as #91 I think?

@everythingfunctional
Copy link
Member Author

Same as #91 I think?

Very similar, yes, but I think the solution I propose is different.

@certik
Copy link
Member

certik commented Nov 1, 2023

@everythingfunctional I see --- you had there "str" in the function call, but "real" as the interface. Everything is clear now after your edit.

@shahmoradi
Copy link

A mechanism like the optional kind type parameter (with kind attribute) of parameterized derived types would be ideal. So instead of

integer, parameter, intent(in) :: KIND = real128

we'd write,

integer, kind :: kind = real128

similar to PDTs.
I have so far bypassed this issue by introducing a like dummy argument for type resolution. But then one has to live with endless compiler warnings about unused dummy arguments and, more importantly, an interface inconsistent with intrinsic procedures of the same name and functionality. There is a clear need for this facility in the language from a user's perspective.

@everythingfunctional
Copy link
Member Author

My idea was more along the lines of that argument being required and required to have the given value (so the compiler can actually do the code generation), but it can then be used for generic resolution. This is a bit with an eye towards one of the generics features being worked on so you could do something like:

generic function real(A, KIND, STAT)
  use iso_fortran_env, only: real_kinds
  character(len=*, kind=*), intent(in) :: A
  integer, parameter, intent(in) :: KIND = real_kinds
  integer(*), intent(out), optional :: STAT
  real(KIND) :: real
  ...
end function
generic function real(A, STAT)
  character(len=*, kind=*), intent(in) :: A
  integer(*), intent(out), optional :: STAT
  real :: real
  real = real(A, kind(real), STAT)
end function

You could also use a feature like this to disambiguate between allocatable or not like a bunch of people seem to want to lately. I.e.

interface foo
  module subroutine foo_alloc(A, WHICH)
    integer, allocatable, intent(inout) :: A(:)
    character(len=*), parameter, intent(in) :: WHICH = "allocatable"
  end subroutine
  module subroutine foo_static(A, WHICH)
    integer, intent(inout) :: A(:)
    character(len=*), parameter, intent(in) :: WHICH = "static"
  end subroutine
end interface
integer, allocatable :: x(:)
call foo(x, "allocatable")

@FortranFan
Copy link
Member

..
interface real
module function str_to_real128(A, KIND, STAT)
character(len=*), intent(in) :: A
integer, parameter, intent(in) :: KIND = real128
integer, intent(out), optional :: STAT
real(real128) :: str_to_real128
..

A typo here? Was the following that was meant?

..
 real(KIND) :: str_to_real128
..

@everythingfunctional
Copy link
Member Author

Given my idea, and that interface, they're equivalent.

@FortranFan
Copy link
Member

So instead of

integer, parameter, intent(in) :: KIND = real128

we'd write,

integer, kind :: kind = real128

Agree totally.

The clause (or call it an attribute if one prefer) of , KIND implies compile-time semantics for the processor. The , parameter doesn't jive with what is in the language since the 2003 revision.

@KHUSHIJAIN910

This comment was marked as spam.

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

6 participants