Patrick Chkoreff, 2015-05-20

Fun Factoring Fexl Functions

This is just a tiny example of a refactoring process, but it illustrates the general approach pretty well.

We're rendering tables in HTML, and we have this code to print the colgroup as literal text.

put
~
<colgroup>
<col width=220>
<col width=120>
<col width=120>
<col width=120>
<col width=120>
</colgroup>
~

Ordinarily that's just fine, but what if we don't like the repetition? OK, let's start by breaking it into pieces.

put
~
<colgroup>
~
put
~
<col width=220>
~
put
~
<col width=120>
~
put
~
<col width=120>
~
put
~
<col width=120>
~
put
~
<col width=120>
~
put
~
</colgroup>
~

At this point the tilde string syntax is overkill, so let's just use a simple say on each line.

say "<colgroup>"
say "<col width=220>"
say "<col width=120>"
say "<col width=120>"
say "<col width=120>"
say "<col width=120>"
say "</colgroup>"

Now let's use a list of column widths to generate those inner lines.

say "<colgroup>"
each [220 120 120 120 120] (\width say ["<col width=" width ">"])
say "</colgroup>"

That's neat, but what if we want to use this in multiple places? We'll factor the width list out.

\widths=[220 120 120 120 120]
say "<colgroup>"
each widths (\width say ["<col width=" width ">"])
say "</colgroup>"

Let's wrap a function around that.

\colgroup=
    (
    \widths=[220 120 120 120 120]
    say "<colgroup>"
    each widths (\width say ["<col width=" width ">"])
    say "</colgroup>"
    )
colgroup

Well, except we want to pass in the widths instead of having them baked into the function.

\colgroup=
    (
    \widths
    say "<colgroup>"
    each widths (\width say ["<col width=" width ">"])
    say "</colgroup>"
    )
colgroup [220 120 120 120 120]

That's it, except I like to keep parameters on the same line as the opening parenthesis.

\colgroup=
    (\widths
    say "<colgroup>"
    each widths (\width say ["<col width=" width ">"])
    say "</colgroup>"
    )
colgroup [220 120 120 120 120]

Done. I can now use the colgroup function everywhere I do a table.

That is just a very tiny example. Refactoring in Fexl is very easy, fluid, and predictable. I like to take entire literal web pages and refactor them into "computed", highly compressed versions. It's particularly neat when the values embedded in the page can be computed from a small handful of input data.