vvhitevvizard wrote: ↑15 Mar 2021, 07:49
Yeah. Those I've read. [...]
I was hoping u would provide me with some additional
rationale why is it so.
So why did you say
"the 2nd line behaves as if
isset declared a local uninitialized variable." and not
"the 2nd line behaves as if
&logger declared a local uninitialized variable.", hmm?
If you want the right answer,
ask the right question, don't just
hope for it.
The
rationale is complex and involves most of the changes presented in this topic, as they are interrelated. If
&var could default to taking a non-super global variable's reference without declaration, a number of things would not work as well as they do - you would not have any of the benefits of the new changes, as I would have left it as merely an experiment.
The use of
&var often makes it impossible for the parser to determine whether the variable is going to be assigned a value. Even if the parser could detect it in some cases,
simple rules are better; easier to implement and maintain, easier to explain, easier to understand.
The
primary use of
&var is to assign to the variable indirectly, usually by passing it to a function. Having them implicitly assign to (non-super)
global variables would introduce problems not present in previous versions.
IsSet is either one of very few exceptions, or the only exception (I can't think of any others at the moment). You "know" that
IsSet(&var) doesn't assign to var, but
maybe it does. As I said before, "IsSet is a function, and can be shadowed by a local variable or user defined function." Even if we assume that IsSet never assigns to the var, making this an exception for the "&var makes var local by default" rule would be harmful. It would add complication to the rules, which makes them harder to understand, and more bothersome to document and learn.
I know that it is not ideal to require a declaration just to check if a global variable is set, when reading its already-set value does not require declaration. As I said,
I will think about alternative solutions.
2. & operator is used in the expression ("right side"), its not an assignment ("left side") for that var, its a "read" operation, we just want to obtain an address of that var (pointer to that var).
If &var was an assignment, the documentation could say
... only read by the function, not assigned or used with the reference operator (&).
... However, if a variable is used in an assignment or with the reference operator (&), it is automatically local by default.
It says what it says because &var
is neither a read operation nor a write operation. You are not using or changing the variable's value.
You do not read a variable to obtain its address. In order to read a value, the program must know where it is.
kczx3 wrote:To me, it just seemed weird trying to get a ref to a variable that didn't exist.
That
would be weird, but that isn't happening. How do you check if a variable which doesn't exist is set? Asking the question "is this variable set?" implies that the variable exists (especially when you're doing it with a plain variable reference, not a name within a string). And in fact, it does. "In AutoHotkey, variables are created simply by using them." The v1 documentation says "Any non-dynamic reference to a variable
creates that variable the moment the script launches." This is actually
still relevant.
The
variable exists, but maybe the value doesn't.
vvhitevvizard wrote:In the future updates, do u plan to address Object.GetMethod("literal name") and other object methods syntax to additionally accept non-literal names by expression obj.method rendering it similar to function references syntax?
I had to read this several times to make any sense of it. "Non-literal names" are presumably names substituted with
%...%. There is no "function reference syntax";
(MsgBox) gives you a reference to a function, but this is just variable reference syntax.
I think what you are asking about (even if you didn't know it) is the use of
%...% to evaluate an expression, instead of just a variable name. No, I have no plan to address this. There might eventually be a capability like
eval() from other languages, but I doubt I would ever make
%...% shorthand for eval.
obj.method is not a "non-literal name". It is (in the right context) an expression, consisting of a variable reference and property name, with the type of operation depending on the context. For instance,
(obj.method) just retrieves a property, while
(obj.method()) calls it and
(obj.method := x) assigns it. If a sub-expression was placed inside a string and evaluated with
%...%, it would have to be done one of two ways:
- The sub-expression is parsed and evaluated independently, and the result is then used within the larger expression. Effectively, x := "obj.method", %x%() would be equivalent to (obj.method)(), which will fail if obj.method is actually a method, since this is omitted.
- The sub-expression is parsed within the context of the larger expression, which would require delaying parsing of at least part of the outer expression. For instance, %x%(1) could be obj.method(1), funcname(1), 1 + (1), -(1), etc. This would be complicated and not worthwhile.