Perhaps I was not clear: I do not recommend the option in that other thread. Given that I do not recommend it, I didn't care to say whether I agree or disagree with your assessment of that option. In the first place, I only posted it to show that it is possible to determine without ambiguity whether an optional ByRef parameter defaulted.
The paragraph you quoted does not relate to the option in the other thread at all. That is why it is a separate paragraph.
Of course it also tells us that y won't be modified
This is clearly a false assumption. Even putting aside VarRef, objects can be mutated without ByRef. Furthermore, the caller has to know what the parameters are for and what to pass, whether that may be a VarRef or a value. If the caller is passing a VarRef, the possibility that it could be assigned a value is obvious. If the caller is not passing a VarRef, they are using the function incorrectly.
My argument against the value of
& as self-documenting is the same as the argument I gave in the other topic against the value of the automatic type-checking that it provides. Parameters which accept VarRef are only a fraction of all function parameters. Every other parameter type must be validated manually and documented separately. The self-documenting and self-validating properties of ByRef are just nice side-effects, not the purpose of the syntax.
Anyway, I didn't previously consider that you would consider the absence of
& in the parameter definition as such a problem for clarity, but I still disagree. Aren't non-ByRef parameters cryptic and obfuscating, because they don't have any declarative syntax to show what the parameter accepts? It could be absolutely
Anything.
In practical terms, I don't believe for a second that having or not having
& visible in the parameter list makes a significant difference for the usability of the function.
For self-documenting and self-validating parameters, type annotations are a more generally applicable solution which I have considered. The
name : type syntax which is used for typed properties could also be used for this.
... if not then it shouldn't be modified.
A variable can't be modified
if you don't pass a reference. You have to pass a reference for the function to work.
Whether you declare the parameter ByRef or not, if you pass a VarRef, there is no guarantee that it will or will not be assigned a value. Clearly, user-defined functions aren't required to assign to a ByRef parameter and can use it for input/output, or just input (e.g. avoiding the copying of large strings). Using the
& operator on a
& parameter produces the original VarRef, so the parameter can even be used just for validation, with the VarRef itself never being dereferenced, only being stored for later use or returned to the caller (e.g.
AssertIsRef(&r) => &r).
... but all built-in methods suggest that it exists.
I think you are conflating the recent use of
& in the documentation with the age-old
OutputVar convention, which is indicated by the parameter name and further documentation. There's also DllCall, which allows the use of VarRefs for input and output.
But what I would like is for both the function definition and the body of the function to be as self-explanatory as possible
What is
x supposed to be? Use descriptive parameter and function names! And comments!
If the reference to the object would have a property or method to access the same information then I have no qualms about that
No, it would not. As I said, you want information about a
function call, not about the function. There can be multiple calls to a function active at any given time. Although you would presumably want to know about the "top-most" one, attaching this information to the function itself is semantically unsound. On the more practical side, it assumes that multi-threading (or lesser substitutes like coroutines) will never be possible.
Doesn't seem to be too necessary (using objects largely gets the same result),
I was addressing the idea of "a function that late-converts the y in f(y?) to an alias", which is literally the same thing as a ByRef parameter, but with the VarRef being provided mid-function rather than as a parameter value. I don't disagree about this
syntax sugar being unnecessary - so is ByRef - but that is beside the point.
Already in the current alpha, a ByRef parameter can be bound not only to a variable/property/array element, but to a pair of getter/setter functions (via a
virtual reference). In the same way that built-in variables like
A_TickCount are dynamic, a ByRef parameter can calculate its value on-demand or perform some action when assigned. That could be extended to any variable (although statically defining
Name => Expression might be better for some use cases). Sure, you can just call functions directly, but would you want to replace all of the built-in variables with functions? Maybe you would.