The code [5].__Enum(100) should throw

Report problems with documented functionality
Springwight
Posts: 7
Joined: 02 May 2015, 04:43

The code [5].__Enum(100) should throw

Post by Springwight » 03 Mar 2023, 16:07

In v2.0.2, the following code doesn't throw:

Code: Select all

for a, b, c, d, e in [1] {

}

iterator := [5].__Enum(100)
iterator(&a, &b, &c, &d)
Because of this, right now it's impossible to check if something is enumerable with N params, even by trying to enumerate it.

Ideally:
  1. __Enum(N) should throw if the collection doesn’t support enumerating with N params.
  2. The Enumerator should throw if it was created via __Enum(N) and you call it with anything except N params.
Alternatively, __Enum(N) can return "" for invalid inputs, which will allow checking if something is enumerable with N params without having to catch an exception.

just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: The code [5].__Enum(100) should throw

Post by just me » 04 Mar 2023, 06:12

Springwight wrote:
03 Mar 2023, 16:07
Because of this, right now it's impossible to check if something is enumerable with N params, even by trying to enumerate it.

Code: Select all

MyArr := ['A', 'B', 'C', 'D']
MaxParams := MyArr.HasProp("__Enum") ? MyArr.__Enum.MaxParams : 0
MsgBox(MaxParams, "MaxParams", 0)

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: The code [5].__Enum(100) should throw

Post by swagfag » 04 Mar 2023, 08:10

Code: Select all

MyArr.__Enum.MaxParams
that tells u the MaxParams of the __Enum method(which are __Enum(hidden_this, NumberOfVars) = 2), not how many variables the Enumerator that ure about to receive from calling __Enum will populate for u
but its pointless to test that too, since the current implementation only cares about whether ure passing N=0, 1 or 2, and everything else beyond that is ignored
also til, this is a valid construct, but im not sure whether it should be(at least not according to the docs)

Code: Select all

for in ['a', 'b', 'c']
	MsgBox A_Index

just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: The code [5].__Enum(100) should throw

Post by just me » 04 Mar 2023, 09:50

Enumerator Object wrote:When defining your own enumerator, the number of parameters should match the number of variables expected to be passed to the for-loop (before the "in" keyword). This is usually either 1 or 2, but a for-loop can accept up to 19 variables. To allow the method to accept a varying number of variables, declare optional parameters.
Source

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: The code [5].__Enum(100) should throw

Post by swagfag » 04 Mar 2023, 11:29

what did u quote this for?

User avatar
lmstearn
Posts: 694
Joined: 11 Aug 2016, 02:32
Contact:

Re: The code [5].__Enum(100) should throw

Post by lmstearn » 05 Mar 2023, 00:11

Not sure if the understanding of this is going well at all (really new with v2): :problem:

Code: Select all

for a, b, c, d, e in [1] {

}

iterator := [5].__Enum(100)
iterator(&a, &b, &c, &d)
The variable 1 used as an object is a command line parameter consisting of a string like "a, b, c, d, e" right? Does that somehow automagically commute to an array object? if so, would 1.length be of any help?
In that case, would it make sense, instead of iterator := [5].__Enum(100) we have instead for the throw/no_throw iterator := [1].__Enum(100)?
(Unless there are actually 5 (A_Args.Length) parameters in A_Args all of them in the form "a, b, c, d, e".)
What is [1] in any case- looks like an array with one element only, 1. Would [%1%] ever expand it?
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: The code [5].__Enum(100) should throw

Post by swagfag » 05 Mar 2023, 06:23

lmstearn wrote:
05 Mar 2023, 00:11
What is [1] in any case- looks like an array with one element only, 1
its a plain old, run-of-the-mill, user-instantiated Array that contains one element inside of it - the Integer 1. nothing more, nothing less.

Springwight
Posts: 7
Joined: 02 May 2015, 04:43

Re: The code [5].__Enum(100) should throw

Post by Springwight » 05 Mar 2023, 12:14

The main problem is that objects support only iteration with certain numbers of variables, like 1 or 2, but in practice this restriction isn’t enforced.

For example, an array is supposed to be iterable with only 1 or 2 parameters, but you can iterate it with 10 params and it doesn’t raise an error.

Besides that, if you ask for an iterator with 2 params and call that iterator with 10 params, that won’t error either, even though it’s supposed to.

__Enum(n) is an internal method used to create an enumerator with n params. However, you can call __Enum(100) on an array and you’ll still get an iterator. You can even call __Enum(-1).

iseahound
Posts: 1444
Joined: 13 Aug 2016, 21:04
Contact:

Re: The code [5].__Enum(100) should throw

Post by iseahound » 10 Mar 2023, 23:45

Well apparently, it is possible to have -5 of something. It's just not clear what enumerating -1 of something is.

So it is possible to have a negative set of elements. The idea displayed in the preceding link is to imagine a bridge linking {• •}, if {• •} has a cardinality of 2, and {•—•} a cardinality of 1, then a bridge, drawn as {o—o} has a cardinality of -1.

I suppose the lazy way of defining an enumeration of -1 would be to just iterate through the elements backwards.

Another possibility, in this paper, is to define an enumeration of -1 as infinitely looping through all the elements. However, they only define what enumerating -1 elements means on a negative set, showing that it's impossible (in their construction) to have -1 elements enumerated from a positive set. (They define -1 as removal, and removing a positive element works, but removing a negative element keeps it there, looping forever)

Perhaps the third possibility is to just have the idea of a negative enumeration being the addition of elements into the set. This makes more sense from a computer science perspective. But it's not clear what an implementation would look like.

Anyways, interesting, if weird, to consider an enumeration of -1, and I don't believe if it's ever been asked before. Source: https://math.ucr.edu/home/baez/counting/

lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: The code [5].__Enum(100) should throw

Post by lexikos » 27 Mar 2023, 02:09

Springwight wrote:
03 Mar 2023, 16:07
Ideally:
  1. __Enum(N) should throw if the collection doesn’t support enumerating with N params.
  2. The Enumerator should throw if it was created via __Enum(N) and you call it with anything except N params.
Alternatively, __Enum(N) can return "" for invalid inputs, which will allow checking if something is enumerable with N params without having to catch an exception.
I will consider this.

Springwight wrote:
05 Mar 2023, 12:14
Besides that, if you ask for an iterator with 2 params and call that iterator with 10 params, that won’t error either, even though it’s supposed to.
In regard to the linked documentation, I think you are misinterpreting something. There is nothing there to indicate that this condition will cause an error to be thrown.

This documentation is meant to cover all enumerator implementations. Even if your suggestions are implemented, there is no guarantee that a user-defined implementation will have error-detection as robust as you describe. The only mention of thrown exceptions is about what is thrown from the for-loop, not the enumerator. The exception is just thrown as a result of a function call being performed with the wrong number of parameters, and (iirc) isn't even actually raised by the for-loop itself.

sirksel
Posts: 222
Joined: 12 Nov 2013, 23:48

Re: The code [5].__Enum(100) should throw

Post by sirksel » 30 Mar 2023, 12:59

Remember too that some of us use variadic enumerators. Once the combination of closures, fn(&byref) changes and generalization of enumerators were added in v2, one can call wrapped Enumerators as e(p*), where p is a variadic array of VarRef. This makes the language incredibly flexible, and enables things like the enumerator chaining I mentioned in another thread. (Although I didn't post a full working library there, it's enough to get the idea of how to wrap enumerators with other enumerators, if you haven't already tried that.) A bunch of strict throw rules could make all of this less flexible, depending of course on how they are implemented. Just a thought...

Post Reply

Return to “Bug Reports”