Forum Discussion
Recursive Lambda: Unpacking LET function
RecentlyTwifoo posted the FIFO Inventory challenge, and PeterBartholomew1 ventured "shouldn't take lori_m more than a few minutes to write a recursive Python script to reduce any LET function back to its simplest form". I've attempted this using a recursive LAMBDA function and it is just naive replacement of a variable with its definition, please see attached. Summary on first tab, and deep-dive on 2nd tab.
I used a few of the various LET formulas from the FIFO Inventory challenge that were submitted as my set of test cases, and was able to finally get a mostly-working version; feel free to play with it, share improvements, and possibly help me figure out my remaining issues. In experimenting, my interim versions of my LAMBDA did kill my Excel instance a few times, but I think this version is stable-ish without having hit it with a bevy of test cases.
Of the 5 LET formulas I tested, only mathetes formula will not yield to my function. Someone will probably identify the issue readily, I may just have been staring at it for too long to see it. SergeiBaklan's formula was the only one that didn't require adjustments to var names to prevent substring collisions. Perhaps others have ideas about how to avoid having to adjust??
Finally, I've included a failed attempt on the 3rd tab that I'd like others to perform an autopsy on and perhaps help me figure out why it doesn't work, but my slightly modified version is successful. During my experimenting, I thought perhaps it was due to limits on parameter length being passed to a LAMBDA, but my brain is a bit fried after working on it for a day or two. Fun exercise!!
- PeterBartholomew1Silver Contributor
Wow, that is a stunning effort! Perhaps the Microsoft Research Team might like to take a look at this to see where their 'baby' is being taken!
LAMBDA: The ultimate Excel worksheet function - Microsoft Research
I wasn't really serious in suggesting that the task should be performed, simply making the point that it could be performed. I was simply expressing the idea that reducing a LET function to traditional spreadsheet formulae (that I know and loath) is a purely mechanistic process. I had thought of using Lambda functions and even taken a step or two in that direction. After all, if Lambda functions make Excel Turing-complete and, given that functional programming is well-suited to the task of parsing data for compiler writing, I thought it should be possible.
The thoughts that led me to suggest Python were that I knew that Lori uses Python more than Excel and the development environment should be more productive. I did have one advantage over you, namely I use Charles Williams's FastExcel which includes regular expression support, so I was able to search for strings that were bounded by word breaks and only replace those with no adjacent word characters.
I completely freaked out at the possibility of matching paired parentheses, so I guess I wasn't sufficiently committed to the task. After all, I am the one that has declared I would sooner consign Excel to the trash-can than go back to spreadsheeting as it used to be! To me the non-LET versions of the formulae are a mess and to be used only as a last resort.
To finish, I can only reiterate my opening sentence; Wow ...
- tbouldenIron Contributor
PeterBartholomew1Much appreciated! I did make several false starts with regard to matching opening and closing chars, but I think the saving grace is that I assumed it only should work on formula that Excel has already properly parsed and calculated; I think building a formula validator might be an interesting exercise as well.
I'll have to check out FastExcel, I've used regex in VBA with the appropriate reference, but having it available in the worksheet itself would be nice. If I recall correctly building regex for bracket matching is a bit complicated with a novice's understanding; I know that my balanced tests would fail if a brace was within a pair of double-quotes without a corresponding matching brace before the next formula-level brace.
I agree that non-LET will be a thing of the past after some time, just wish we'd had it sooner, would've made spreadsheet modeling much less aggravating at times.
Interesting, thanks for sharing. Can't say I understood this, make bookmark to play with your file later.
- tbouldenIron Contributor
And I've sorted the issue with mathetes formula not yielding to my function: my helper LAMBDA CheckCommaBeforeOpenChar throws an error because there are no curly braces in the formula. Updated the helper LAMBDA to this, though probably better to handle errors differently than pass a value that isn't correct:
T_KthCharInstance,LAMBDA(myStr,myChar,k,IFERROR(FIND(CHAR(1),SUBSTITUTE(myStr,myChar,CHAR(1),k)),LEN(myStr)+1))
- TTodorovCopper Contributor
Hi,
I'm trying to transform this table (two columns, separated in text bellow with symbol "|"):
3 | 138, 169, 192, 193
3, 4 | 127
2, 3 | 115, 138, 144
to this column:
3-138
3-169
3-192
3-193
3-127
4-127
2-115
2-138
2-144
3-115
3-138
3-144
I prepared with helper table, wit formula TOROW(TEXTSPLIT($A2, , ", ") & "-" & TEXTSPLIT($B2, ", ")) for each row.
In sample above $A2 = 3 and $B2 = 138, 169, 192, 193
After that with TOCOL() from helper table will have result column as mentioned.
But wonder for better way (without helper table).
Is it possible to be done with recursive LAMBDA?- rachelSteel Contributor
I need to use @ to convert array into a string to use textsplit in let, I not sure whether it is supported on your excel, but it works for me:
=TOCOL( TEXTSPLIT( ARRAYTOTEXT( MAP( A2:A4, LAMBDA(x, LET( data, TEXTSPLIT(x, "|"), xs, TEXTSPLIT(@TAKE(data, 1, 1), ","), ys, TEXTSPLIT(@TAKE(data, 1, -1), ","), ARRAYTOTEXT(TOROW(xs & "-" & TRANSPOSE(ys)), 0) ) ) ), 0 ), "," ) )