Within a function call, array literal or object literal, the keyword unset can be used to explicitly omit the parameter or value. An unset expression has one of the following effects:
- For a user-defined function, the parameter's default value is used.
- For a built-in function, the parameter is considered to have been omitted.
- For an array literal such as [var?], the element is included in the array's length but is given no value.
- For an object literal such as {x: y?}, the property is not assigned.
The unset keyword can also be used in a function definition to indicate that a parameter is optional but has no default value. When the function executes, the local variable corresponding to that parameter will have no value if the parameter was omitted.
Source: Scripting Language | AutoHotkey v2
The first case does not apply, as there is no parameter, and no default value. The special case at the bottom does not apply, because the parameter is not defined and therefore has no corresponding variable. However, it is similar: the array element exists, but has no value.
This isn't an array literal, but it intentionally behaves the same as one. How else would you replicate the behaviour of
[unset] with a function?
When a variadic function is called, surplus parameters can be accessed via an object which is stored in the function's final parameter. The first surplus parameter is at params[1], the second at params[2] and so on. As it is an array, params.Length can be used to determine the number of parameters.
Source: Functions - Definition & Usage | AutoHotkey v2
a.Length is telling you that for
f(1, unset) there are 2 parameters, and
a.Has(2) will tell you that the second parameter has no value.
As the one writing a variadic function, if you strictly want it to consider a parameter to be "specified" if it has a value and "omitted" otherwise, you should not be consulting Length for that purpose in the first place.
f(1, , 3) will produce a Length of 3, but the second parameter has no value.