[2.1 alpha8] Question re Array.Pop() and unset?

Report problems with documented functionality
sirksel
Posts: 222
Joined: 12 Nov 2013, 23:48

[2.1 alpha8] Question re Array.Pop() and unset?

29 Dec 2023, 09:11

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?
iPhilip
Posts: 823
Joined: 02 Oct 2013, 12:21

Re: [2.1 alpha8] Question re Array.Pop() and unset?

29 Dec 2023, 13:02

sirksel wrote:
29 Dec 2023, 09:11
Should a2 be 99 rather than ''?
No. The documentation for the Default property states:
https://www.autohotkey.com/docs/v2/lib/Array.htm#Default wrote:If defined, its value is returned by __Item or Get if the requested element has no value, instead of throwing an UnsetItemError.
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:

Code: Select all

z := [1,]
MsgBox z.Pop()  ; 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:

Code: Select all

z := [1,,]
MsgBox z.Length  ; 1
but this returns 3:

Code: Select all

z := [1]
z.Length := 3
MsgBox z.Length  ; 3
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
sirksel
Posts: 222
Joined: 12 Nov 2013, 23:48

Re: [2.1 alpha8] Question re Array.Pop() and unset?

29 Dec 2023, 16:26

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!
lexikos
Posts: 9632
Joined: 30 Sep 2013, 04:07
Contact:

Re: [2.1 alpha8] Question re Array.Pop() and unset?

18 Jan 2024, 23:13

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.
Last edited by lexikos on 19 Jan 2024, 05:07, edited 1 time in total.
Reason: Fix misquote
iPhilip
Posts: 823
Joined: 02 Oct 2013, 12:21

Re: [2.1 alpha8] Question re Array.Pop() and unset?

19 Jan 2024, 03:12

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.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

Return to “Bug Reports”

Who is online

Users browsing this forum: lmstearn and 11 guests