@everythingfunctional The code you mentioned is very good and it indeed highlights an issue with Fortran, but I don’t think exceptions are the answer in this particular case:
pure function mean(vals)
real, intent(in) :: vals(:)
real :: mean
mean = sum(vals) / size(vals)
end function
Here what I personally would like is something like:
pure function mean(vals)
real, intent(in) :: vals(:)
require :: size(vals) > 0
real :: mean
mean = sum(vals) / size(vals)
end function
Then in Debug mode I get a beautiful runtime stacktrace if this condition is not satisfied. In Release mode this will not be checked and the result is undefined, but performance is high (no exceptions or other overhead). One can also consider a ReleaseSafe mode, where this check remains, for safety reasons, if that is what you need.
My workflow is that if I get an error in Debug mode here, I have to adjust the caller to ensure it never passes an empty array into this function.
In existing Fortran, you can define an ASSERT
macro to do something similar.
The feature that is missing are these pre conditions (contracts) for functions, automatically enforced by the compiler. See these two issues for further information and a proposal:
- Add assert statement to Fortran · Issue #70 · j3-fortran/fortran_proposals · GitHub
- https://github.com/j3-fortran/fortran_proposals/pull/177
Regarding:
While some overhead may be incurred by such a feature, it is not as much as would be incurred by any of the other mechanisms of error handling currently available to us.
I think the approach I showed above indeed has zero overhead in Release mode.