Page 1 of 1

[V2.0.3:] An unintentional inconsistence between f(1) and f(1,unset)

Posted: 13 Jul 2023, 12:09
by V2User
Is there any proper reason that f(1) and f(1,unsset) should return different result?
In my general opinion, despite what function it is, f(1) should be unconditionally the same with f(1,unset).
Just as ob:={p1:7},ob.p1:=unset will delete the property, therefore a[length]=unset should automatically pop the last element too.
Code:

Code: Select all

f(a*)=>a.Length
OutputDebug(f(1))       ;return 1
OutputDebug(f(1,unset)) ;return 2
@Lexicos I am quite sure this result is out of your original intention. Isn't it?

Re: [V2.0.3:] An unintentional inconsistence between f(1) and f(1,unset)

Posted: 13 Jul 2023, 16:23
by iseahound
Yes, the general approach is that unset is something that happens, rather than a value to be passed null. So passing f(1,unset) should be the same as passing a single parameter f(1).

Code: Select all

unset → 0 parameters passed
p? → 0 or 1 parameters passed
p* → 0 to infinite parameters passed
Also it is @lexikos

Re: [V2.0.3:] An unintentional inconsistence between f(1) and f(1,unset)

Posted: 14 Jul 2023, 02:48
by lexikos
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.

Re: [V2.0.3:] An unintentional inconsistence between f(1) and f(1,unset)

Posted: 14 Jul 2023, 04:57
by V2User
lexikos wrote:
14 Jul 2023, 02:48
This isn't an array literal, but it intentionally behaves the same as one.
Since you already did similar things to normal functions in v2 RC.2, thereafter array literals will no longer behave as function parameters.
viewtopic.php?f=24&t=110696#:~:text=Fixed%20trailing%20unset,count%20toward%20MaxParams.
In f2(a)=>0, f2([1,unset]*) is permited and behaves the same as f2(1) after RC.2. Maybe you would make the same apply to f(1,unset) and f(1) too, for variadic functions.

Re: [V2.0.3:] An unintentional inconsistence between f(1) and f(1,unset)

Posted: 14 Jul 2023, 10:28
by iseahound
I think you are confusing the role of a* in f(a*)=>a.Length. This asks the function to collect all the parameters into an array a.

An array can have missing parameters, such as [1, , 3] where 2 is missing and the length is 3.

I think a better solution would be to "trim" the array on each end to remove the missing unset values, and perhaps a method can be designed to do so.

Re: [V2.0.3:] An unintentional inconsistence between f(1) and f(1,unset)

Posted: 14 Jul 2023, 21:22
by lexikos
For functions with formally defined parameters, unset behaviour is based on the formal parameter definitions. Variadic parameters, which have no formal definition and are placed in an array, behave as array elements. I have heard no compelling reasons to change this behaviour. In any case, the behaviour is neither unintentional nor contrary to the documentation; it is not a bug.