Helgef wrote:It looks like can be an expression changed to sometimes must be an expression,
What do you mean? SendMessage's entire parameter list is an expression (or sub-expression).
It just introduces an unecessary exception to normal use of built in functions.
Regardless of what we do, SendMessage is necessarily
an exception, because (like DllCall) it interfaces with an external system which does not allow type information to be carried across. In other words, unlike every other built-in function, we have no control over how the callee interprets the parameters. If we pass a string "123" by address to a message which expects a number, it will see not the value "123", but some arbitrary address. This is not how a normal built-in function acts.
No one should be surprised that you can't pass a literal string to SendMessage (as a string) if they read the documentation
for the message, and it says "A pointer
to a null-terminated string [...]." Parameters of official messages are always documented this way, because they are documented for C. In C, one has to perform a typecast to pass a pointer as WPARAM/LPARAM (a numeric
SendMessage's parameters are variable type, but unlike native AutoHotkey functions, we don't know what type the parameters should be. So the options are:
- assume the type of the value shows the author's intent (not necessarily true, even for me)
- require the type to be specified (if you want to do that, you can use DllCall)
- let the parameter always be integer
Message parameters are nearly always
numbers. The third option improves reliability/ease of use for the most common scripts, at the expense of a minor convenience in some very small percent of cases. Although I don't agree with half of what jeeswg says, I agree that treating numeric strings and pure numbers differently can cause issues. I personally ran into such issues with objects repeatedly, until I changed objects to treat key "1" as 1, etc. It's not a matter of the problem being easy or hard to debug, but of having too little reason to allow it to be a problem in the first place. Stricter languages which differentiate between types generally do so more consistently and/or have better tools to prevent these issues.
(For NumPut/NumGet, it seems far less likely that an address
will come from a string, or that one would want to put into/get from the numeric component of a variable when one can simply perform an assignment. Likewise for RawRead/RawWrite; if you want to read into or write a variable which holds a pure integer, there's no good reason to use the Raw methods over ReadInt/WriteInt.)
In v1, scripts were already required to use the address operator for variables' content, but SendMessage cheated a bit and "introspected" the code to find the variable to update (even though the variable itself wasn't passed to the command).
If XXXmessage , "num" or XXXmessage , varContainingNumericStr had thrown an exception, it would make more sense.
Why? Wouldn't that be "an unecessary [sic] exception to normal use of built in functions"?
jeeswg wrote:In this example, we see the normal behaviour for parameters that expect 'numbers' (numeric content)
I'll point out, again
, that SendMessage (in Win32, decoupled from the artificial restrictions of C) does not "expect numbers". It expects values of varying type, depending on the message.