Select a part of a function's result

I was inspired by @rouson et al.‘s paper on “Julienne” for this little program. It shows how you can select a part of the result of a function without first explicitly storing it. You cannot do:

x = func_returning_array(n,m)(1)

where the function returns an array of data (or a derived type of which you only need a small part). But what you can do is this:


program select_array
implicit none

integer :: n

n = 10

associate( f => get_series(n) )
    write(*,*) f(1), f(size(f))
end associate

contains
function get_series( n ) result(series)
integer, intent(in)  :: n
integer, allocatable :: series(


integer              :: i

series = [(i, i = 1,n)]

end function get_series
end program select_array

The ASSOCIATE construct lets you access the function’s result as if it was a regular array, stored in a separate variable.

Whether this is useful except in special cases, I do not know, but it was amusing enough :innocent: .

5 Likes

The associate construct works as if you are making a subroutine call where f is the dummy argument associated with the actual argument get_series(n) evaluated as an expression. So the compiler is evaluating that expression and making a temporary copy for you. That temporary copy dissappears after the end of the block, just like a dummy argument disappears after the procedure returns. I think the same thing could be done with a block statement with the declaration integer :: f(n). I’m not sure if the allocatable attribute is required (in either the procedure or the block) – maybe the temporary array is in the heap with it but on the stack without it?

The allocatable attribute is there only to make it possible to return an array of varying size, it could indeed be done simpler, using an automatic array. But what I found enlightening is that you do not need to epxlicitly store the function’s result to get at parts of that result.