-
Notifications
You must be signed in to change notification settings - Fork 17
Variadic functions #76
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
Comments
Can you describe what this is? I've been programming since 2006 and never heard of these until now. I understand now because I Googled it, but we shouldn't have to Google stuff proposed here. An example would go a long way. Now for my view on this idea: I use it occasionally in Python via |
If I'm using the term correctly, I just meant a function that has an unknown number of arguments. It's not entirely unknown to Fortran, since the intrinsic a = max(1,2)
a = max(1,2,3)
a = max(1,2,3,4,.....etc) But, we have no ability to write routines like this ourselves. |
Interesting, I had no idea I could use |
I didn't know that either. |
The use of MIN/MAX with more than two arguments goes all the way back to the original Fortran compiler for the IBM 704, although the names of the functions were different. |
For example, function HYPOT(x,y) has just two arguments while it could have more. By the way, does any know what was the reason for introducing this as intrinsic function in F2008? Do some architectures provide hardware implementation for this? As for variadic functions, Python handles such arguments to the function as list. For example: def hypot(*p):
import math
return math.sqrt(sum([x**2 for x in p]))
print(hypot(1))
print(hypot(3,4))
print(hypot(1,4,8)) I am guessing in Fortran the issue would be how to implement that without the performance hit of unnecesary construction of a temporary array. |
Ok, a quick google search revealed the answer. Please ignore the first paragraph of my last post. :) |
Maybe useful, indeed, but the interaction of those arguments with the usual Some cases can be handled by using arrays instead, like Is there a showcase, where anyone can demonstrate the necessity of variadic routines and show, that it would be impossible or very inconvenient to implement the same functionality using arrays and/or optional arguments? Otherwise, it would be quite difficult to argue for a non-trivial language extension. |
There have been several times that this would have been useful for me, I have code at the moment that looks like: class(*), intent(in), optional, target :: a1,a2,a3,a4,a5,a6,a7,a8,a9,a10
...
if (present(a1)) then
call someFunction(i0+0,a1)
end if
if (present(a2)) then
call someFunction(i0+1,a2)
end if
if (present(a3)) then
call someFunction(i0+2,a3)
end if
et cetera... Not impossible to implement, but inconvenient and limiting, since there is necessarily a finite number of optionals. |
OK, I see. Further question would be, how one ensures type safety? Does one request all variadic arguments to have the same type/rank? Or should a routine iterating over the arguments return |
I think yes, similarly to almost all intrinsic subroutines having to have
arguments of the same type and kind. Everything else would be a mess. 😉
pon., 11 lis 2019, 12:39 użytkownik Bálint Aradi <[email protected]>
napisał:
… OK, I see. Further question would be, how one ensures type safety? Does
one request all variadic arguments to have the same type/rank? Or should a
routine iterating over the arguments return type(*)/rank(..) objects?
Latter would be more flexible, but then type and rank checking would be
shifted to run-time instead of done at compile time. (And you would have to
embed the evaluation of the arguments into select type and select rank
constructs, which does not make it very convenient to use...)
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#76?email_source=notifications&email_token=AC4NA3M6L6UKE2UKFU774MTQTE75ZA5CNFSM4JLJDHZKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDWRSWA#issuecomment-552409432>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AC4NA3MC7JQOG3V6YLLATHTQTE75ZANCNFSM4JLJDHZA>
.
|
I've been thinking about this a bit and come up with an idea of how the syntax could work, loosely inspired by how C handles variadic arguments. A procedure without any optional arguments could have zero or one argument with the attribute function get_variadic_count()
integer :: get_variadic_count
end function
subroutine get_variadic_argument(number, value, status)
integer, intent(in) :: number
type(*), dimension(..), intent(out) :: value
integer, intent(out), optional :: status
end subroutine As an example, I'll show how these could be used for an implementation of function array_max(arrays)
integer, dimension(:), intent(in), variadic :: arrays
integer :: array_max
integer :: i, j, n
n = get_variadic_count()
do i = 1, n
call get_variadic_argument(i, arrays)
if ( i == 1) array_max = arrays(1)
do j = 1, size(arrays)
if (arrays(j) > array_max) array_max = arrays(j)
end do
end do
end function array_max The advantage of can see of this is that the |
@cmacmackin Just for clarification and make sure I understand your proposal correctly. Did you mean
on line 10 in the 2nd example? |
@cmacmackin I like your approach a lot. Just a minor remark. The interface you specify won't work with your example, as the dummy argument type |
Ah yes, thanks for catching those. I'll update the code fragments accordingly. |
62 years later, FORTRAN doesn't cease to impress me! |
I think, the calling of such a routine with named arguments needs also some thoughts. Given the variadic routine
which of the following calls should be valid:
|
From what I understand, currently the keywords argument must come after all positional arguments. So I think vararg must be restricted that it always comes as a positional argument or things can get very very messy. I feel it might be actually quite difficult to design it in a good way that will not cause confusion. |
Currently, having
the calls
are valid. If varargs must be positional arguments, then basically this would invalidate keyword-like arguments in the call of such a routine. Unless, one allows for multiple occurancies of a given keyword if it belongs to the vararg:
I think, this would be the most compatible with the way how kewyord arguments work in Fortran now. |
I was thinking that would be the tidiest solution. |
Keep in mind how the intrinsic procedures are set up: From 16.9 Specifications of the standard intrinsic procedures of the standard:
Note the following:
outputs 4. Consistency with how intrinsic procedures are specified as being ELEMENTAL and being able to accept any number of dummy arguments of the same type such as MAX, MIN, .. work with argument names of Now these intrinsic procedures only accept intrinsic types of course (usually integer, real, or character) but I think it'll be useful if such user procedures can accept dummy arguments which are derived types of the same declared type. |
This would have been useful for me in the past is when writing N different subroutines to print N different column vectors. With support for variadic arguments I imagine it would be possible to have a single subroutine |
@FortranFan You are right, then we should allow for enumerating the varargs in the call to be similar to already existing intrinsic functions:
|
FYI: here's another example where this would be handy: https://github.com/urbanjost/M_msg/blob/master/src/M_msg.f90 |
Has this even been discussed? Some other languages have it. Why not Fortran?
The text was updated successfully, but these errors were encountered: