A Practically Infinite For Loop Function

About advanced scenes, and the Thyme scripting language used in Algodoo.

A Practically Infinite For Loop Function

Postby →The Real Thing← » Wed May 23, 2018 10:01 pm

This is a for loop function with a maximum limit that is so astronomically large that it can be considered practically infinite.

Source Code:
Code: Select all
scene.my.xfor = (start, end, func)=>{
    n := start;
    finished := false;
    iteration := {
         ! finished ? {
            (n < end) ? {
                result := func(n);
                 ! math.tobool(result) ? {
                    finished = true
                } : {};
                n = n + 1
            } : {
                finished = true
            }
        } : {}
    };
    str := "iteration; iteration; iteration; iteration; iteration; iteration; iteration; iteration";
    exec := {
         ! finished ? {
            eval(str);
            str = str + "; " + str;
            exec
        } : {}
    };
    exec
}


Arguments:

- "start" (int/float): The initial value of the counter which is increased by 1 after every iteration.
- "end" (int/float): The target value at which the loop will stop once the counter value is greater than or equal to the value.
- "func" (function): The function which is called on each iteration which should accept the counter value as a single argument. An additional feature for this function is that it should return a boolean which indicates whether the loop should continue. Return false to stop the loop.

Here is a while loop version:
Code: Select all
scene.my.xwhile = (cond, func)=>{
    n := 0;
    unfinished := math.tobool(cond(n));
    iteration := {
        unfinished ? {
            func(n);
            n = n + 1;
            unfinished = math.tobool(cond(n))
        } : {}
    };
    str := "iteration; iteration; iteration; iteration; iteration; iteration; iteration; iteration";
    exec := {
        unfinished ? {
            eval(str);
            str = str + "; " + str;
            exec
        } : {}
    };
    exec
}


Arguments:

- "cond" (function): A function which is called before each iteration which should return a boolean which indicates whether the loop should continue.
- "func" (function): A function which is called on each iteration which should accept the counter value as a single argument. Unlike the "func" argument in the "scene.my.xfor" function, returning a boolean does not do anything, as it should have been returned in the "cond" argument.

"scene.my.xfor" Example Usage:
Code: Select all
value := 0;
scene.my.xfor(0, 100, (n)=>{
    value = value + 1;
    true
});
value

Sets a variable named "value" to 0, increases it by 1 100 times, and then returns the variable. It is always best practice to return a boolean at the end of the loop function to ensure the desired effect.

The for loop function can also be used as a while loop:
Code: Select all
value := 0;
scene.my.xfor(0, +inf, (n)=>{
    value = value + 1;
    value < 100
});
value

Does the same thing as the first example, but is used like a while loop.

"scene.my.xwhile" Example Usage:
Code: Select all
value := 0;
scene.my.xwhile((n)=>{
    value < 100
}, (n)=>{
    value = value + 1
});
value

Sets a variable named "value" to 0, increases it by 1 until it is greater than or equal to 100, and then returns the variable.
Last edited by →The Real Thing← on Fri Jul 20, 2018 1:52 am, edited 3 times in total.
→The Real Thing←
 
Posts: 2
Joined: Wed May 23, 2018 1:11 am

Re: A Practically Infinite For Loop Function

Postby Xray » Tue May 29, 2018 11:52 pm

User kilinich developed an excellent FOR loop function (also called "Xfor" like yours) many years ago which has served us Thyme scripters very well. I don't recall what its iteration range is, and I don't know how well it compares to yours. His version is recursive which makes the code very compact, and I personally think that it's quite clever:

Code: Select all
scene.my.xFor = (n1, n2, code) => {
  n2 > n1 ? {
    m := (n1 + n2) / 2;
    scene.my.xFor(n1, m, code);
    scene.my.xFor(m + 1, n2, code)
  } : {code(n1)}
}


Just curious, have you used your For loop in one or more scenes that you've posted on Algobox? If so, do you use the same user name on Algobox as you use here in the Forum? I would like to take a look at them. :thumbup:
User avatar
Xray
 
Posts: 500
Joined: Sun Jun 17, 2012 6:12 am
Location: USA

Re: A Practically Infinite For Loop Function

Postby →The Real Thing← » Thu Jun 21, 2018 6:40 am

Xray wrote:User kilinich developed an excellent FOR loop function (also called "Xfor" like yours) many years ago which has served us Thyme scripters very well. I don't recall what its iteration range is, and I don't know how well it compares to yours. His version is recursive which makes the code very compact, and I personally think that it's quite clever:

Code: Select all
scene.my.xFor = (n1, n2, code) => {
  n2 > n1 ? {
    m := (n1 + n2) / 2;
    scene.my.xFor(n1, m, code);
    scene.my.xFor(m + 1, n2, code)
  } : {code(n1)}
}


Just curious, have you used your For loop in one or more scenes that you've posted on Algobox? If so, do you use the same user name on Algobox as you use here in the Forum? I would like to take a look at them. :thumbup:


It was actually that thread by kilinich (Thyme 2.0) that inspired me to make a better for loop function. I strongly believe that this function has a much higher loop limit due to the function doing eight loop checks initially, then doubling the number of loop checks after each iteration until the loop is finished. I have already tested the function with (literally) 1 million iterations, and after about 30 seconds of waiting, there were no errors or stack overflows and it worked as intended.

Also, if you're wondering who I am, I was formerly the user BeltedRose85463. I stopped using Algodoo for quite a while now and I can't get back into my account, so I created a new one.
→The Real Thing←
 
Posts: 2
Joined: Wed May 23, 2018 1:11 am

Re: A Practically Infinite For Loop Function

Postby s_noonan » Sun Apr 12, 2020 10:21 am

I found out (after a lot of pain and aggravation) that the →The Real Thing←'s xFor function causes a memory leak when using nested xFors. The reason I was using his xFor in place of Kilinich's is that →The Real Thing←'s xFor allows you to exit the xFor at any time. Here are my suggestions:

1. Rename →The Real Thing←'s scene.my.xfor to scene.my.yfor. →The Real Thing←'s xFor function is not directly interchangeable with Kilinich's xFor function since →The Real Thing←'s xFor function is expecting the "func" parameter to return a boolean. Also, the "end" parameter equals Kilinich's "n2" parameter minus 1.

2. Replace [exec] in the last line of →The Real Thing←'s xFor function with [exec; iteration = ""; exec = ""]. This will eliminate memory leaks.

3. Replace "(n < end)" with "(n < end + 1)", so it matches Kilinich's xFor usage.

Code: Select all
scene.my.yfor = (start, end, func)=>{
    n := start;
    finished := false;
    iteration := {
         ! finished ? {
            (n < end + 1) ? {
                result := func(n);
                 ! math.tobool(result) ? {
                    finished = true
                } : {};
                n = n + 1
            } : {
                finished = true
            }
        } : {}
    };
    str := "iteration; iteration; iteration; iteration; iteration; iteration; iteration; iteration";
    exec := {
         ! finished ? {
            eval(str);
            str = str + "; " + str;
            exec
        } : {}
    };
    exec;
    iteration = "";
    exec = ""
}
s_noonan
 
Posts: 61
Joined: Tue Mar 30, 2010 2:25 am


Return to Thyme scripting

Who is online

Users browsing this forum: No registered users and 4 guests

cron