Hej everyone,
I have a syntax convention question. Take the Julia
syntax convention as an example.
Consider an arbitrary function. The convention in Julia is y = foo(x)
does not do pre-allocate y
, while foo!(y, x)
pre-allocates the y
array and modifies it in-place.
What I’m currently using in Fortran
is:
y = foo(x) ! No preallocation version.
and
call foo_ip(y, x) ! Array y is pre-allocated.
The _ip
stands for in-place. I was wondering though if there is such a syntax convention in Fortran
. I kind of recall this was discussed at some point but I’ve been unable to find the corresponding thread.
1 Like
If Y is allocatable but you have already allocated it to the desired size and you are populating it via a function using
y(:)=f(x)
instead of
y=f(x)
might be adequate for most circumstances. If you are partially filling Y with an unknown number of replacements at the point of the call or want to do bounds checks and so on a subroutine interface
has many advantages in efficiency and flexibility in general; but function syntax is typically more compact and clear in my opinion but if the only reason you have to create two interfaces is to control whether Y is open to being reallocated and/or have its size changed that might be all you need.
I used a simple function
as example, but what I really had in mind was a more complex subroutine
where multiple returns arguments may or may not be modified in-place.
Everything below is opinion.
The syntax convention should be that procedures that mutate their arguments be written as subroutines, not functions. A strength of Fortran is that it distinguishes between functions and subroutines, rather than just having functions that may or may not return something, or may or may not mutate their arguments, as in other languages. You don’t need an _ip
suffix in the name of a subroutine, because the reader should be assuming that any arguments can be modified, unless they are declared intent(in)
within the subroutine. You could name arguments in a way that indicates whether they are inputs, outputs, or both and used named arguments instead of positional ones. I suggest that the order of subroutine arguments be required arguments before optional arguments, and within the required arguments that inputs be placed before outputs. If I have a call statement with many arguments, I sometimes document the outputs in the same line to clarify what is being changed, for example
call circle(radius, circumference, area) ! output: circumference, area
2 Likes
I use this convention and go a bit further by using two spaces between inputs and outputs in both the calls and in the subroutines. This makes the code easier to read.