Almost @Decorate

This is a handy little snippet I’ve been using to emulate ES7′s decorators without needing to depend on a non-standard syntax, nor wire in extra Babel (or whatever) plugins. Or even use more than ES3, once the function itself is transpiled.

const decorate = (...decorators) => component =>
    decorators.reduce((c, d) => d(c), component);

Consider this ES7 decorated component (using the syntax as of 2017-08-25):

@MyDecorator(/* my config */)
@OtherDecorator(/* other config */)
class Fred {}
export default Fred;

Without decorators, it looks like this:

class Fred {}
export default OtherDecorator(/* other config */)(
    MyDecorator(/* my config */)(
        Fred
    )
);

I find this hard to read, even before complicated configuration (functions returning objects of functions, anyone?). Even if you play around with different line breaks, indentation, and intermediate variables, it’s never super clean. Also, the nesting is in the “reverse” order of how decorators apply. You often see a temp variable to fix this latter issue:

class Fred {}
const wrappedFred = MyDecorator(/* my config */)(
    Fred
);
export default OtherDecorator(/* other config */)(
    wrappedFred
);

Still a lot of cruft. Now if we use that decorate function up top, we get this:

class Fred {}
export default decorate(
    MyDecorator(/* my config */),
    OtherDecorator(/* other config */)
)(Fred);

Not as nice as today’s candidate ES7 syntax, but only barely. And it’s also completely transparent, unlike the Babel plugin (found at https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy/blob/v1.3.4/src/index.js for the masochists among us).

Update: if you don’t have an ES6 transpiler and need ES3, here it is:

function decorate() {
    var l = arguments.length, decorators = Array(l);
    for (var i = 0; i < l; i++) {
        decorators[i] = arguments[i];
    }
    return function(component) {
        return decorators.reduce(function(c, d) {
            return d(c);
        }, component);
    };
};

Advent of Code

Last December, Brenna did a bunch of Advent of Code, and on a number of problems I played mentor while she worked through them. My central tenet was that the hard part of programming is the part you do before you put your fingers on the keyboard. It’s really tempting to read through the problem and jump right into the code part and start laying out functions and stuff to solve it. It doesn’t work so well though.

The essence of good software design is effective abstraction. Abstracting things is not terribly difficult, but effective abstractions are rather trickier. As a programmer, you have to take human/business “stuff” and translate it into something so simple a computer processor can understand it. The bottom of that process is all taken care of for you by various compilers/assemblers/linkers/interpreters/etc., but that’s the uninteresting (and thus easily automated) part.

The technique that we repeatedly used was simple, but quite effective. It’s also totally obvious, so much so that it seems almost pointless:

Your first version should be English.

Start by writing prose in comments, and make it really high-level prose. I’m talking “the whole program is described in 10 lines” high-level. Once that’s done, it’s easy to pick out the nouns and verbs, which indicate where you probably need to make an abstraction. A noun represents a data structure of some sort. Declare the type somewhere, and reference it in your comment. A verb represents a function of some sort, and the object(s) will be the function’s parameter(s). Declare that function somewhere, and reference it in your comment.

Now you’ve got some types and functions, which are exactly the same as your program as a whole, so you approach the same way: write prose in comments for what they do. Find the nouns and verbs and repeat.

At some point you’ll get to functions which are either provided by your language runtime or libraries, or can be expressed directly in your language’s syntax. Once that happens, your comment can just be written as the equivalent line of actual code, at which point you’re done. And I don’t mean “done with the first draft”, I mean actually done as in “all the code is written.”

This is recursion, of course! Undoubtedly the scariest concept in programming, and one of the most useful.

Part of the reason this works so well is that it forces you to name everything. Naming stuff is a) really hard, and b) really, really useful. By having good names for stuff, it becomes possible to have natural-language conversations about the “stuff” in your program, at any level of abstraction. Even the best of programmers don’t think like computers, they think like humans, and humans use natural language to converse, even when they’re talking to themselves. By having good names in your programs, you make it much easier to talk about – and therefore think about – what is actually happening when they run, especially if there is more than one human involved.

As one specific example, consider this type I created when working on Day 6 of the Advent of Code:

type LightGrid [][]bool

This might not seem very useful: what is wrong with just passing [][]bool around everywhere? But consider the question “how many lights in the grid are turned on?” for a moment, and then look at these two effectively-equivalent function signatures and ask yourself which one is more obviously the way to answer that question:

func CountTurnedOn(LightGrid) int
func CountTurnedOn([][]bool) int

I hope you would agree with me that the former is much more obvious about what it’s doing, and this is an unusual case where “turned on” sort of makes sense for boolean values. If you’re familiar with Go, you’ll not be surprised that in my actual solution the first one was a method on the LightGrid type, not a standalone function.

By having the LightGrid type, we can talk about it with other humans (or ourselves) without having to understand that it’s a two-dimensional slice of boolean values. That’s irrelevant if you’re talking about the grid as a whole, and the names in your program should reflect that.  I.e., the name provides encapsulation.

In Brenna’s specific case, a rather significant part of the problem was that she’s primarily developed using CFML in her career. CFML doesn’t provide a good way to create lots of data types to help with this problem. As a result, you have lots of signatures that use array, struct, or query in their types, and who knows what their semantics are. Which means you often have to go digging around in the implementation to deduce the semantics, which can be quite time consuming and completely breaks up the thought flow. Using CFCs and having good function names can help, but the function names in particular often end up being unwieldy, because they have to express argument type info as well as the verb in question, not to mention the extreme verbosity and runtime penalty of CFCs.

If you’ve done your job right, after you’re all done with your program, you final shipping version should still be pretty darn close to English. The grammatical rules mandated by your compiler/interpreter are probably rather different than English, and the punctuation rules certainly will be, but with a little effort it’s surprising how close you can get. Everyone who has to read the code later (especially Future You) will thank you.

Information Transfer

I have some information in my mind.  I want to transfer it to another person’s mind.  This is a surprisingly subtle problem.

Obviously I can walk over to them and start taking to them.  Chances are good that I’ll be able to get a pretty respectable information transfer, especially if we both are competent users of the same spoken language.  But what if we’re not?

If it’s information about the physical world, I can probably gesture with my hands, or maybe even point at stuff if it has to do with things that are close by.  If not, maybe a picture is a better choice, especially if I can use color and/or rudimentary animation (a la comic book panels).  Or perhaps non-language sounds will fit the bill.

If my information is anything more interesting than whether I use 1% or 2% milk on my cereal, chances are good that this will evolve into a conversation, where we are both communicating information with each other (and requesting specific information from each other).  We might even move through different media as we go, adapting to the specific information being transferred at any given time..  But what happens when I only want to share part of the information in my mind?

Now we have something interesting.

Any given piece of information can be communicated in a huge number of ways.  For example, I don’t like dill pickles.  If you asked me, I’d tell you.  But let’s say we go have lunch together, and I leave my pickle spear behind.  The same information was transferred, though certainly with less clarity.  If I have lunch at the same place and I always leave my pickle spear behind, should an attentive server who waits on me numerous times stop bringing me a pickle spear?  Hmmm.  If I go in one day and get served without a spear, is the right thought “the server is stalking me” or just “oh, they must have forgotten”.  Perhaps the right thought is “they’re having supply chain problems, and are out of pickles”.  Hmmm.

Once I got asked “Do you eat ice cream?”  I answered like a smart ass, because a) I’m a smart ass, and b) everyone likes ice cream.  A split second later, my brain actually decoded the information being transferred in that question: “I don’t like ice cream, but I don’t know if you do, so I’m offering to get you some even though I don’t want any.”  Hmmm.

Somewhere in there is a line which delineates what is an appropriate use of transferred information, because we all transfer far more information out of our minds than we think it is acceptable for those around us to use.  Obviously the line is contextual: you would probably expect your spouse to react to the tone of “I’m good, how are you?”, but you would be appalled at the new supermarket checker who took it anything other than literal face value, regardless of inflection, tone, or body language.

To say that another way, it is shared context which determines the meaning of any communication.  Yet another way, language only governs a tiny part of the information transferred through the use of the language.  Let alone the information transferred through other media, like action.  Or through lack of action.  “Implicit consent” is the term for that one: they didn’t object, so it must be okay.

Our society runs on an economic basis.  Those with the money make the rules, those without the money can either accept it or get some money so they can help make rules. But in reality, money is a highly non-interesting economy.  The real economy is based on information.  The relative value is far less tangible, and it inherently has huge differences between different entities.  Having a currency just means you can interact indirectly – the lack of a currency means everyone is directly involved with everyone else.

If I know fact X about person Y, I can barter that information for information about other people.  This is called “gossiping.”  We all do it.  If you listen well, you get a double deal, because not only do you learn about the other people, but you also learn about the person you’re trading with.  What do they consider important?  What information do they value?

Police informants are good at this game, but they have a high-risk job with poor pay.  Which is, in itself, and interesting bit of information to internalize.  What it means is money is not the currency of the information economy, even by proxy.  The currency of the information economy is power, whether you’re in the board room, on the playground at a preschool, or running a siege of an enemy in war.  If you have power, you can buy information.  If you have information, you can trade for power, but the exchange rate is horrible.

What is truly amazing about all of this, is that every two-year-old grasps this concept.  “If you don’t give me the ball, I’ll tell mom you stole candy.”  Knowledge is power, and so it is reasonable to expect those with the most knowledge will have the most power.  But it’s not that way at all.  Usually the opposite.  The people with the least hesitation to use their knowledge to grab power will have the most power as long as the economy is stable.  If the economy is unstable, things are different; knowledge is power at the edges of the stability envelope.  When things are unstable people’s inhibitions fade, and they act more aggression and less restraint.

Between a constantly shifting set of shared contexts with other people (and other entities) and just their sheer number, it is effectively impossible for an individual to do the calculus of information transfer in real time.  Fortunately, the past few years have provided us with a wealth of tools (Facebook, Twitter, etc.) that can not only increase the number of people we’re frequently interacting with, but also increase the shiftiness of those shared contexts.

I will leave as an exercise to the reader what three conclusion paragraphs contain.  : )

Mercenaries

I am a mercenary.  This is a weird revelation, as “mercenary” usually carries a “solder” connotation with it.  And usually across national boundaries and/or affiliations.  But it perfectly matches what I am: I solve problems the highest bidder can’t solve on their own.

There is no allegiance in either direction; there is nothing beyond utility.  No mercenary dies and has their employer mourn.  No mercenary succeeds and gets an award.

This seems at odds with the “craftsman” label I’d previously adopted as an apt descriptor, but I’m hesitant to disagree.  An traditional artist/craftsman who works on commission is exactly the same: a mercenary sans violence.

I have a certain set of skills.  They don’t happen to be martial in nature, but they are certainly worth people paying to have at their disposal.  Where is the line?  What is the differentiator?

Fractions!

Fractions can be confusing.  But there there are a few simple rules which encompass everything you could ever want to do with fractions.  In order to use the fraction rules, you have to be able to add, subtract, and multiply ordinary whole numbers.  You’ll also want to keep in mind two rules about arithmetic which are very helpful with fractions.

Arithmetic Rule #1

Any number stays the same when zero is added to it or subtracted from it.

3 = 3 + 0 = 3 - 0

Arithmetic Rule #2

Any number stays the same when multiplied or divided by one.

5 = 5 \times 1 = 5 \div 1

Fractions have a few specific terms which are important to know as well.  Here are the big ones:

Glossary

  • numerator: the number on the top of a fraction
  • denominator: the number on the bottom of a fraction
  • improper fraction: a fraction with a larger numerator than denominator
  • reduced fraction: a fraction that cannot be equivalently written with smaller numerator and denominator
  • mixed fraction: a fraction with a whole number part and a fractional part

On to the rules, of which there are six, but only the last two are particularly interesting.

Fraction Rule #1

Any fraction with 0 as the denominator is undefined (illogical, nonsense, error).

undefined=\frac{2}{0}=\frac{0}{0}

Fraction Rule #2

Any fraction with the same number for both numerator and denominator is equal to 1.

1 = \frac{1}{1} = \frac{8}{8} = \frac{12345}{12345}

Fraction Rule #3

Any fraction with 0 as the numerator is equal to 0 (unless the denominator is also 0 - see rule #1).

0=\frac{0}{1}=\frac{0}{7}=\frac{0}{456}

Fraction Rule #4

Any simple number can be converted to a fraction by placing it over 1.

2 = \frac{2}{1}

This is the same as the division version of arithmetic rule #2, since fractions are just division problems.

Fraction Rule #5

Fractions with the same denominator are added by adding their numerators and copying the denominator. Fractions with different denominators cannot be added together directly (see below).

\frac{1}{5}+\frac{3}{5}=\frac{1+3}{5}=\frac{4}{5}

Fraction Rule #6

Fractions can be multiplied by multiplying the numerators and denominators separately.

\frac{2}{3}\times\frac{1}{6}=\frac{2\times1}{3\times6}=\frac{2}{18}

Using the Rules

Division

Division is often a useful thing to do with fractions, and it’s easy.  Just turn the divisor fraction (the second one) upside-down and multiply.  This is commonly referred to as “invert and multiply”.

\frac{1}{3}\div\frac{2}{5}=\frac{1}{3}\times\frac{5}{2}=\frac{1\times5}{3\times2}=\frac{5}{6}

Improper Fractions

Improper fractions can be made proper by repeatedly pulling 1 (expressed as a fraction) out of the fraction to create a proper mixed fraction.  Remember that every fraction has a “ones” place to the left of the actual fraction to make it a mixed fraction.

\frac{5}{2}=0\frac{5}{2}

The 1 that we want to pull out when converting an improper fraction to proper form is based on the denominator.  By addition rule #1, we can subtract 0 from something without changing it.  And we know that a fraction with the same numerator and denominator is equal to 1 by fraction rule #2.  So if we subtract a one-equivalent fraction and then add 1 back to it, it won’t have changed.

\frac{5}{2}=\frac{5}{2}-\frac{2}{2}+1=\frac{3}{2}+1=1\frac{3}{2}

In this case we still have an improper fraction, so we’ll repeat the process again (and continue until we no longer have an improper fraction).

1\frac{3}{2}=1\frac{3}{2}-\frac{2}{2}+1=1\frac{1}{2}+1=2\frac{1}{2}

So the improper fraction \frac{5}{2} reduces to the proper mixed fraction 2\frac{1}{2}.

Mixed Fractions

Sometimes you have a mixed fraction and want to make it a pure improper fraction.  Get rid of that pesky whole number part.  Improper fractions are usually easier to manipulate than mixed fractions, so it’s common to make everything improper, solve the problem, and then make the answer proper again.

The process of converting a mixed fraction to an improper fraction is quite simple.  Remember that a mixed fraction is the same as the fractional part plus the whole number part.

2\frac{1}{2}=2 + \frac{1}{2}

If the whole number is converted to a fraction, we can just add them and get a fractional result.  We know how to do that because rule #4 says we can slap a 1 under any whole number.  The denominators won’t match, but arithmetic rule #2 says we can multiply by 1 (a special form – namely the denominator over it self – see rule #2) without affecting anything.

2 + \frac{1}{2}=2\times1 + \frac{1}{2}=\frac{2}{1}\times\frac{2}{2}+\frac{1}{2}=\frac{2\times2}{1\times2}+\frac{1}{2}=\frac{4}{2}+\frac{1}{2}=\frac{5}{2}

This process is a special case of adding fractions with different denominators discussed next.

Adding Fractions With Different Denominators

Adding fractions with different denominators requires multiplying one or both fractions by a special form of 1 first (which doesn’t change anything – see arithmetic rule #2). The trick is in picking the right version of 1 to use.  The goal is to get both fractions to have the same denominator.  The easiest way is to multiply each fraction by the denominator of the other fraction over itself (which is a way of writing 1 – see fraction rule #2).  For the problem

\frac{1}{3}+\frac{1}{2}

we want to do this

(\frac{1}{3}\times\frac{2}{2})+(\frac{1}{2}\times\frac{3}{3})

Doing multiplication according to rule #6 yields this

(\frac{1}{3}\times\frac{2}{2})+(\frac{1}{2}\times\frac{3}{3})=\frac{1\times2}{3\times2}+\frac{1\times3}{2\times3}=\frac{2}{6}+\frac{3}{6}

Now that the denominators match (and they always will by following this process) we can add according to rule #5 without difficulty.

\frac{2}{6}+\frac{3}{6}=\frac{2 + 3}{6}=\frac{5}{6}

An there we go, adding two fractions with different denominators by multiplying the parts by a clever form of 1.

\frac{1}{3}+\frac{1}{2}=\frac{5}{6}

Reducing Fractions (Part 1)

Answers to problems, whether in math class or the real world, should almost always be given in reduced fractions.  No one likes to be told \frac{5}{10} when they ask how much pizza is left.  Much better is \frac{1}{2}, but how to get from one to the other?

Since you know that the above rules describe everything you’ll need to do with fractions, it’s probably not surprising that a special form of 1 is integral to the answer. Finding the right form is tricker than for addition above, but there is still a foolproof process.

The first step is to find a non-trivial common factor for the numerator and denominator.  A factor is a number that can be multiplied by another number to get the answer.  For example, 2 and 3 are two factors of 12.  The “non-trivial” means “not including one” since that’s a factor of every number and per addition rule #2 and fraction rule #4 dividing by 1 doesn’t change anything.  We don’t want just any non-trivial factor, however, we need one that is a factor of both the numerator and the denominator (a common factor).

factors of  5: 1, 5
factors of 10: 1, 2, 5, 10

Since 5 is prime, the only options are 1 and itself.  10 has a couple more options, but the only non-trivial common factor of both numerator and denominator is 5.  If you’re reducing a fraction and there are multiple choices for common factors, always pick the largest one.  If you don’t pick the largest one, when you’re done, you only have a partially reduced fraction, not a fully reduced one (and you’ll have to do the process again).  If there aren’t any non-trivial common factors, meaning 1 is the only common factor, then the fraction is already in it’s reduced form.

Now that we have 5 as our factor, we can rewrite our problem by “pulling out” that factor according to rule #6:

\frac{5}{10}=\frac{1\times5}{2\times5}=\frac{1}{2}\times\frac{5}{5}=\frac{1}{2}\times1=\frac{1}{2}

Thus we know that \frac{1}{2} is a reduced version of \frac{5}{10}.  Further, since 5 was the largest common factor, we know that it cannot be reduced any further.

Reducing Fractions (Part 2)

A quick way of describing the above process is to say “divide the same number out of top and bottom and repeat you can’t do it anymore”.  It’s still the same process, but mashing a few steps together and not worrying so much about doing it all in one pass.  As an example, reduce \frac{18}{24}.  Top and bottom are both even, so let’s divide out 2.

\frac{18}{24}=\frac{18\div2}{24\div2}=\frac{9}{12}

Still not reduced, but 3 will divide out of each.

\frac{9}{12}=\frac{9\div3}{12\div3}=\frac{3}{4}

Alright, no other numbers can be divided out, so it must be reduced.  If we’d picked 6 (2\times3=6) initially, we’d have been done in one step, because 6 is the largest common factor of 18 and 24 as discussed above.  Doing it this way meant we had to go through the process a couple times, but we didn’t have to figure out the list of factors and then figure out the largest common factor.

Both approaches are 100% correct and will yield the same result every time.  If you’re doing the reduction in your head while baking, chances are you’ll do the quick’n’dirty way.  If you’re doing the reduction while designing a bridge strut, you’ll probably do it the longer way.  Regardless which you choose, the answer will be the same.

Reducing Proper and Improper Fractions

Reducing fractions and switching from proper and improper forms are all simple conversions.  They’re not changing the fraction’s value, just the way it’s written.  Thus if you have to do both, it’s completely irrelevant which order you do them.

Since a proper fraction’s whole number part is always reduced (whole numbers are as reduced as they come), doing the reduction second is often easier because the numbers in the fraction will be smaller.  But it doesn’t change the math at all; the result is the same.

Domino Functions

At Gram and Gramp’s this weekend we played dominos, and the question came up of counting a set of dominos.  In particular, Gramps wanted to know how many dominos there were in a set with double twelves.

After we were done playing, we lined them all up in the “domino triangle” with and Emery and I figured it out.    The domino triangle is simply an arrangement of dominos with double zero in one corner, the zero-one next to it, followed by zero-two (etc.), and with the double one at the end, followed by the double two (etc.).  Here is a partial rendering of the triangle for our double nine set:

+-+   +-+         +-+
|0|   |0|         |0|
+-+   +-+   ...   +-+
|0|   |1|         |9|
+-+   +-+         +-+

+-+         +-+
|1|         |1|
+-+   ...   +-+
|1|         |9|
+-+         +-+

...

+-+
|9|
+-+
|9|
+-+

To start, let n equal the number of the largest double (twelve, if our case).  We’re looking for f(n), which is the number of dominos in a set with largest double n.  Simply counting the dominos in the triangle gives us a values for our function, but not the one we want:

  n  | f(n)
-----+-------
  0  |   1
  6  |  28
  9  |  55
 12  |  ??

Before dealing with f(n), let g(n) denote the number of doubles in the set.  A quick glance at the triangle will show that the formula for this function is

g(n)=n+1

because there is one double for each

[0, n] = \{x \in \mathbb{N} \,|\,0 \le x \le n\}

Now thinking back to the “domino triangle”, it’s easy to see that g(n) is both the width (base) and the height of the triangle.  If you recall from planar geometry, the area of a triangle is half it’s base times height:

\frac{base \times height}{2}

So a first guess at f(n) would be this:

f(n)=\frac{(g(n))^2}{2}

But that isn’t correct.  Thinking back to the domino triangle quickly shows why.  If you were to take two copies of the triangle to make a rectangle (the reason the triangle area formula works), you’d see that you’d have to offset them by one domino in one direction, so the rectangle is actually g(n) by g(n) + 1.  So the right formula is this:

f(n)=\frac{g(n)\,(g(n) + 1)}{2}

Simplifying by inlining the formula for g(n) yields:

f(n)=\frac{(n + 1)(n + 2)}{2}

This turns out to be the correct formula, and yields 91 when its argument is twelve.  Thus a set of double twelve dominos will have 91 dominos.

What was particularly striking as Emery and I worked through the formulas, is that Emery had more trouble with the larger multiplication (which he hasn’t done in school) than following the function notation, doing the step-wise evaluation of the functions, and even the function nesting.

Branching and Refactoring

Mark Mandel made an interesting post about branching strategies when you have both feature development and refactoring to perform together.  Specifically, he’s wondering how best to ensure you don’t orphan the refactoring if you abandon the feature, since the refactoring might be useful elsewhere.

I posted my comments, and you should too.  Effectively using your tools is vital to success in the software world, and no tool has more potential value (and potential pitfalls) than source control.

Everything you care about having around tomorrow should be stored in source control.  That obviously means your source code, but also includes your build/deploy scripts, editor/IDE config files, design documents, etc.