[2.1 alpha8] Question re Array.Pop() and unset?
Posted: 29 Dec 2023, 09:11
by sirksel
In the following code:
Code: Select all
a := [10,,30]
b := [20,,40]
c := [30,,]
d := [,,5]
a.Default := 99
a3 := a.Pop(), a2 := a.Pop()
b3 := b.Pop(), b2 := b.Pop()
MsgBox(''
. 'a2 is set: ' IsSet(a2) '`n' ; 1
. 'a2 type: ' type(a2) '`n' ; String
. 'a2 val: ' a2 '`n' ; ''
. 'b2 is set: ' IsSet(b2) '`n' ; 1
. 'b2 type: ' type(b2) '`n' ; String
. 'b2 val: ' b2 '`n' ; ''
. 'c length: ' c.Length '`n' ; 1
. 'd length: ' d.Length '`n' ; 3
)
Should a2 be 99 rather than ''? Should b2 be unset or some kind of error?
I'm less clear about this one, but should c.Length be 3, or are all final "unset values" always dropped?
Re: [2.1 alpha8] Question re Array.Pop() and unset?
Posted: 29 Dec 2023, 13:02
by iPhilip
sirksel wrote: ↑29 Dec 2023, 09:11
Should a2 be 99 rather than ''?
No. The documentation for the
Default property states:
The
Pop method is not part of the methods that use the
Default property value.
sirksel wrote: ↑29 Dec 2023, 09:11
Should b2 be unset or some kind of error?
The documentation for the
Pop method is unclear about what happens when the last array value is unset. In my opinion, the behavior is inconsistent. For example, this returns 1:
It's as if the unset element is skipped. This, on the other hand, returns a blank:
Code: Select all
z := [1,,2]
z.Pop()
MsgBox z.Pop() ; Blank
sirksel wrote: ↑29 Dec 2023, 09:11
I'm less clear about this one, but should c.Length be 3, or are all final "unset values" always dropped?
Here too the documentation is not clear. It seems that the
Length property ignores any "trailing" unset elements. Again, the behavior appears to be inconsistent. For example this returns 1:
but this returns 3:
Code: Select all
z := [1]
z.Length := 3
MsgBox z.Length ; 3
Re: [2.1 alpha8] Question re Array.Pop() and unset?
Posted: 29 Dec 2023, 16:26
by sirksel
It seems to me that pop is expected to be a combination of (1) removing and (2) returning the rightmost element. The removal seems like it happens correctly, whether the element is set or unset. It's the blank return that's odd and undocumented. I think, as I'm remembering now, array item access returning unset (so it can be used with ? and ??, rather than throwing UnsetItemError), might be something already planned? I'm not finding the right thread where it was discussed however.
The following is more of an opinion than a bug report, I guess... After living/using/loving the unset/maybe world for a while now, it seems to me like it might be more consistent if .Default applied wherever an unset Array item's value is accessed. This would include get and __Item, but it would also include __Enum and the return values on popping an unset, as well as single-item Delete/RemoveAt. Am I forgetting others? Currently __Enum actually leaves the value variable unset rather than throwing UnsetItemError, which, at least for me, is the more useful behavior, since using ?? is simpler than catching the error.
It almost seems like UnsetItemError should only occur when one tries to inappropriately assign/pass/use (but not simply access) an unset item (in other words, without the var? notation). This universalizes the opportunity to quickly handle the unset case with ?? without trapping UnsetItemError. In this hypothetical world, (1) if you define .Default, it would never be necessary to ??/catch an unset item, and (2) if you didn't define .Default, then ?? would be available in every place an unset item might be accessed, for easy handling without any inconsistency.
That's obviously just my opinion, and it may be irrelevant, since it would require a potentially breaking change. Maybe if something about array access is in fact in the roadmap, @lexikos might still be considering options? Even as it is, unset is much better than it was before, and the wonderful flexibility of the language makes for easy workarounds for whatever behavior is required. Thanks for all the hard work on this!
Re: [2.1 alpha8] Question re Array.Pop() and unset?
Posted: 18 Jan 2024, 23:13
by lexikos
iPhilip wrote:It seems that the Length property ignores any "trailing" unset elements.
Such elements are not "ignored"; rather, they do not exist in the first place, because they were never added to the array.
Trailing commas are ignored at the syntax level. However, it
is possible for an array to contain trailing unset elements: by explicitly setting Length, by using
unset, or perhaps by other means.
Unlike trailing commas, which are ignored when the parameter list is enclosed in parentheses, a trailing
unset parameter would be included in the length of the parameter list. For example, Array(unset) produces an array with a length of 1.
Source: Scripting Language | AutoHotkey v2 (alpha)
This also applies to v2.0, but was added while I was revising related documentation to account for changes in v2.1, so is not currently in the v2.0 documentation.
I'm intending to revisit the possibility of unset return values in various places before the release of v2.1.
sirksel wrote:it seems to me like it might be more consistent if .Default applied wherever an unset Array item's value is accessed.
Noted.
Re: [2.1 alpha8] Question re Array.Pop() and unset?
Posted: 19 Jan 2024, 03:12
by iPhilip
lexikos wrote: ↑18 Jan 2024, 23:13
sirksel wrote:It seems that the Length property ignores any "trailing" unset elements.
I will take responsibility for that statement.
lexikos wrote: ↑18 Jan 2024, 23:13
Trailing commas are ignored at the syntax level. However, it
is possible for an array to contain trailing unset elements: by explicitly setting Length, by using
unset, or perhaps by other means.
Unlike trailing commas, which are ignored when the parameter list is enclosed in parentheses, a trailing
unset parameter would be included in the length of the parameter list. For example, Array(unset) produces an array with a length of 1.
Source: Scripting Language | AutoHotkey v2 (alpha)
This also applies to v2.0, but was added while I was revising related documentation to account for changes in v2.1, so is not currently in the v2.0 documentation.
Thank you for clarifying that. It helps.