j3-fortran / fortran_proposals

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

Function kind specified by optional input #91

Open jacobwilliams opened 5 years ago

jacobwilliams commented 5 years ago

I want to be able to define a function that behaves like, for example, the intrinsic SIZE function, where the kind of the output is specified by an optional input. Am I correct that this currently isn't possible?

Maybe using something similar to @cmacmackin's parameterized function syntax from #4, combined with a better way to specify the default value of optional arguments (see also #22):

function my_class_size(me, kind=INT32) result(s)
class(my_class) :: me
integer,intent(in),optional,kind :: kind  
integer(kind) :: s 
...
end function my_class_size

See also #78, and also the various issues about generic programming and templates.

FortranFan commented 5 years ago

@jacobwilliams wrote:

I want to be able to define a function that behaves like, for example, the intrinsic SIZE function, where the kind of the output is specified by an optional input. Am I correct that this currently isn't possible? ..

The specific example with 'my_class_size' function above is not feasible since KINDs need to be known at compile time. However, based on further description of the need, it may be possible to workaround it by designing the 'my_class' as a parameterized derived type.

Anyways, the need "I want to be able to define a function that behaves like, for example, the intrinsic SIZE function" is yet another instance where the Fortran standard makes certain allowances for intrinsic procedures (generic like ABS, FINDLOC, etc; variadic like MAX, MIN) and intrinsic types that are inextensible, single-component like C_PTR, etc. but does not extend the same courtesy for user procedures and types

This really comes to 'bite' because the committee refuses to include certain intrinsic 'classes' (a la what other languages now already have e.g., C++ in STL with std::string, std::vector, std::variant) that are so badly needed in the language but then there is extreme recalcitrance to offer to coders all the tools and mechanisms they need to build their own such 'classes'.

ivan-pi commented 3 years ago

I have stumbled into this a few times already. The last time was in a discussion of extending the intrinsic character functions like verify and scan to a custom string type (see https://github.com/fortran-lang/stdlib/issues/321).

Allowing a mechanism to allow a kind attribute in functions would make it much more convenient to use custom derived types (floats, strings) or types supporting automatic differentation (see #95), by allowing to overload all the intrinsic functions which have such an optional kind argument.

For a specific example say I want to use a derived type designed to emulate quadruple precision (106 bits of significand) using two doubles (also known as double-double arithmetic) or potentially the more ambitious quad-double (unevaluated sum of 4 doubles):

  type :: dd_real
    real(dp) :: x, y = 0.0d0
  end type

To allow easily porting code from double to double-double, I would like to overload the real(a [,kind]) function, to cast down to a standard real value (say for output):

pure function real(a,kind) result(y)
  type(dd_real), intent(in) :: a
  integer, kind, optional :: kind
  real(kind=kind) :: y
  block
    intrinsic :: real
    y = real(a%x,kind=kind)
  end block
end function

If no optional argument is present, then kind should resolve to the default type (and not a null pointer). Maybe this is something which could be pursued in connection to issue #22 (default value for optional arguments) and the related proposal #175. In that case, the default real kind could be set using

integer, kind, default(kind(1.0)) :: kind

Is there any way to find out if any related proposals have been discussed previously, and if yes, why were they rejected?

cc @certik @milancurcic @wclodius2 @sblionel

sblionel commented 3 years ago

@ivan-pi , I don't recall ever seeing a proposal along these lines. It's an interesting idea.

certik commented 3 years ago

I think this proposal is very similar to #128.

jacobwilliams commented 3 years ago

Similar, but not the same. size returns an integer, but can be passed in any type. So there isn't an integer input to get the kind from. That's the kind of function I want to be able to write. There are couple other intrinsic functions that are not possible for a user to write (max is another example)...see my other proposal at #76.