DEV Community

loading...
Cover image for Can you help me to improve my Functional Programming skills?

Can you help me to improve my Functional Programming skills?

adancarrasco profile image Adán Carrasco ・3 min read

This weekend I wanted to refresh what I knew about Functional Programming. I read and took some notes about it, (feel free to add your thoughts in the comments section):

The theory:

There are some principles in regards of FP:

  • FP uses Pure Functions: Functions that its return depends on its input, for example:
    • Math.floor(16) --> 4 // This function will always return 4 when it's called with 16
    • Math.square(2) --> 4 // Same for this function
  • To contrast Impure functions:
    • function() { return x; } // In this case this function will return the value of X but doesn't depend on any input, and will depend on X mutation
  • Do one thing well:
    • Functions that are divided into smaller functions, that are divided into smaller functions until the smallest function does one thing but does it well
  • Small testing, since the functions are really small it's easy to keep them tested, rather than trying to test really big functions
  • Immutable data/state, each function should return a new object. Those object data structures are: [] or {}, Arrays or Maps
    • In terms or performance it's not affected because the compiler most likely knows that non changed values will have the same hash (not get to deep into this)
    • Using immutable data reduces bugs because the new object is the result of your called function, making easy to have different states across time for your data, for example:
      • emptyCar = createCar();
      • carWithOneBook = addBookToCar(emptyCar, myBook)
      • carWithTwoBooks = addBookToCar(carWithOneBook, myOtherBook)
    • In the previous example it's easy to do time travel because your objects are independent one to the other, so you know that if the addBookToCar works well, it'll work well in all the cases, plus testing that function will be easy as well.

The practice

A while ago I was in a phone interview, the interview was split in two sections: Technical questions + Coding Challenge. I solved the challenge applying what I learned from this FP weekend.

Coding Challenge

Part 1:

Given an object with the keys in kebab-case, convert the keys into camelCase.

Part 2:

Do it for nested objects.

Sample object:

const userData = {
  "first-name": "John",
  "last-name": "rough",
  "social-security-number": 9083910,
  "pets-details": {
    "cats-details": {
      "how-many-cats-are": 3,
      "cat-data": [
        {
          name: "Charlie",
          age: "8 months",
          "hair-color": "red"
        },
        {
          name: "Angel",
          age: "2 years",
          "hair-color": "white"
        }
      ]
    }
  }
};

I divided the problem into two. First...

Convert a string from kebab to camelCase, the functions created below are returning a new object, are simple, and do one thing well:

// Create a function to split a word into arrays by a char
const splitStringByChar = (key, char) => key.split(char)

// Create a function to capitalize an array of strings
const capitalizeArray = stringsArray => 
  stringsArray.map(key => key[0].toUpperCase() + key.substring(1, key.length))

// Create a function to join an array
const joinArray = stringArray => stringArray.join("")

// Create a function to lowerCase the first letter of a string
const lowerCaseFirstLetter = key => key[0].toLowerCase() + key.substring(1, key.length)

// Now run it altogether
const camelCaseString = toCamelCase => {
  const splittedKey = splitStringByChar(toCamelCase, "-")
  const capitalizedArray = capitalizeArray(splittedKey)
  const joinedKeys = joinArray(capitalizedArray)
  const lowerCasedFirstLetter = lowerCaseFirstLetter(joinedKeys)
  return lowerCasedFirstLetter
}

And second... a function to convert the object to camelCase:

// Create a function to convert the object to camelCase

const convertToCamelCasedObject = obj => {
  // Create the new object to be returned
  let camelCasedObj = {};
  Object.keys(obj).map(key => {
    const newKey = camelCaseString(key)
    // Checking if the object is an object and needs to be converted as well
    if (typeof obj[key] === "object") {
      camelCasedObj[newKey] = convertToCamelCasedObject(obj[key]);
    } else {
      // Pointing the value to the new object[key]
      camelCasedObj[newKey] = obj[key];
    }
    return camelCasedObj;
  });
  return camelCasedObj;
};

Conclusion

FP is good to change the way that you think or solve problems, by design it's good for Distributed Systems.

What would you change to make it better/simpler? What would you add about FP?

Thanks for reading!

Discussion

pic
Editor guide
Collapse
pradosh987 profile image
Pradosh Gaonkar

Sorry to point out but writing small - small functions is not all together functional. You can try lodash flow to compose camelCaseString using those small functions, that would be functional approach -> , "Composition".

Collapse
adancarrasco profile image
Adán Carrasco Author

Hi Pradosh - Good to know about lodash and flow, I wasn’t familiar with those! However, in this case as it was an interview challenge I wasn’t allowed to use any third party utility methods, but to solve it by myself. 😅

Collapse
pradosh987 profile image
Pradosh Gaonkar

Oh Okay, you know you can implement something like flow, this is just POC and not tested either

export const flow = (methods: Function[]) => {
  return function(...args) {
    return methods
      .slice(1, methods.length)
      .reduce((acc, method) => method(acc), methods[0](args));
  };
};
Thread Thread
adancarrasco profile image
Adán Carrasco Author

This is really cool! Thanks for sharing! 💪🏽💪🏽

Collapse
adancarrasco profile image
Adán Carrasco Author

Now I see what you meant following the book that Bryce suggested below: mostly-adequate.gitbooks.io/mostly...

Thanks Pradosh!

Collapse
brycedooley profile image
Bryce

Hey Adán, I think this is a good intro into FP! One resource that I really like that covers more advanced topics is: mostly-adequate.gitbooks.io/mostly...

Collapse
adancarrasco profile image
Adán Carrasco Author

Hey Bryce - This looks great! Thanks a lot for sharing! Definitely helps to improve my skills! 💪🏽 Appreciate it!