Agreed. This is very unfortunate. Not only for the desire of programming in a “functional” style, but for the use of pure functions in general. With the current set of language features pure functions can realistically only be infallible.
What Fortran really would benefit from is support for rich enumerations or tagged unions. Then one could write functions that either return a value (with a specified type) or an error (with another specified type). This should preferably be combined with good generics support to avoid boilerplate code.
The best workaround I can think of today is to define a type, e.g.
type :: result_int_t
character(len=:), allocatable :: error
integer, allocatable :: value
end type
and then only allocate one of the members depending whether the function failed or succeeded, for example:
type(result_int_t) pure function foo(i) result(res)
integer, intent(in) :: i
if (i > 42) then
res%error = 'For some reason this is not ok'
else
res%value = i + 2
end if
end function
I think this is similar to what @samharrison7 proposed in a previous post.