The beginning of a line of code often states a variable to which assignment is occurring. This means that once you know which variable has the wrong value, a quick scan down the left side of the code enables you to find where it is being assigned. Unfortunately inout functions spoil this: even though the ampersand in the function call should alert you to the fact that the variable is being altered, this will be somewhere over on the right side of the code rather than lined up beneath the assignee variables.
Conceptually a function has three gates: an in gate (the argument(s) which affect the function), an out gate (the return value or tuple of values which is affected by the function) and the inout gate (inout argument(s) which both affect the function and are affected by it). There is no good reason for the in gate and the inout gate to rub shoulders with each other, and I believe it has happened because computer functions were modelled after maths functions, which only have two gates.
I propose that inout arguments in function calls should optionally have their own argument list which appears in brackets before the function name. This would allow them to be stacked up on the left side of the screen beneath the assignments. This would be optional where the function is called, and would have no effect on the function definition. I believe that if all inout arguments were either separate on the left or mingling on the right, there should be no confusion: some inout arguments on the left while some were on the right would not be allowed.
Example:
Definition (unchanged):
func myFunction(inA:Int, ioB: inout Int, inC: Int, ioD: inout Int) -> Int
Existing style call (still to be allowed):
let result = myFunction(inA:43, ioB: &B, inC: 97, ioD: &D)
Trigate style call
let result =
(ioB: &B,
ioD: &D)myFunction(inA: 43, inC: 97)