1

I am trying to get my head around both composed functions and pure functions.

I have an object with a mixture of data. On some values I need to:

  1. remove the value's units
  2. parse string to integer
  3. Convert to value decimal

I have written three functions attempting to make them pure in the sense that they only do one thing but strictly speaking, they are mutating state. I'm not sure how to avoid mutating state though and if this technically makes it not a pure function?

My three "pure" functions are:

function parseValue(val) {
    return typeof val === 'number' ? val : parseInt(val)
}

function stripUnits(val) {
    return typeof val === 'string' ? val.match(/\d+/)[0] : val
}

function convertToDecimal(val) {
    return val / 100
}

I am then trying to compose these functions into one function with the help of lodash compose()

function prepValue(val) {
    return compose(stripUnits, parseValue, convertToDecimal)
}

When I try run this console.log("prepValue", prepValue(weather.current.temperature)) I get the following in the terminal:

prepValue function (){var n=arguments,e=n[0];if(o&&1==n.length&&of(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}

So the main things is,

  1. How can I make my three functions "pure"
  2. How can I compose these functions into 1
Stretch0
  • 8,362
  • 13
  • 71
  • 133

2 Answers2

2

The only mistake you made is not calling the resulting composed method with val as the argument:

function prepValue(val) {
    return compose(stripUnits, parseValue, convertToDecimal)(val);
}
Jamiec
  • 133,658
  • 13
  • 134
  • 193
1

You need to "create the function composition" before calling it.

function parseValue(val) { console.log(val)
    return typeof val === 'number' ? val : parseInt(val)
}

function stripUnits(val) { console.log(val)
    return typeof val === 'string' ? val.match(/\d+/)[0] : val
}

function convertToDecimal(val) {console.log(val)
    return val / 100
}

function prepValue(val) {
    return _.compose(stripUnits, parseValue, convertToDecimal)(val);
}

console.log("prepValue", prepValue('001232'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.fp.js"></script>
rafaelcastrocouto
  • 11,781
  • 3
  • 38
  • 63
  • 1
    Why does `prepValueComp` take `val` and not use it? – Jamiec Mar 14 '18 at 11:11
  • Thanks, that resolves the issue with calling the composed function but I am with @Jamiec, why does `prepValueComp` take `val` and not use it? – Stretch0 Mar 14 '18 at 11:14
  • Still unsure about the pure functions as well. How can I avoid mutating state on those functions? – Stretch0 Mar 14 '18 at 11:15
  • @Jamiec it just composes the functions (no need to handle any arguments) - but I updated the answer to match your solution, since it's way easier to understand. – rafaelcastrocouto Mar 14 '18 at 13:47
  • 1
    @Stretch0 Pure function always return the same output (given the same input) AND produces no side effects. Seems to me that your functions respect those conditions, so you will be fine ;D. – rafaelcastrocouto Mar 14 '18 at 13:49
  • Thanks @rafaelcastrocouto. Good to know – Stretch0 Mar 14 '18 at 13:57