Page 1 of 1

Iterators

Posted: Sun Feb 04, 2024 1:05 pm
by DarkDragon
Hello,


What
I'd like to see iterators for lists and maps and maybe even arrays in PB implemented on two levels.

Level 1:

Code: Select all

CreateIterator(NumberOrPBAny.i, List())
*ElementData = IteratorNext(Number.i)
; or
IteratorNext(Number.i, @*ElementData) ; such that While IteratorNext(..., @*ElementData) is possible and there's no need for more lines.
ReleaseIterator(Number.i)
Level 2:

Code: Select all

ForEach [*ElementData[.Type] In] List()
  ; do something with *ElementData
Next
Where [] is used for optional parts. This way it wouldn't break the old ForEach. Right now I have a workaround using Macros:

Code: Select all

EnableExplicit

Macro ForEachList(name, type, container)
  Define name.type
  ResetList(container)
  While NextElement(container)
    name = @container
EndMacro

Macro ForEachListNext(name, container)
    ChangeCurrentElement(container, name)
  Wend
EndMacro



NewList X.i()

AddElement(X()) : X() = 1
AddElement(X()) : X() = 2
AddElement(X()) : X() = 3


Debug "Classic ForEach cannot be nested easily (without storing current position) as you can see here:"

ForEach X()
  ForEach X()
    Debug X()
  Next
Next

Debug ""

Debug "ForEachList can be nested"

ForEachList(*X1, Integer, X())
  ForEachList(*X2, Integer, X())
    Debug *X2\i
  ForEachListNext(*X2, X())
ForEachListNext(*X1, X())
Output:

Code: Select all

Classic ForEach cannot be nested easily (without storing current position) as you can see here:
1
2
3

ForEachList can be nested
1
2
3
1
2
3
1
2
3
---

Why
Whenever I come back to PureBasic I struggle with that, since nesting is not always so obvious. Imagine something like this:

Code: Select all

ForEach X()
  Subroutine(X())
Next
The inner subroutine could potentially change the current element of the list, which influences the outer ForEach. Also recursively iterating through a list could be necessary with some algorithms and named iterators would be useful then.


That's actually why I wanted the C headers for user libraries. I saw a PB_List thing there.

Re: Iterators

Posted: Sun Feb 04, 2024 1:48 pm
by Little John
DarkDragon wrote: Sun Feb 04, 2024 1:05 pm

Code: Select all

Classic ForEach cannot be nested
ForEach can be nested by using PushListPosition()/PopListPosition() or PushMapPosition()/PopMapPosition(), respectively.

Re: Iterators

Posted: Sun Feb 04, 2024 1:51 pm
by HeX0R

Code: Select all

NewList X.i()

AddElement(X()) : X() = 1
AddElement(X()) : X() = 2
AddElement(X()) : X() = 3


Debug "Classic ForEach can be nested as you can see here:"

ForEach X()
	PushListPosition(X())
  ForEach X()
    Debug X()
  Next
  PopListPosition(X())
Next
[Edit]
Damn too slow :mrgreen:

Re: Iterators

Posted: Sun Feb 04, 2024 2:46 pm
by DarkDragon
Of course, but it needs mangling around with the position manually just like my workaround macro stuff. What if I access said item before or after such an iteration and misplace it before/after push/pop? Why do I need to write 3 more lines if it could be integrated seamlessly in the language? Every other language has the concept of iterators as individual objects to exactly overcome this issue of having a global state attached to the container.

Re: Iterators

Posted: Sun Feb 04, 2024 3:05 pm
by Little John
DarkDragon wrote: Sun Feb 04, 2024 2:46 pm Of course, but it needs mangling around with the position manually just like my workaround macro stuff. What if I access said item before or after such an iteration and misplace it before/after push/pop? Why do I need to write 3 more lines if it could be integrated seamlessly in the language? Every other language has the concept of iterators as individual objects to exactly overcome this issue of having a global state attached to the container.
Please note that I did not say that your suggestion is useless. I only corrected a false statement you made.

Re: Iterators

Posted: Sun Feb 04, 2024 3:06 pm
by Demivec
I share your request.

Here is a previous request of mine: https://www.purebasic.fr/english/viewtopic.php?p=330236

Re: Iterators

Posted: Sun Feb 04, 2024 6:01 pm
by DarkDragon
Little John wrote: Sun Feb 04, 2024 3:05 pm Please note that I did not say that your suggestion is useless. I only corrected a false statement you made.
Ok, thanks, I've edited it.
Demivec wrote: Sun Feb 04, 2024 3:06 pm I share your request.

Here is a previous request of mine: https://www.purebasic.fr/english/viewtopic.php?p=330236
Oh I didn't search for that, sorry. We can delete my topic then, duplicates should be prevented.

Re: Iterators

Posted: Sun Feb 04, 2024 6:11 pm
by Demivec
DarkDragon wrote: Sun Feb 04, 2024 6:01 pm
Demivec wrote: Sun Feb 04, 2024 3:06 pm I share your request.

Here is a previous request of mine: https://www.purebasic.fr/english/viewtopic.php?p=330236
Oh I didn't search for that, sorry. We can delete my topic then, duplicates should be prevented.
I think it's better that they both be kept as they include different view points on how to possibly implement the request.

Re: Iterators

Posted: Mon Feb 05, 2024 11:29 am
by NicTheQuick
This is especially interesting for multi threaded applications where you have multiple threads iterating over the same global list without writing anything to it.