Pure pipeline
How to fetch and submit this exercise
Once: install the tool and connect your account.
curl -fsSL https://gonomicon.com/install.sh | sh
gonomicon loginEach exercise: download it, edit the file named in the instructions, then submit.
gonomicon fetch fs-week-2/02-07-pure-pipeline
cd 02-07-pure-pipeline
gonomicon submitPure pipeline
Rewrite a function that secretly depends on the outside world into one that only uses its own inputs, then write a function that chains several small steps into one.
Worked example
Here's an impure function, the way the starter's addTax is impure:
let greetCount = 0;
function shout(word) {
greetCount++;
console.log(`${word.toUpperCase()}!`);
}
shout changes greetCount (a box outside itself) and prints instead of returning anything - call it twice with the same word and you can't even get the result back, only watch greetCount climb. The pure rewrite uses only what's handed in, and returns the answer instead of printing it:
function shout(word) {
return `${word.toUpperCase()}!`;
}
Now here's compose, chaining pure steps together:
function compose(...fns) {
return function piped(input) {
let result = input;
for (const fn of fns) {
result = fn(result);
}
return result;
};
}
const trim = (text) => text.trim();
const exclaim = (text) => `${text}!`;
const shoutLoud = compose(trim, shout, exclaim);
console.log(shoutLoud(" hello "));
console.log(compose()("unchanged"));
HELLO!!
unchanged
shoutLoud runs trim, then shout, then exclaim, each one feeding its result to the next. compose() with nothing to chain just hands back whatever it's given.
Your task
Rewrite the starter's impure addTax(price) as a pure function addTax(price, percent) that returns price + price * percent / 100 using only its two parameters - no outside variable, and nothing printed.
Write function compose(...fns), exactly as in the worked example's pattern: it returns a function that passes its input through every function in fns, left to right, and with no functions at all it returns the input unchanged.
Rules
addTaxmust not readtaxPercent, writelastTotal, or callconsole.log- delete all three from the file along with the old one-parameter version.addTax(price, percent)gives the same answer every time it's called with the same two arguments, no matter what was called before it or what order things ran in.compose's returned function calls each function infnsexactly once per call, left to right, each one getting the previous one's result.- Neither
addTaxnorcomposemay print anything or change a variable that lives outside the function.
What you'll practice
Turning a function with side effects into a pure one by passing in everything it needs, and writing a higher-order function that chains functions together using a closure over the list it was given.
Run it
gonomicon fetch fs-week-2/02-07-pure-pipeline
cd 02-07-pure-pipeline
gonomicon test
gonomicon submit
Hints
- A pure addTax should only ever look at price and percent - if your answer changes when some outside variable changes, something outside is still being read.
- compose(...fns) can keep a running value in a loop: start it as the input, then for each fn in fns, replace it with fn(the running value). With no fns, the loop runs zero times and the input comes back untouched.
- Delete taxPercent, lastTotal and the console.log call entirely rather than just not using them - the finished file shouldn't mention them at all.