I will not make parameters ByRef by default. Doing so would make it much harder, when looking at the code, to determine whether a variable passed to a function might be modified by that function. When a global variable is passed to a (ByRef) parameter, it is also possible for that parameter's value to unexpectedly change when the function calls some other function, or when the thread is interrupted. Parameters should act as local variables by default, allowing the function to be self-contained.
A lesser point to consider is that a function currently cannot pass its own local variable to a ByRef parameter in a recursive call to itself (whether called directly or via some other function). I do not expect this problem to be solved any time soon.
I have only rarely felt that the (sometimes non-existent) difference in performance justified the changed semantics of ByRef or the "ugliness" of declaring a parameter ByRef when the function isn't intended to modify it.
The performance cost of passing large strings to functions by value can be negated without changing the semantics of function calls - for instance, by using reference counted (or garbage collected) strings/buffers. ByRef gives the function a reference to a variable, not a reference to its value.
Flipeador wrote:In addition, the context in which I suggest the & is different from the others, so, as I said, there is no confusion at all. If you feel uneasy, you can always choose not to use it.
There is no confusion to you, because you know what it means. If a user feels uneasy, they can't choose for everyone else not to use it. (However, I can.)
I do not think an example is necessary.
I do not think it is necessary to implement your suggestion, or even to argue the reasons for not implementing it. I can simply choose not to do it.
ByRef is much clearer than
&, especially considering "pass variable by reference" and "pass variable's contents by address" are similar concepts. You want
¶m in a function definition to mean "param accept a variable reference", but when calling it,
¶m passes the address of a string, number or object, not a variable reference.
You're wrong, this is horrible and unclear.
"A_Field" or "A_Sp" would only have one meaning each, and users of v1 can probably guess what that is. By contrast,
& has never meant "accepts a variable by reference" in AutoHotkey before and there is little reason for anyone reading the code (who is not familiar with C++) to guess that it does so. It would have to be read about and memorized; something that's probably easier for A_Field and A_Sp. (But I'm not in favour of A_Field or A_Sp either.)
I idly considered allowing or requiring
ByRef,
ref or some currently-unused operator symbol in the function call instead of - or in addition to - the definition. It then becomes clear that a function
or method call may modify that variable, without looking at the function or method definition (which would depend on the object). Non-ByRef variable references within the parameter list could then resolve to their value at the time the parameter is evaluated, not at the time of the function/method call, as it is now. For instance,
n := 1, a.method(n, ++n) could produce the intuitive result
a.method(1, n := 2) instead of
a.method(2, n := 2). (This sort of thing is undefined behaviour in some languages, where order of parameters evaluation is not guaranteed.)