I’ve been trying to implement memoizing existing recursive functions without the user needing to change the function’s definition. So for example: , with the original definition:
Memoizing is a rather simple operation, but one needs to make a few adaptations within the original function’s definition (or implementation, as IMO is a more fitting term). Since, as implied above, I strive to automate that process, I’m going to achieve that through metaprogramming. While I'm at it anyway, I want to include the memoizing process in one go. So I’m trying to implement two changes in a function’s definition - and the function may be any (recursive) reporter (or predicate) provided that its result is fully determined by its formal input parameters:
- Replace any recursive calls with calls to the name of the new function. So far, this has proven to be the easy part.
- Replace any REPORT (some expression) blocks with SET (value) TO (some expression); ADD (LIST (key) (value)) TO (memory); REPORT (value). This is the hard part.
In order to manipulate code it has to be transformed to a (usually multilevel) list using SPLIT (code) BY (block).
Update: the memoizer is working now.
Annoyingly, if the code is only one block (“REPORT” …), the formal input parameters are the final items of the main list. If, however, the code consists of multiple blocks, the parameters are the final sub-items of item 1. Perhaps this is handy for the interpreter executing the code, but not so if one’s trying to change the code - I built a parameter stripper and a reassembler in order not to unnecessarily complicate other operations:
Secondly I noticed that in some cases REPORT is not part of the code as transformed into a list. E.g. I rewrote the above Fibonacci function:
… and this is what its
implementation definition looks like as a list (REPORT has disappeared!):
Yet another (undocumented) complication if one tries to replace REPORT with something else.
Thirdly I noticed what looks like a bug (transformation: code -> list -> code gone wrong):