Menu

After Sliced Bread Came Ramda.js (Part I)

It Began in the Age of C#

This is Part I of a two part series on functional programming here's Part II

I used to be like everyone else. I thought I was going to own the world through imperative programming.

I envisioned class hierarchies to the ceiling that could run an entire business. Abstract classes, interfaces, inheritance, getters, setters, this and self.

Private properties, public properties and protected properties. Oh my! There is a lot of shit to keep track of in an object-oriented world.

But no one could tell me anything different at the time. I knew it all!

Then something strange started to happen. Things started showing up in C# that I hadn't used before.

Things like LINQ, with Select, Where, OrderBy and GroupBy. I took to this, like a duck to water.

You could also pass functions around as variables in C#, with Action and Func<T, ...>. Although, this didn't seem as revolutionary to me. After all you've been able to do this in Javascript pretty much forever.

I've been writing Javascript and taking this ability for granted since I was 17 years old.

But, C# was annoying because your functions had to have strongly-typed signatures. In Javascript, you could do anything you wanted.

Generics helped, in that they gave you more flexibility to express yourself. But it was also painful code to write.

If you got over the complex syntax, you were still left with the verbosity of an object-oriented world.

I started to learn about this whole new paradigm called functional programming. I remembered all the times in my career where I was unhappy with the implementation of some code.

And I often found myself asking, "Why can't this class be a simple function? Why do I need all this dependency injection? Why can't I pass the dependencies into my function, as other functions?"

Turns out you can.

It started to dawn on me that imperative programming may not be the end all be all. Functional programming seemed like it may be closer to my natural tendencies.

While C# is a pleasant and fine language, I still felt restricted. I switched jobs and started to ditch C# in favor of working more with Javascript.

Javascript Code Monkey

Not everyone thought that this was a smart decision back in 2012-2013. Some people laughed, and others would still laugh today.

But there is no shortage of work in JS and it is exploding to become the most dominant language on the planet. For better or worse.

So, I did what anyone would do. I started returning functions from my functions.

I thought it was nifty that you could configure the state for a function in the first call:

You'll have to forgive me, in this example I want to show the code as it was before ES6

The enclosed state in the function acted as private data. Yet it remembered the ctr between function calls. At the time this was super handy! Anything that made Javascript seem more object-oriented was a win for me. And this was like private properties in classes.

I also realized that the LINQ methods I loved, were functional constructs of a different name. Select was map and Where was filter. I would later discover many more, including reduce, flatMap, curry and compose. The well was much deeper than I thought.

The Age of Lodash

The next stepping stone in my journey was underscore/lodash. All maps and filters and finds flowed through there for a long time. And let me tell you, I felt pretty slick.

Lodash was a big step. It got me thinking about programming in functions. Things like pick and path, which are functions for accessing data on an object.

That's not something I would have used a function for in the past. Like everyone else I would say person.name instead of _.pick(person, ['name']).

Imperative programmers look at those two options and say, "But person.name is so much simpler! Why on Earth would you ever want to do the second one?"

Well..we will get into this later, but for now think of it like this. In a world, where everything is a function, accessing .name is not a function. It's hard coding some data access.

To be sure, you could write a function like this:

const name = person => person.name; // Not bad, better than person.name
// But you could also do this
import R from 'ramda';
const name = R.prop('name'); // We'll get into this later

But this new paradigm of everything is a function started to invade my psyche.

I even started to wonder, "Is there a good use for the identity function?"

Before this, I thought the identity function was useless. It turns out that I was wrong. It's simple enough to call the identity function. But knowing why you would want to call it is another part of the journey.

I was looking through the code for underscore or lodash at one point, I don't remember which. Anyway, I remember something like this:

One of the things I forgot to mention in the Age of C# was my love of lambda functions. I loved the concise syntax so much that I wanted everything to be a lambda function. But alas, in the land of objects this was not meant to be.

When I started using ES5, I was super annoyed as I was going through lambda withdrawal.

You be the judge:

(x, y) => x + y
function (x, y) {
return x + y;
}

You don't get extra points for typing extra characters.

So ES6 came along and PSSHHHH MIND=BLOWN

It was like Christmas for nerds. It's like oh Javascript, humming along for 20 years, nothing to see here.

And then BOOM:

Arrow functions

let

const

Destructuring

Default Values

Rest/Spread Operator

Template Strings

Native Promises

Modules

Classes?!

Generators?!?!

Proxies?!?!?!

It was incredible! In ES5 the only option was the var keyword shudder. Now we had let and const all in one shot.

It wasn't perfect though. It annoyed me that const didn't make the entire object or array immutable. You can achieve this by recursively calling Object.freeze. But that would have been handy as part of the spec for const itself.

Performance be damned!

Destructuring and the rest/spread operator also allowed very concise syntax: