This blog post is also available on the Fortnox developer blog.
TL;DR: It’s actually pretty amazing how far you get using just functions.
For almost a year now I’ve had the chance to spend my time at work developing apps with React Native, and it has been a fun ride so far. Developing for the front-end is really refreshing for a back-end code monkey like me, and the instant-feedback you get from changes in the user interface is rewarding. Another cool thing about programming in JavaScript is that I get to write functional code, and so far I haven’t missed object-oriented building blocks like classes at all.
In a way, I find it to be liberating that I don’t have to worry about whether a particular method should be a class or an object method, or if the method makes sense in the context of a particular class. In functional programming, a function is just a function, and you assemble your program by composing functions to make the greater whole do useful things. Right now, I’m at a stage in my thinking where I’m starting to question the purpose of many of the concepts that we find in object-oriented programming. My thoughts can be summarized somewhat like the following: if I can write my business logic with just a few simple and reusable constructs, why should I feel compelled to use the more complex object-oriented toolbox?
I know, I know, there are no silver bullets, so functional programming (probably?) isn’t one, but for many problems we as programmers are trying to solve I think it is fair to question what we gain from the mental overhead that e.g. classes in object-oriented programming bring. In the object-oriented toolbox we find stuff like classes, class instances, instance methods, class methods, abstract methods, class inheritance, a myriad of design patterns to aid in the design of these abstractions, and much more. In the functional toolbox we find, well, functions. I think that in limiting the number of unnecessary abstractions we have a chance to reduce complexity in our code, and that’s something desirable, right?
Another cool effect from not programming with classes is that we get to think about data and behavior as two distinct things. Let me try to convey my thoughts of why this is neat via an example. In e.g. Clojure, a common way to represent some aggregate structure is to use a map. Maps are key/value data structures, just like objects are in JavaScript. Below we have an example of a map with two keys:
{:firstName "Martin" :lastName "Moberg"}
For a particular problem we’re trying to solve, the above example could be a perfect data structure to represent a person. It does not carry any behavior, it’s just key/value structured data. And it’s not an instance of any pre-defined class used as a cookie cutter because, again, it’s just structured data. Just toss the map as input to any function that know how to deal with maps to start working with it, and in Clojure, there are plenty of those. And we can choose to apply this way of thinking in JavaScript too.
Where I am right now in my understanding of programming, I’m thinking, that for many problems, programming with functions along with a way to control what parts of your code that gets exposed from a module gets you really, really far. In JavaScript, we have the export statement that lets you decide what parts should be included in the module’s API. With some opt-in static typing for arguments and return values I’d be an even happier JavaScript programmer, but still, as a programmer that have spent years with object-oriented programming, I find it pretty amazing how far you can go using just functions.