The systemic failure of the IT industry

Let me tell you a story.
This is a story about a brand new software project, using last technologies and mobile devices, a really important project for BigCorp. They want to use this new product as a vitrine to show how good they are to create mobile applications.

The gold rush

BigCorp invests a lot on this project, quickly a team of 15 people was created. 1 project manager, 1 assistant project manager, 1 scrum master, 3 business analysts, 3 testers 1 architect and 5 developers.
Everybody wants to be in, the global mood was very good, all the requirements were clear, this will be the best project we’ve ever seen.

Sprinting to reality

After 3 weeks it was time for the first release… And the first deadline was missed. Less than half of the expected User Story were produced, and the code was really brittle.
During the retrospective (where project managers and business analysts were missing because they are busy) it was decided to do less automating testing and less refactoring, because it was obviously a lot of time invest in unproductive stuff. We need to deliver more User Stories.

Wall ahead

The project is now 1 year old. Half of the team was replaced. One of the business analysts was fired because he “screwed” up a demo to the company board. The mood is no longer that good. The requirements were not clear enough after all, it’s even hard to know who the users of the system are. The technology is no longer shiny because 2 new frameworks have been created during the year and seem much cooler.
The software is still really brittle, which leads to even less refactoring because “we don’t want to break it”. New attempt to add unit tests were made, but it “costs” too much, this is obviously “not possible for us to do unit testing”. Retrospectives were stopped, because who can afford one unproductive day?

And yet another awful legacy

The project is now 5 years old. No one from the initial team is still working on the project. The team is only 1 developer now, half-time. We ask her to “maintain and fix bugs” that users will find. The code is a nightmare to work with. We have no idea of what is done, and how it’s done.
It creates lots of frustration for the developer, and for the user.

Failure = lesson learned?

Not really, it’s just a normal software project in BigCorp. It’s actually so common that most people in BigCorp think that software projects are always going this way. From developers to the top management, no one is shocked anymore, this is how software project works.

What can we learn from BigCorp?

Software of big companies and governments are usually pretty bad. Because the product is just a mirror of the system that produces it. A system with lots of hierarchy, politics, arbitrary deadline and silos. A system with no idea of the level of communication and collaboration required to achieve great software. A system where the customer does not really exist, because the company is too big to care about them. A system that erases the creativity required for good software.

Most companies have systemic errors. They produce bad software, no matter how skillful the employees are, because the system pushes them in bad habits and make them believe that this is the only way to go.

This explains why it’s so hard to create good software. It’s not only about technical practices and principles, this is also a lot about the system in which this software is produced.

PS: Thanks to Anthony Cassaigne, and on the recommendation of Woody Zuill, I finally read the paper “Nobody Ever Gets Credit for Fixing Problems that Never Happened”. I highly recommand it, many echoes with this article !

 

The violence of software programming

I have no doubt than many jobs are complicated, but I’m convinced that software development is also a really violent one. Mostly because it does not seem violent at all at first sight. But let’s dig a bit in our world to have a better understanding of this “geek job”.

The constant learner

Every seasoned programmer will tell you how important it is to keep your skills sharp. Technologies are running really fast, you have to learn almost daily in order to improve.
Universities are many years late. As a young graduate, you might learn some programming languages, but you will have no clues about how hard building software is. Writing the code is just the emergent part of the iceberg.
In terms of personal investment, this is comparable to what good physicians must do. We need to read many books, to attend conferences, to listen to podcasts, to do regular training…
Everybody acknowledges how hard it is to be a physician, very few acknowledge that being a software developer might require the same kind of learning habits.

The developer paradox

Of course, being hard does not mean it sucks. But most universities and companies explain to us that we can’t stay “developer”. As if it was something to be ashamed of. We need to “evolve” (which often means we need to become manager and fill Excel sheets instead of delivering software). If you don’t take this opportunity to “evolve”, you might stay at the same low salary, which creates a violent paradox.
You must work a lot in order to be good, and you don’t earn much. Basically, you’re considered as one of the lowest roles in hierarchy, even though you’re developing the software that makes the company earn money. This lack of alignment between what you give to the company and what you get as feedback might be so hard that it could lead to burnout. In better case it might just lead to disengagement, either as an old developer or as a new manager. In “best” cases, it leads to deep questioning about your job and how you want to practice it.

Extreme Programming

I once tweeted that XP should not use extreme, because doing good software might not be considered as something extreme. But I think I was wrong, these are extremely violent practices.
Test Driven Development will reveal how bad your architecture and coding habits are. Unit testing will demonstrate how bad you are at predicting software behavior. Pair Programming will show you daily the gap between you and your co-worker. It forces you to reveal how weak you are, because sometimes you don’t remember some simple syntax or shortcuts.
If you can push software each day in production, it will accelerate the feedback loop of unhappy users. If you use mob programming, any malfunction in your team will lead every mob session as a painful disaster of people arguing for ages instead of coding.
These practices are extreme, because following them daily require a deep level of mastery, an egoless approach of your job and a strong ability to communicate at the same time. Three skills that are not common on the same person. Even less common is to find them on each member of a team.

Fighting the violence

How can we be happy as a software developer then?
In theory it’s easy: we want to reduce the developer paradox. In other words, we want to work in places where our job is understood.
In such places, salaries might be higher, but it’s mostly a state of mind. In such places we encourage constant learning, either by helping you to attend conferences or by buying any book you feel useful for your job. We might give you some time at work to practice and learn. In such places we don’t push you to become manager, because we understand the value of seasoned developers. In such places your co-workers will make you feel safe, safe to show that you don’t know everything, safe to fail. In such places nobody will show you how better or higher in hierarchy they are, because they have understood that building software is such a hard thing, that only great team can achieve it. In a great team, everybody feels proud to work with awesome teammates.

If you are working in a place where you can feel this experience, this is great, and your duty is to help more developers to achieve it. Otherwise, do yourself a favor, leave your job and find a better one. The world is full of great companies having a hard time to find good developers.

 

When business does indeed sucks

In a recent article I explained why I think we should all be Domain Driven.
I get some interesting feedbacks on the “business sucks” syndrome.

Indeed in this previous article my point was to make technical teams aware of the necessity for business to change in order to constantly fit its market as much as possible. But sometimes business does indeed suck.
Let’s take a few examples I’ve met in 10 years as a software developer.

The never-ending prototype

One of the most common business error I’ve met is the fast hacked prototype that goes into production, and then evolve in a maintenance nightmare because you know… It works, why should we rewrite it?
To be fair, this is one of the hardest things to do when you start a new business. The first step is to look for a market fit. This can take years, and you must be very fast to test your hypotheses. You are sending many prototypes in production, and most of them will only live for a few months. At this step this is perfectly fine.
Of course the problem arises when, finally, you find your market fit. The growth is here, more and more customers are using the prototype. This is when courageous entrepreneurs should throw all the technical stuff, and write it from scratch with more money and knowledge. More money because growth means that we can get money, more knowledge because many technical limitation from the prototype will be clear, and a more robust product can be built from this knowledge. As Francesco Cesarini would say: “A programmer will fully understand a problem only when he fixed it at least once”.
What happens instead is that the money is used to growth even faster, the prototype has to scale even if it’s not done for it, and the technical team has to deal with many domain and technical problems that should have been avoided.
Here starts the famous “we don’t have time for tests, we have to deliver”.

Head in the sand policy

This error concerns mainly big corporation. But I’m sure you already were as surprise as me to see how fast politic can become important even in small companies.
The company is big enough to have a few layers of management and different services. Because the top managements want to keep control of the company, he’s requesting the famous KPIs. Each service has different KPI, and quickly enough, most employees understand that they can earn more money by targeting the KPIs than by trying to achieve the best possible product for their customers.
Worse, KPIs might be highly destructive when the KPI from a service leads to more burden for another service.
For example, if one of the KPI for the support team is to take as many call as possible, they will quickly classify lots of tickets as critical bugs to be managed by the technical team. Just because it’s faster than trying to understand what happens to the user.
As a result the technical team might have a more work and the global delivering flow of the company will be slower.
Each service prefer to keep their head in the sand rather than trying to collaborate with other ones.

Enterprise Standards

Another widely spread error is the standardisation spree. Usually in the name of costs hunting (even if it’s more about power and control, because in the end it often cost more than local auto organization), the company imposes some methods, tools and/or architectures, without knowing if it makes sense for a given context.
For instance a policy will enforce all the teams to work with SCRUM. Or they will impose a common integration platform for the whole company.
It often happens when management confuses practices (SCRUM, Unit tests, continuous integration…) with principles (being more agile, code quality, fast feedback…).
Many consultants actually increase this confusion and deliver what they (think to) know instead of what the company need in its context.

So should we be domain driven when they suck?

I think my point in the original article is still valid. In the end the problems I described here is just that sometimes, the business itself is not Domain Driven. In the sense that they are looking for immediate profit or power and control instead of caring about the domain.
Thus we should all be Domain Driven, especially the business part of the company. And writing it like that is a bit depressing, but yeah, quite often the business part of the company does not really care about the domain itself.
In this case, we should help them to be more Domain Driven, or just leave them and go work in more healthy environment 😊

 

Dry should not be technical

Do you know the “I talk about it so often that I believe I already wrote a blog post about it” effect? It happens when you talk about something so often that you are sure to have a blog post somewhere to explain it more deeply 😉
It happens to me recently about DRY (Don’t Repeat Yourself). In a twitter conversation where I once more had to explain why DRY should not be technical. I’ve looked for my blog post about it. Just to find that it doesn’t exist yet… Thus, here it is.

DRY ?

According to Wikipedia, DRY is a principle of software development aimed at reducing repetition of software patterns, replacing it with abstractions or using data normalization to avoid redundancy.
One of the main arguments for avoiding redundancy is to improve software maintenance. It seems great right? If you have to modify the code in two places instead of one when you want to change a behavior, you increase the risk of error.

Coupling ?

According to Wikipedia, coupling is a measure of how closely connected two routines or modules are.
Low coupling is often a sign of a well-structured computer system and a good design, and when combined with high cohesion, supports the general goals of high readability and maintainability.

The main issue with DRY when apply dumbly is that it increases coupling (which is a code bad smell). Because, sharing the same code between two things create a coupling between them. Too many developers consider that two identic lines of code in the system must be merged and shared into one, because we want to be DRY.
The key to have a smart refactoring in order to be DRY is to care about cohesion.

Cohesion ?

According to Wikipedia, cohesion refers to the degree to which the elements inside a module belong together. In one sense, it is a measure of the strength of relationship between the methods and data of a class and some unifying purpose or concept served by that class. In another sense, it is a measure of the strength of relationship between the class’s methods and data themselves.

If we share code between two modules with low cohesion, the result is a dramatic decrease in maintainability. We take the risk to break the second module, each time we want to change something in this shared code for the first module.

DRY Should not be technical

An easy way to avoid this pitfall is to consider the business concept of what you want to share.
If the business concept is the same for the two modules, you can share it with less risks, because it should evolve for the same reason in the two places.
If it’s just a technical concept, sharing it may be dangerous, because both modules will probably need different updates depending on their use cases.

Of course it happens because, no matter if you know/want it, you’re Domain Driven. It means that your module will evolve because of business requirements. Low cohesion means the two modules have different business purposes, then will evolve very differently. And we don’t want to share something between two things that evolve very differently.

Let me recap

  • To be efficient, DRY must be combined with high cohesion (and few people remember that)
  • An easy way to detect cohesion is to care about the business goal of each module

I do believe it’s one of the first good practice easy to apply that can radically change your code maintainability day after day.

 

We’re all Domain Driven

Believe it nor not, one of the main reasons why software exists is to help companies to make money. These companies earn money because they have a business. Usually they sell something to customers, in order to solve a problem for them.

A software developer that doesn’t care about the business is missing an important point. It creates a mismatch between the business and the software. This mismatch makes the system harder to maintain, because even if we don’t want it, we’re all domain driven.

The burden to maintain this system lies on the IT team. In other words, denying the domain aspects of the software is a way to shoot yourself in the foot.

How to recognize this mismatch

When this mismatch happens, there are many patterns that emerge.

One of them is the “business sucks” syndrome. You can recognize it when the IT team is always complaining with arguments like “they don’t know what they want!”, or “they always change their mind”, and even “they sell something that doesn’t exist!”.

Of course they sell something that doesn’t exist, otherwise how would you know what to build?
Of course they change their mind, because they are constantly testing and adapting to customers.
Of course they don’t know what they want, precisely because it doesn’t exist yet, and it’s not trivial to know what’s possible to do with software.

Let me raise a warning though, selling something that doesn’t exist is totally legitimate from a business perspective. But stressing someone else because a business man took unrealistic commitment with a customer is not.

It’s the business job to sell stuff that doesn’t exist, and then to handle customers expectations until it’s delivered. It shows why it’s a team work. Without the production team, the business man has only dreams to sell. Without a business man, a production team has no one to sell the product. The sweet spot is to sell something that doesn’t exist, but that can be done quickly. In other words, something that “almost exist”.

How to handle this mismatch

The solution is to let the business drive your software. To let your domain drive your design. Good news, there is a bunch of literature about Domain Driven Design!

It can be resumed by: organize your code, then your teams, then your company around the business, and you will improve software maintainability and customer satisfaction.

It seems trivial, but it isn’t. Trying to know at every line of code which business purpose it serves is hard. Trying to know at every meeting which business purpose it serves is hard. Trying to know if the company has a structure that serves the business is hard.

It’s even harder because as the business evolve, the whole structure (company, teams, software) should evolve as well.

To be fair it’s so hard that I don’t think any company can achieve it. But trying to constantly improve following the principles of Domain Driven Design is good enough to be far better than the average.

 

The Road Less Traveled

“Confronting and solving problems is a painful process which most of us attempt to avoid. And the very avoidance results in greater pain and inability to grow both mentally and spiritually”. Does it remember you something? Root cause analysis, Domain Driven Design and so many practices in IT are about solving the problems instead of fixing the consequences. Actually, I think it’s the difference between a young and an experienced developer. The young dev wants to hack a solution as fast as possible. The experienced dev will use this time to analyze the problem, because when it is done correctly, building the solution will be “trivial”.
The passionate thing about The Road Less Traveled by Scott Peck is that it’s a book written by a passionate psychiatrist, drawing heavily on his own professional experience. It’s all about human relationships, and the incredible number of lessons from this book we can directly apply in our software developer job should be a huge warning for people arguing that we must be technical monkey.

Discipline

Seems familiar again? That’s the very first section of his book. Through different experiences he explained how discipline is important to grow as an adult, and how most of us stay children. Each time we refuse responsibilities, each time we look for the easy solution instead of a more permanent one, each time we take a direct gratification instead of investing in a delayed but greater one, we are acting like children. This book brings us this hard truth: being an adult is not fun, and nobody will help or prepare you to become one. But fleeing our responsibility results in pain. That’s why discipline is required to grow as an adult, even if it hurts.

Love

This one is a bit far away from software development, but important for mind growing. In a nutshell, the author tries to define love: true genuine love. Not the one you think to know when you’re 16 years old and discover the opposite sex. True genuine love is the unconditional love we have for our children for instance. This kind of love does not require anything from the loved one, it does not have to be mutual. It’s just something you give to someone. This kind of love is hard, and usually not what we’re used dealing with. It excludes the myth of “love at first sight”, because genuine love requires a deep understanding and respect of the loved one. The author explains that this kind of love is the one that can stand for life.

Religion and Grace?

The two other sections use some words that make me very careful… Religion, Grace… I believed this psychiatrist was a scientific man? But the reading was still really pleasant. The author is not trying to convince you of anything (even if he personally believed in god, or at least in something bigger than us). Again, he drew on his experience to relate some stories were religion drive people crazy. And some stories were these same religions literally save people. And grace is about all these things that we observe but can’t explain. What’s the link with psychiatry and psychology? Well, to be happy you need to accept that you won’t understand the world.

Yet another must read

It will not be the book that will make you a better developer technically. But we can feel the passion of the author through chapters, and his feedback on human relationships are priceless. It helps me to realize how much the job of a software developer is driven by people’s relationships, more than by anything else.

I highly recommend it.

 

I did often fail

I like to read technical blogs. I do it daily since a few years now, and I really enjoy the way in which this community is sharing in order to improve. I would argue that it’s an efficient way to raise the bar of the software industry. There is one thing I regret though: we almost never talk about our failures. We talk about concepts, implementations, and how we think the industry can be better. But we very rarely share about our failures. I do meet failure more often than success. I think it’s a good idea to share about it, because people who read us without working with us may think that we are kind of “super developers”. We are not. Let’s talk about how we fail and why.

When the pressure comes back

I’m bad to work under pressure. I mean like really bad. My brain is just in panic mode and seems to hide data from myself when I’m stressed. I can physically feel the pain when I try to focus in this situation.I have no way to clear out my ideas, my mind goes in many directions and I almost systematically miss obvious stuff. The usual result is that I push code I should never have committed (like code I changed “just for test”), and/or that I need lots of time to sort out simple problems. In this situation, I may bypass some quality practices because you know… We’re in a hurry!

Where does this pressure comes from?

In ten years, I learned to say no, thus it generally does not come from other people. It’s usually my own commitment due to my own estimation. And in ten years I learned to be very careful about my estimation.I know that unexpected things happened all the time. And still, the pattern is almost always the same. First I commit to a deadline that seems correct to me.Then I’m not as fast as expected, and I feel like I lose time on trivial stuff.Finally, I feel guilty that it takes “so long” for this “trivial” thing. I feel like it’s “almost done” and work extra hours in order to finish it. I see the pressure growing. At some point, I bypass some quality practices (no one is here to validate my pull request after 8 pm anyway… And do I really need this test? This piece of code seems so simple…)

Consequences

The consequences are most often the same. The few hours of extra work cost me a few hours/days to fix it. My colleagues usually look at the PR in the morning, and it took them a few minutes to spot my mistakes. That was the cost of my extra work. That is how productive I am when I work 10 hours a day.

A developer with good practices

It reminds me this truth from Kent Beck I know for a while: I’m not a great developer, I’m a developer with great habits. Losing these habits make me much less efficient. And even after 10 years as a software developer, it’s still easy for me to discard these practices.

Being a code crafter is a continuous challenge.

 

Migrating Database from ClearDB to MySQL for WordPress in Azure

You know this feeling when something that should take an hour finally take a day? That’s what happens to me when I tried to move my database from ClearDb (because it’s no longer included in the MSDN subscription). I wanted to use the free MySQL in App instance instead, and I wasn’t able to find a simple and complete guide for that. Hopefully this one will avoid some pain to some people.

About ClearDb and MySQL in App

ClearDb is a Saas service for MySql database. They used to host the WordPress azure app service. But now we have to pay for it as it’s no longer included in the MSDN subscription. An alternative is to use the free MySQL in App database provides by azure with app services. Beware that this Database is normally for testing purpose, they are not recommended for production. But for a WordPress site hosting a blog like mine, I think we should be fine.

Let’s save everything

The first action to do is to save your website (Just in case :)):
YourApp -> Settings -> Backup

The second action to do is to save your Data from ClearDb. The easiest way I found was to activate MySQL In App:
YourApp -> Settings -> MySQL In App

Click on “activate”. Then you would be able to click on “manage” in the upper left corner. It will open your php MyAdmin UI for your web app. You normally have (at least) two server available in the server list in the upper left corner. One is for your ClearDb database, the other one is for the localDb from your MySql In App.

You can select the ClearDb server, select your WordPress database, and use the export button to get a sql script from your DB schema and Data.
Now you can select the MySQL In App server (localhost), and use the existing localDb, then import the sql script that you get from the ClearDb database.

Reroute WordPress to the new Database

Last but not least, you need to change the wp-config file from the WordPress site to use the new MySqlApp database.
Go to https://[yourwebsite].scm.azurewebsites.net/ to see your Kudu UI. Using the Debug console, you will find your wp-config file in: D:\home\site\wwwroot.
You need to change the following values:

define('DB_NAME', ‘localdb’);
define('DB_USER', ‘azure’);
define('DB_PASSWORD', 'password’);
define('DB_HOST', ‘127.0.0.1:port’);

To know the value for the connection you can check the ConnectionString for the My SQL App in D:\home\data\mysql\MYSQLCONNSTR_localdb.txt
It should looks like this:
Database=localdb;Data Source=127.0.0.1:port;User Id=azure;Password=password
Just extract your database name, user id, data source (host) and password.
Note that you need to precise the port for the host.

Cleanup

You can now remove the ClearDb connection string from the app service:
Settings -> application settings, connection strings
And of course stop your potential ClearDb subscription!

Hope it helps.

 

 

 

 

 

 

 

How do you teach DDD?

The more I work using Domain Driven Design in my daily job, the more I face how hard it is to teach. What’s the matter here? Why is DDD so often misunderstood? Of course, we can just consider that it’s a complex thing, hence requiring lots of knowledge and practices to be mastered. But let’s be more constructive and try to find the root problem in the domain of DDD teaching.

Like always, we need to agree on the terms we’ll use through this post.

Reminder: DDD

DDD is about tackling the complexity of the domain in the heart of software. It means that, in an ideal world, your software must be as complex as the problem it’s solving. Plus, the problem you solve must be the most valuable possible thing for your company. DDD provides patterns to address these points (spoiler alert: it’s not an easy task). Implementing DDD is all about analyzing dependencies.

Reminder: Tactical patterns

Tactical patterns are the most concrete parts for us developers because it’s about code! It’s a set of technical tools to concretely apply a DDD approach where it matters the most. These patterns evolve quickly, at the same speed as good practices. A well-known example is the repository pattern. Tactical patterns help to know how to build each part of a business.

 

Reminder: Strategic patterns

Strategic patterns are more abstract. They allow to categorize the domain (the business) into subdomains, in order to know how to build context of applications around it. Each context has a specific common business language (the ubiquitous language) and use precise way to communicate. Does a context impose things to another context? Do they share a kernel? How do they communicate? All of this can be captured using strategic patterns. They help to know what the different parts of the business are, and how they interact.

 

The DDD usual problems

Since I start studying DDD in 2012, I meet two recurrent problems.
The first is that newcomers (including me) do not know where to start. They can feel DDD is huge, but the reference books are intimidating. The community of smart peoples using words you never heard before seems nice, but you feel so stupid around them that it’s hard to stay.
The second one is that most people (yep, was me again) will not grab the duality of strategic versus tactical patterns at first glance. Worse, they may stay focus on the tactical patterns because they seem more concrete. We already know some of them, like factories or layered architecture. The consequence could be that we overlook the strategic patterns.

Root cause analysis

Following the principles of good design, how can we improve DDD so that these mistakes are harder to make for newcomers? Let’s use my (almost) secret silver bullet for that.
In my domain of DDD teaching, I believe there are two sub domains: one is about tactics, the other is about strategies.
An efficient implementation for teaching DDD would map one bounded context for strategic patterns, and one context to for tactical patterns. We have several clues to justify this implementation.
First clue: different languages. The two contexts have specific ubiquitous language.
Second clue: different life cycle. Tactical patterns evolve quickly. Most of the patterns from the blue book can be replaced by more recent patterns like CQRS/ES or hexagonal architecture. Strategic patterns are much more durable.
Third clue: the level of abstraction is not the same in both contexts.
Last clue: the strategic context is much more important. It’s my core domain, the core values I want to share when teaching DDD. There is a clear dependence between my contexts. Tactical patterns are important but will bring much less value if I teach them alone.
I now have a part of the answer about why DDD is hard to teach: it mixes two very different contexts. Both are useful, one is more central than the other, but also more abstract, hence harder to understand.

Solution attempt

Eric was really ambitious in his attempt to improve the industry, providing both strategic and tactical views. I think the trending and the emergence of major DDD conferences across the world are proofs that he succeeds. I also understand his willing to provide something that is not only abstract, to avoid the architect ivory tower syndrome.
Still, strategic and tactical patterns are really different beasts. These two faces of DDD make it harder to understand.
How can we manage this complexity? It depends on the context (did you see that coming?). But in the domain of teaching DDD for newcomers, I would accentuate on strategic patterns, mainly bounded context, because this is the pattern that can lead to all other patterns. Then I would explain that all the industry standards good practices (continuous integration, segregation of responsibility and so on…) are mandatory to implement the core domain, and that DDD also includes them under the name tactical patterns.
Trying to go the other way around (teaching the tactical part as introduction to DDD) increases the risk of missing the core concepts.

As always, it’s not a recipe, but it may be a way to facilitate the understanding of DDD.

 

The context of OOP and FP

If you want lots of reaction when you tweet, a sure recipe is to talk about Object Oriented Programming (OOP) vs Functional Programming (FP).

Let’s throw the cat among the pigeons, with another blog post on the Internet giving personal perspective on OOP vs FP. I’m far from being a functional expert. I code professionally mainly in C#, and sometimes in F#. I only play with Haskell and Idris in coding dojo. I’m not trying to convince anyone about anything. I just would like to share my thoughts about these two important paradigms.

And the first step would be to agree on what’s OOP and what’s FP.

What’s OOP?

To really grasp the philosophy, I highly encourage you to follow Alan Kay’s work. Of course, he’s not the only one behind this paradigm, but I find his explanations really clear. This keynote is a good start. In a nutshell, Alan has (beyond other knowledge) a PHD in biology. The way complex organisms are working is basically what inspired the OOP paradigm. In other words: collaboration through specialize components to achieve a complex task. Each component can be independent and don’t need to be aware of the full system. They just collaborate, receiving some messages when something was required from them, and sending messages when they have done something meaningful for the system. How these components communicate, and how the orchestration between them is managed is not imposed by the paradigm. And different languages have used different implementation. But this notion of independent component collaboration is the core concept of OOP. Not really what we see when we type OOP in duckduckgo…

What’s FP


Instead of looking for inspiration in the biological field, Functional Programming is rooted in mathematics. I’ll quote Philip Wadler to give a better definition:
A program in a pure functional language is written as a set of equations. Explicit data flow ensures that the value of an expression depends only on its free variables. Hence substitution of equals for equals is always valid, making such programs especially easy to reason about. […] Explicit data flow also ensures that the order of computation is irrelevant, making [functional] programs susceptible to lazy evaluation.”
What does he means? If I write X = A+B, or Y = C * D I don’t care about the values of A and B, or C and D. That’s a mathematical equation, it represents the concept of all the valid values for an addition of type A and B, or a multiplication of type C and D. Hence I can compose X with Y, and do substitution:
X>>Y = (A + B) >>  Y = X >>( C * D) = (A + B) >>( C * D)
(>> is the composition operator in F#)
If any of these values have the possibility to change (mutate) outside of my scope, all this reasoning is no longer true. Even worse if not only the values, but also the types can change. That’s why we say that in FP, we can write code only thinking locally. I know that my “equations” (or pure functions) are always true, no need to think about the rest of the world to ensure that.
Please note that this willing of “local thinking” can also be find in the “independent components” from OOP. But contrary to OOP, FP explains how it can be achieved, thanks to mathematics.

Which one is the best?

Finally, the answer the whole industry was looking for since many years. Here it is: none of them, because this is not the good question. The question should be: which one is the best in my context? And now we can start to talk. I think the answer is easier that what many believe.
The more constraints you have, the harder it is to write code that woks, the easier it is to maintain the code in the long term. What are code constraints? We have many of them depending on the language: syntax, immutability, no side effects, unit tests, types and dependent types for example. Is it better to write code faster or to have long term maintainable code? In a start-up context, I probably need to produce code quickly, until I find the good product. In a critical context where lives are involved, I probably want something robust, even if I need 1 year to write it. And of course, there are all the scales from “quick and dirty” to “mathematically robust” that might be your context.

Just tools

Functional Programming is by nature more constrained than Object Oriented Programming. Because it forbids mutability and side effects. When the language also uses types, it leads to powerful concept like Type Driven Development where we can, by design, remove the invalid states from our system, to make it more robust at runtime. And when the language also uses dependent types, we can even encode business rules into the types, to avoid compilation if a business rule is not met. As a drawback, it is harder to write. But when you achieve to write it, you can trust the famous quote “if it compiles, it works”. Maintaining this code is usually easier than a huge OO codebase, because thanks to pure functions we can use local reasoning to maintain the system. Please note the “usually” in my previous sentence. A “good” OO codebase can in theory have this property of local thinking, but the fact that side effects and global impact are not forbidden by design makes it almost impossible to scale (at least in my experience).

FP is hard to write, but easy to maintain (easier to reason about). OOP is easier to write, but harder to maintain (harder to reason about due to side effect).