Refactoring with a functional programming mind set

68 views
Skip to first unread message

Edward K. Ream

unread,
Jan 8, 2019, 4:24:11 PM1/8/19
to leo-editor
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

vitalije

unread,
Jan 9, 2019, 7:21:12 AM1/9/19
to leo-editor
May I suggest a different naming scheme at<X>ToString  and writeAt<X>.

Having the word 'write' in both of them seems a bit odd.

Vitalije

Edward K. Ream

unread,
Jan 9, 2019, 7:47:28 AM1/9/19
to leo-editor
On Wed, Jan 9, 2019 at 6:21 AM vitalije <vita...@gmail.com> wrote:

May I suggest a different naming scheme at<X>ToString  and writeAt<X>.

Thank you.  Excellent suggestion.

Edward

Edward K. Ream

unread,
Jan 9, 2019, 8:28:42 AM1/9/19
to leo-editor
On Tuesday, January 8, 2019 at 3:24:11 PM UTC-6, Edward K. Ream wrote:

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.

I meant to say, we can't rely on existing unit tests.  Indeed, a few hours after writing this I saw that designing a test environment is essential, so that we can prove that the old and new versions of the code are identical.

Edward

Edward K. Ream

unread,
Jan 9, 2019, 3:16:09 PM1/9/19
to leo-e...@googlegroups.com
On Wednesday, January 9, 2019 at 6:21:12 AM UTC-6, vitalije wrote:

May I suggest a different naming scheme at<X>ToString  and writeAt<X>.

We will also need new get<X> methods, which will be top-level entry points that init everything like writeAt<x> and return a string.  In other words, the at<X>ToString  and writeAt<X> methods do not suffice.

This is all very complicated. My strategy will be to make a series of "simplest possible" changes.  The starting point will be to eliminate the toString kwarg from at.write. Even this is non-trivial.

Edward
Reply all
Reply to author
Forward
0 new messages