Forum Discussion

tchoha888's avatar
tchoha888
Copper Contributor
Aug 07, 2023
Solved

Recursive LAMBDA and LET function problem

Can anyone tell me why my lambda function called "RecursionTest"

 

 

 

 

 

=LAMBDA(txt,
LET(
    pos, FIND("x", txt),
    IF(
        ISERROR(pos),
        pos,
        LET(
            nextTxt, MID(txt, pos + 1, 1000),
            next, RecursionTest(nextTxt),
            IF(ISERROR(next), "xx", VSTACK("xx", next))
        )
    )
))

 

 

 

 

 

returns unexpected (wrong) result

... while the following version of the same lambda function is ok

 

 

 

 

 

=LAMBDA(txt,
LET(
    pos, FIND("x", txt),
    IF(
        ISERROR(pos),
        pos,
        LET(
            nextTxt, MID(txt, pos + 1, 1000),
            next, RecursionTest(nextTxt),
            IF(ISERROR(FIND("x", nextTxt)), "xx", VSTACK("xx", next))
        )
    )
))

 

 

 

 

 

The only difference is that the varable "next" that is set in the innner LET function is used twice in the original version.

  • OK so it gets funky here. If you try only 1 or 2 it works but after that it fails. Basically after the 1st next becomes an array and the conditional part of the IF statement has N elements the TRUE parameter is singular so applied across any array size, but the FALSE parameter is N+1 elements so when there are 2 the conditional at that time max at 1 and the output array of 2 is allowed but after that there are unequal dimensions on the conditional and the FALSE parameter resulting in a #NA (value not available) in 1 case. If instead you had VSTACK("xx","xx",next) then you will get 2 #NA because there will be 2 values not available as it tries to parse through the arrays. A possible solution to this might be using CONCAT:

    IF(ISERROR(CONCAT(next)), "xx", VSTACK("xx", next))
  • mtarler's avatar
    mtarler
    Silver Contributor

    OK so it gets funky here. If you try only 1 or 2 it works but after that it fails. Basically after the 1st next becomes an array and the conditional part of the IF statement has N elements the TRUE parameter is singular so applied across any array size, but the FALSE parameter is N+1 elements so when there are 2 the conditional at that time max at 1 and the output array of 2 is allowed but after that there are unequal dimensions on the conditional and the FALSE parameter resulting in a #NA (value not available) in 1 case. If instead you had VSTACK("xx","xx",next) then you will get 2 #NA because there will be 2 values not available as it tries to parse through the arrays. A possible solution to this might be using CONCAT:

    IF(ISERROR(CONCAT(next)), "xx", VSTACK("xx", next))
    • tchoha888's avatar
      tchoha888
      Copper Contributor

      mtarler Thank you very much! Appently I still need some more experience on how arrays affect formulas. Besides that I would suggest just a small improvement to your solution:

      IF(ISERROR(TAKE(next, 1, 1)), "xx", VSTACK("xx", next))
      • mtarler's avatar
        mtarler
        Silver Contributor
        You are very welcome. I considered TAKE or INDEX or even @ but since I wasn't sure there wasn't some possibility of an array with an error in it where the error wasn't in the first location (or last if you used TAKE(-1) ) I thought CONCAT was the 'safer' option to make sure any error was found. In terms of performance, I suspect an 'index' type of function would be slightly faster but doubt that would be a factor here.
        Regardless, glad I could help you learn a bit, it wasn't easy to track that one as I was going down the rabbit hole of why isn't the error passed through the function or maybe not recognized through the function when it had nothing to do with the function call passing an error correctly, it had to do with what was getting returned.

Resources