- I can predefine if an array / variable is intended as input, output or both, simply with `intent(in)`, `intent(out)` etc.
- compiler can thus do checks for me if I'm breaking a contract.
- yet, since I pass by ref, I don't have to worry about memory not being used efficiently. This really matters once you deal with GB, TB or even PB worth of data going into a simulation over time - there's just no way to deal with that in a purely functional way.
- only where really necessary, you can still drop down to pointer semantics, e.g. for the outer glue code of a simulation that swaps outputs and inputs for the next time step.
- having `restrict`-by-default semantics here helps immensely. Imagine you have many arrays with lots of data to deal with, and your kernels access always several at a time to do calculations. In Fortran I can write it intuitively, while in C/C++ I must remember to specify `restrict` or to preload all point-inputs first into separate variables to direct the compiler. Otherwise the memory pressure increases, and by far most such physics simulations are memory bandwidth bound - every access counts.
* finally, a clean symbol definition system that decouples types from byte lengths. a `float` in fortran is just `real(4)`, a double is `real(8)`, a long int is `integer(8)` and so on. now, it's trivial to do a bit of preprocessing to switch the precision.