4 ms·
Suppose I have a procedure that plays a piano: const playTwinkleTwinkleLittleStar = (piano) => { piano.play('c'); piano.play('c'); piano.
by substation13 4y ago
Suppose I have a procedure that plays a piano:
const playTwinkleTwinkleLittleStar = (piano) => {
piano.play('c');
piano.play('c');
piano.play('g');
piano.play('g');
piano.play('a');
piano.play('a');
piano.play('g');
};
Now I want to have every note played twice. How can I do that?
Usual OOP solution is to have a wrapper on piano:
const playItTwicePiano = (piano) => {
return {
play: (note) => {
piano.play(note);
piano.play(note);
},
};
};
playTwinkleTwinkleLittleStar(playItTwicePiano(piano));
However, if we instead return a description of what to do, such manipulations compose far more easily:
const twinkleTwinkleLittleStar = () => {
return [ 'c', 'c', 'g', 'g', 'a', 'a', 'g' ];
};
const playItTwice = (sequence) => {
const xs = [];
for (const x of sequence) {
xs.push(x);
xs.push(x);
}
return xs;
};
And it's easier to test:
it('should start with c', () => {
const xs = twinkleTwinkleLittleStar();
assert(xs[0] === 'c');
});
Wherever you are building a complex mock for testing consider defunctionalization instead.
- b0afc375b5 4y agoAhh I see. So if I may use an analogy: I have an html page with all my details, etc. Then say I want to create a markdown version of it, or a pdf version, or a docx version. The first approach would be to manually rewrite my details to each format, as markdown, as pdf, as docx, essentially duplicating work each time. The second approach, which is akin to defunctionalisation, would be to separate my details (data) from the format. So that would mean I would store my data in json format, then use a cli tool/program to generate it in html format, in pdf format, or in docx format. I hope I got the basic idea right.
- cutthegrass2 4y agoThis is a great example, and feel the concept has "clicked" with me because of it. Thank you!