[v2] Custom for-loops: Enumerators, Iterators, Generators

Helpful script writing tricks and HowTo's
sirksel
Posts: 222
Joined: 12 Nov 2013, 23:48

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by sirksel » 14 Mar 2023, 01:59

You all might be interested in this. A while back, I wrote a "chainable" iterator class that's kind of a functional programming approach. Since I saw you all were discussing this topic, I extricated this from my main code library:

Code: Select all

class enm extends itb {                     ;enumerator wrapper extends iterable

  __New(ebl, enmw, atyx?) {      ;instantiate w enum wrapper and arity transform
    this.ebl := ebl                                          ;enumerable subject
    , this.enmw := enmw                               ;wrapper for __Enum(a)(p*)
    , this.atyx := atyx ?? (x=>x)                               ;arity transform
  }

  __Enum(aty)                                      ;enumeration start with arity
    => ((t:=this).aty := aty                              ;store arity in object
      , t.enmw.call(t.ebl.__Enum(t.atyx.call(aty))))  ;call on wrapped fnc/arity

} ;=============================================================================
It's layering on the functions for the ultimate call to __Enum from the for loop. You need an itb class for this to work, which would contain the usual iterable methods (map, reduce, etc). They rely on too much of my standard library to extricate them here, but they are all standard implementations. But the enm class above was the real breakthrough part for me.

With this you can chain a bunch of stuff (like a Java stream, or lazy evaluation) such that the items pass through one at a time, rather than making intermediate lists. Like generators instead of list comprehensions for the Python gurus in the thread. If you also DefineProp the itb methods into Array.Prototype, the top of a for loop that uses this could look something like:

for i in myArray.drop(5).filter(x=>x>50).take(10).transform(x=>x*100)

where this drops the first 5 items, filters those above 50 but only the next 10 of them, multiplying each by 100. This is a crazy example, but it demonstrates the power and terse nature of chained enumerator functions.

The itb.take method looks like this, for example, so you can see how the constructor gets called:

Code: Select all

  take(cnt) => enm(this                                   ;enum take first count
    , (i:=0,  f => (p*) => (++i > cnt ? 0 : f(p*))))
You can see how this then gets wrapped around the functions already inside the enm chain when __Enum is called.
Last edited by sirksel on 14 Mar 2023, 07:29, edited 1 time in total.

AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by AHK_user » 14 Mar 2023, 06:17

My v2 listview class has also a nice custom enumerator to loop over the lines.

for row, rowcontent in lv => loop over the content

viewtopic.php?f=82&t=104041&hilit=listview

User avatar
Relayer
Posts: 160
Joined: 30 Sep 2013, 13:09
Location: Delaware, USA

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by Relayer » 16 Mar 2023, 12:25

I'll ask a question here because it is on-topic...

In v1 I could create a class that contained a set of methods. I could then reference that class with a for-loop (for Name, Method in classObj). Inside the for-loop I would need to make sure what was retrieved was indeed a method I can call because the loop would enumerate all methods and properties. This was easily done by checking a spelling pattern. Often it was enough to test if Method was a function with if (isFunc(Method)).

I don't see how to do this in v2. The documentation mentions that methods are skipped in the enumeration. I believe it makes suggestions for how to have it enumerate methods but I cannot decipher it well enough to make it work.

Ideas?

Relayer

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

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by sirksel » 16 Mar 2023, 12:36

I think you want .OwnProps. Like this:

Code: Select all

class cls {
  test(str) => 'hi ' str
}
for name in cls.Prototype.OwnProps()
  MsgBox name
For testing if something is callable, look at the remarks for HasMethod.

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

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by iseahound » 16 Mar 2023, 13:07

Do you have a working snippet for your version of the java.util.stream API? That looks really fun to play with, but I don't see how to get working code from your snippet.

Also, I think you should use the existing 3 letter abbreviation ary for arity. It already exists as n-ary (same meaning as variadic)

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

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by sirksel » 16 Mar 2023, 21:55

I like it. ary it is! Thanks for the suggestion. Will fix it when I have time. I do need to extricate all that into its own class. There are just so many cross refs to all my library functions and built-in extended methods. Oh well, I guess that's the problem with extending primitives with thousands of extra lines that you thought no one else would need to see. Anyhow, when I get time, I'll extract at least some of it to a more executable snippet.

If I ever really get enough time, I'd love to build an AHK functional library more akin to Ramda for JS, with proper currying of functions. The change I requested in the other thread will help with that, as well as make it more useful. Unconditional/constant definition of partials/boundfuncs that doesn't rely on execution order seems to be what all these languages with quasi-functional support (even JS and Python) are missing. Sounds like it's harder to do than I thought, based on your comments about parsing for invalid names, so it may never happen. Will hold a good thought though.

User avatar
RaptorX
Posts: 371
Joined: 06 Dec 2014, 14:27
Contact:

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by RaptorX » 15 Apr 2023, 13:47

FredOoo wrote:
07 Jun 2022, 12:11
Thank you too for sharing.
Can you tell me more about the syntax a & v?
I see it returns an item in v but, what means &, where can I read about it in the doc?
I love fat arrow functions and the fact that parenthesis are optional on function calls but it just opened a very ugly looking can of worms :lol:
I still dont quite get it but what i think it is doing is: a(&v)... right? that seems SO different than a & v. It makes no sense whatsoever :crazy:

well, thats one of the things we are going to have to endure now... fat arrow functions used for multiline statements (defeating the purpose of fat arrow functions in the first place, blame javascript for that one) and really ambiguous looking code that only the one who wrote it might have a clue as to what he meant by it.
Projects:
AHK-ToolKit

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

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by sirksel » 29 Apr 2023, 01:19

You probably would have liked my original version (from a couple of years ago), then:

Code: Select all

rpt(f, i) {   ;repeat f(A_Index) i times
  Loop i
    f(A_Index)
}
grp(xs)   ;grouped enum of xs array; size of group matches arity
  => {__Enum : (_,a) => (len := xs.Length // a,  i := 0,  (rs*) 
    => (++i > len) ? 0 : (rpt(j => (%rs[j]% := xs[i*a-(a-j)]), a), 1))}
Some thought it was intentionally obfuscated, but I still like it. :) I mostly did it for fun. It combines custom __Enum, closures, nested fat arrows, and variadic array of varrefs to do something similar to what one might do in Haskell, ML, or one of the functional programming languages. It also uses some of those functional programming variable naming conventions (like xs meaning a list of x).

User avatar
RaptorX
Posts: 371
Joined: 06 Dec 2014, 14:27
Contact:

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by RaptorX » 29 Apr 2023, 09:58

sirksel wrote:
29 Apr 2023, 01:19
Some thought it was intentionally obfuscated, but I still like it. :) I mostly did it for fun. It combines custom __Enum, closures, nested fat arrows, and variadic array of varrefs to do something similar to what one might do in Haskell, ML, or one of the functional programming languages. It also uses some of those functional programming variable naming conventions (like xs meaning a list of x).
:D its amusing seeing those... one can probably learn very clever tricks and very efficient code hidden on those snippets.

This is bit off topic:
I do agree that when you want to obfuscate, that's exactly the way to go. But I've seen some ppl doing it just to look cool and then 2 weeks later they have to re-write their 150 lines of code function because nothing makes sense to them.

I find it really funny. Code is for humans, computers will definitely convert all that to 1's and 0's anyway, so, unless you are preoccupied with someone stealing your already simple to extract code, just go ahead and write clean code for yourself and any other poor soul that will have to read it and try and help you fix it. :lol:

When anybody needs help with their code and just pastes something like that, i don't even try wasting my time, someone smarter than me can do that.
Projects:
AHK-ToolKit

mfedorov
Posts: 5
Joined: 10 Jul 2023, 00:32

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by mfedorov » 10 Jul 2023, 04:34

Descolada wrote:
06 Mar 2023, 17:40
@FanaticGuru

Code: Select all

Range(Start, Stop, Step:=1) => (&n) => (n := Start, Start += Step, Step > 0 ? n <= Stop : n >= Stop)

For n in range(12, 2, -3)
    MsgBox n
Wow - Amazing!

sashaatx
Posts: 332
Joined: 27 May 2021, 08:27
Contact:

Re: [v2] Custom for-loops: Enumerators, Iterators, Generators

Post by sashaatx » 28 Nov 2023, 11:41

mfedorov wrote:
10 Jul 2023, 04:34
Descolada wrote:
06 Mar 2023, 17:40
@FanaticGuru

Code: Select all

Range(Start, Stop, Step:=1) => (&n) => (n := Start, Start += Step, Step > 0 ? n <= Stop : n >= Stop)

For n in range(12, 2, -3)
    MsgBox n
Wow - Amazing!
jfc the density, that's illegal!
https://github.com/samfisherirl
? /Easy-Auto-GUI-for-AHK-v2 ? /Useful-AHK-v2-Libraries-and-Classes : /Pulovers-Macro-Creator-for-AHKv2 :

Post Reply

Return to “Tutorials (v2)”