For me, the actual details of various functional programming languages are not likely to significant. No doubt there are major applications where functional languages have huge advantages.
For Leo, it will suffice to use the ideas of functional programming to simplify and refactor python code. This morning's work was a surprising example. Splitting tasks in novel ways collapsed quite a bit of the code's complexity.
For a bigger challenge, I would like to simplify all the various methods that write external files. This morning's work improved just a sliver of the ugly beast.
Vitalije commented that there are too many switch-like arguments in this code. A new thought: removing these switches, in some clever order, might well be a quasi-methodical way of refactoring the code. Each mini-refactoring will aim to remove or simplify at least one switch-like argument.
Terminology
Let X be the set of various kinds of @<file> nodes (@clean, @file, @auto, etc), denoting a set of methods. So at.writeXNode stands for at.writeAtAutoNode, at.writeAtCleanNode, etc.
toString
All write code could (should) write to a string as an intermediate step. This might eliminate the "toString" kwarg completely. We can do this by defining a set of at.writeAtXToString methods, called by the another set of at.writeAtX methods.
The at.writeAtXToString methods seem like the "middle" point of each at.writeAtX method:
- The preceding code will set state vars based on X and on Leo's directives found in the to-be-written tree.
- The following code will write the string to an output file, based again on Leo's directives, and the path implied by the @<file> node itself. For @shadow, there will be two output files, with two separate paths.
Graphs analysis
Refactoring is messy because the preceding and following code for each X is similar, but mostly different. There are way too many details to keep in mind. It is essential to keep the effect of the existing code!
These difficulties suggest creating a summary graph describing the existing code. For each X, we want the graph to clarify which kwargs are used, what code is executed, and how code depends on the various kwargs.
It will suffice to create this graph by hand. The process of doing so may reveal patterns that will allow doing all the essential existing computations more simply. This probably looks like the best way of reducing incidental complexity.
Summary
The exact details of writing files of type X vary significantly for each X. It is essential to keep the effect of the existing code! We must be careful. We can't just rely on unit tests.
Refactoring should be done methodically, using an analysis graph. This graph should highlight the role of kwargs, and may reveal methodical ways of removing most kwargs.
This project is highly experimental. Only time will tell whether it can be done safely.
All comments and suggestions welcome.
Edward