Can you help me to improve my Functional Programming skills?

adancarrasco

Adán Carrasco

Posted on March 8, 2020

Can you help me to improve my Functional Programming skills?

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!

💖 💪 🙅 🚩
adancarrasco
Adán Carrasco

Posted on March 8, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related