Functional Programming and Justice in a World Without Time
Passionate about finding patterns in computers, society and minds.
My grandfather was staring deeply into the television screen in the dimly lit living room. After his cataract had over matured, he swapped the newspaper he peeled through every morning for a news channel with as much depth as the flat screen it was served on.
The biggest punishment for putting off the surgery was turning out not to be the loss of sight in one eye, but the 24 hour news cycle — a different sort of blindness.
The television buzzed about the stampede that killed nearly forty people in the “Mumbai Local” train station. My grandfather shook his head and asked why innocent people had to senselessly die. He shifted his attention to me and dragged his finger across his wrinkled forehead while quietly confessing, “For each of us, it is written.”
His finger paused at the end of that invisible line of code like a blinking cursor indicating fate can be rewritten like a program yet to be executed. Each news channel he switched to confidently delivered a different opinion on how the cursor should have been used before it was too late.
After all, the system they were critiquing wasn’t a mysterious natural phenomenon. Humans created the train station and use it everyday. So how could it so tragically surprise us?
We have had so much practice laying down airtight laws on how the systems we build should behave; and yet we still hold our breath. Before a major software release, when the first passengers step into a new train, as a police officer approaches a car with their hand resting on the holster of their gun, we uneasily wait for our system to behave in a way we could not foresee.
But why do we find ourselves at the mercy of time even when trying to understand the behavior of something we’ve designed every inch of?
Functional programming is a software paradigm investigating this very problem, and finding ways to peel back the mystery around the systems we build.
We will turn the lens of functional programming towards our society to explore why our human-made world behaves in surprising ways despite the laws we lay down for it.
We will try to make the process of law enforcement in our society transparent enough that we can see a little bit more of our world without time.
As Transparent as Math
We declare laws in society as though they are as timeless as math equations. In math,
1 + 2
. Both mean the same thing. And in fact, to say
1 + 2
is to say
, which in turn is another way to say
when we realize it. It has always been
. When solving a math problem, we aren’t creating something new as time passes, we are just rearranging the truth in front of us; so that we can see all that it means.
The law makes the same promise. It will not create an unexpected consequence to an action as time passes. Anything you discover about it has already been clearly written.
The law like any other system can be seen as a function. A function is a process that takes in an input and returns an output. The illustration above is a function’s type signature and it tells us the type of input it takes in and the type of output it returns. In this case law takes in an action and outputs a consequence.
We can go further to define how law pairs actions to consequences in the example of marijuana possession in the United States.
Although it is changing, for most of the country marijuana possession is still illegal.
The law recognizes a set of two actions: possessing marijuana and not possessing marijuana. These two actions are mapped to two consequences: being arrested and not being arrested, respectively.
This function exhibits determinism, which means given the same input (possessing marijuana) the function will consistently return the same result (arrested). A person can immediately know the consequence an action will result in without needing time to pass.
However, when we bring the written law into the real world it becomes non-deterministic.
Some people are punished for possessing marijuana and some people are not just like some people lose their lives on the Mumbai Local and some don’t. Visually such a function shows one input pointing to two different outputs.
To understand why this is happening let’s explore why even something as clear as a math equation becomes non-deterministic when we bring it into the real world.
How the Law Breaks Down
When a math equation is written as code it becomes concerned with time.
and stores the result in the variable to the left of
1 + 2
results in only after the line of code is executed. Computation has to happen and time must pass before we know
. But you probably can tell that
even before the program is ever executed. The line of code appears to clearly point one input to only one result just like the math equation.
But unlike a math equation, a program must live in the real world, which means many hidden assumptions are being made about how the real world behaves that could turn out to be wrong.
For example, programs require electricity, and electricity depends on physics and someone paying the light bill — both of which are governed by things outside of the program.
If electricity is not constantly available we will have to wait and see if the program evaluates to
const y = 3
or the computer just dies. Though our line of code does not show it, we are facing non-determinism.
The problem is the presence of electricity is a variable we assumed to be constant. When the function hopped out of our minds and into a computer, it was subjected to variables like this that we did not teach it to consider.
Once human-made systems, whether they are math equations or drug laws, are released into the real world they are confronted by the messy uncertainty of reality and develop a character of their own.
Suddenly we find ourselves holding our breath as we wait to see what the functions we created will actually output. Our frustration with this uneasy situation leads us to desperately re-establish a sense of determinism in two ways
- Seeking nuance
- Embracing ignorance
A lot of arguments in software and social issues stem from the differences between these two approaches. We will explore the benefits and drawbacks of each one as we methodically step through many arguments in the debate over law enforcement.
This is not meant to be comprehensive. Frankly, I’m not qualified to do that. My intention is to sketch the logic of these two approaches so that we may more intentionally switch between them and understand why and where we disagree.
Our program became mysterious when it entered the computer because it had to interact with variables we didn’t teach it to consider. If we list these hidden variables as explicit inputs, the program becomes deterministic.
Now each input points to only one output. We can clearly see our function depends not only on the code we wrote, but the presence of electricity.
If we can similarly gather hidden variables that influence how law enforcement behaves we will be able to explain when a person will and will not be arrested for marijuana possession.
Though it may seem non-deterministic an arrest is not a matter of chance. There are people sitting in handcuffs for possession who can explain how they got there.
They could describe the moment of their arrest, how the marijuana got into their possession, and what neighborhood they were in when the police car drove by.
Their arrest is predetermined by a number of factors that they can clearly see in hindsight. lawEnforcement, like most things in the universe, is deterministic, but it may appear random to us because we don’t fully understand its logic.
Now we can explain why many of the people in jail for marijuana possession (and other non-violent crimes) are people of color. When we consider race with our inputs, lawEnforcement’s type signature and law’s type signature differ in a very key way.
law only considers what a person does when determining consequences, while lawEnforcement considers who the person is along with what they do. We’re not just dealing with people committing crimes. We are dealing with people of a certain background committing crimes.
Thus, the only way to pair an action with one and only one consequence is by taking a closer glance into the environment and making sure we haven’t missed some other variable that influences the outcome.
In other words, to see the world without time is to see the present more carefully. Time won’t tell us anything we haven’t already heard. It will only tell us what we shouldn’t have ignored.
The Religion of Science
A critic could argue that our latest lawEnforcement sketch is still very simplistic. After all, not all black individuals who possess marijuana will get arrested and people who are not black get arrested for possession too.
Though the function takes in more factors, it is still not nuanced enough to give a true view into the behavior of law enforcement.
When we settle for a particular level of nuance in our understanding and dig no deeper like this, science becomes religion. Religion in this case means any explanation of reality that gives a sense of determinism even if there is evidence in reality that contradicts it.
By this definition religion can span from creation myths to scientific theories. Even the idea that the universe is deterministic at all is a religion that this article accepts.
Human beings take these shortcuts to determinism because it gives us the confidence to build society, to trust our technology, and bravely tread through a world that would otherwise seem uncertain.
It gives us the courage to step onto a train platform in Mumbai after a tragic, senseless accident. We trace the line on our forehead and believe that the one who wrote it knows best.
But religion also gives us the illusion that we can see the world without time when we really can’t. The universe often refuses to obey the laws we thought it obeys. Sometimes this pushes us to deny the lived experiences of others because it exposes our ignorance — especially in the case of injustice.
If we continue to dig for all of the possible factors that influence the behavior of law enforcement, we will quickly be overwhelmed. How law enforcement really works is way too complicated, controversial and uncomfortable to discuss.
A common path forward is to side step the debate by accepting that the consequence of committing a crime is uncertain; so we can at least agree that if a person doesn’t commit a crime they won’t be arrested.
From a functional programming perspective, we’ve put our consequence into what is called an optional. Think of it basically as a box that you can put a value inside of or say that the value is uncertain. The possible outputs of lawEnforcement expands from ‘arrested’, and ‘not arrested’ to ‘definitely arrested’, ‘definitely not arrested’, and ‘uncertain’’.
For some people the sketch above perfectly explains their experience with law enforcement. Putting aside the uncertainty, they can conclude based on their experience that a person will never be punished by law enforcement as long as they never commit a crime.
Preserving the Status Quo
However, it is flawed to assume the determinism an individual experiences is what everyone else will experience. There are certain factors like ethnicity and gender that remain constant for an individual no matter how many time they face law enforcement, but vary from individual to individual.
The problem with discussing social systems like law enforcement is that the consequence for an action can appear deterministic for one person while at the same time ambiguous for another because of who they are.
The visibility of non-determinism is often relative to the viewer’s identity.
In many countries law enforcement punishes people even when they have not committed a crime. In the United States the most extreme example is the murder of many unarmed black people by police now caught on video.
If we try to explain these cases while still embracing our ignorance, any action a person will take points to an uncertain consequence.
All inputs pointing to uncertainty is the easiest way to establish determinism. We can confidently say without time needing to pass that the effect of any cause is definitely something uncertain.
May-Know offers us a broader classification to group all of the non-deterministic outputs into a single output.
However, the danger of pointing distinct inputs to the same output, is that the inputs become interchangeable from the perspective of anything that consumes the output. Imagine we had a function, which gives recommendations on what to do based on the consequences returned by lawEnforcement.
The bold arrows show that no matter what the action is, ultimately the recommendation will be the same. After all, if a person perceives that they may be treated as a criminal regardless of what they do, it should come as no surprise that whether an action is illegal or not will have no bearing on what they decide to do.
This rationale is often exploited around the world to ironically justify the further policing of targeted groups.
Using false arrests, other unwarranted punishments, or police intimidation they push persecuted groups to act in a criminal way and then point to their acts of criminality to further justify their targeting of that group.
This undermines the goal of law, which is to discourage people from doing certain actions.
Even outside of law enforcement, collapsing meaningfully distinct details into the same output is a common technique used to perpetuate a default response.
The fossil fuel industry does this by massively funding research that suggests carbon emissions do not contribute to global climate change. They do not need to disprove the opposing evidence. They simply need to create a sense of non-determinism.
Victory for the fossil fuel industry is making us as a society believe that the only thing we know for sure is that we don’t know for sure whether green house emissions significantly contribute to climate change.
When facing uncertainty especially with regard to a highly lucrative industry, our default response is ‘business as usual’ until the evidence becomes more conclusive.
Social systems give us the illusion that we understand how they work just because we created them. The truth is even with the systems we build we need time to pass to know its output with full certainty because they exist in a natural world we don’t understand.
Before then the only claim we can make with 100 percent confidence is that the output for any input is uncertain.
Accepting ignorance is an important act of humility. Stopping at ignorance can be dangerous because the only thing we can build from ignorance is the status quo.
A System Understanding Itself
Neither seeking nuance nor accepting ignorance is inherently superior. Both are paths we take and often switch between on the journey to determinism.
The benefits and drawbacks I’ve shared in this article largely come from my experience using these strategies while facing complex software systems that need to be fixed.
Programmers regularly argue over whether getting more nuance or accepting ignorance is the best way to move forward on fixing a system. Even so it is easier to reach a common understanding when arguing over software systems than social systems because software is nicely framed by the edges of a computer screen that sits at a distance.
We do not have this luxury when facing social systems. Unlike in programming where we can sit outside of the system and debug it with a god-like perspective, in society each of us are actually a part of the system. Everything we perceive, every diagram of the rest of the system we draw is based on what inputs we receive from that system.
Those inputs come through the news channels we watch, our friends and family, the schools we go to, and many other things we did not choose for ourselves.
Depending on where you stand in society you will have a different idea of how our social systems behave and what kind of reality they produce. Your very idea of what the system is is itself a part and product of the system.
And so is mine. I come to the topics with a lot of ignorance. I am not a lawyer nor an academic studying the justice system. I have experienced very mild police overreach in my personal life. I don’t feel qualified to make any final statements about the justice system or any of the other issues I’ve discussed.
I come as a software developer with tools with which I hope to help improve society. But if my views are a function of what the system has exposed me to and my actions are a function of my views, then is my decision to write this article, the system perpetuating itself through me? Perhaps.
But there is a difference between perpetuating the system and perpetuating the status quo. I wrote this article because I believe the later cannot continue. Innocent people are punished in the name of justice across the world ever day.
The climate is quickly reaching a point of no return. And a cataract was forming in my grandfather’s other eye.
We had to do something. From my research the probability of complications when removing a hyper-mature cataract was still in our favor. Still, high likelihood of an outcome is not a guarantee. At some point, I simply believed the outcome of his surgery would be positive.
My grandfather chose an auspicious day in the Telugu calendar for each appointment including the final surgery. We were both creating determinism.
When he peeled off the bandage and looked at me through his recovered eye, perhaps he saw a younger him. A version of himself that took his anxious father to a cataract surgery many, many years earlier. I certainly saw an older me in him.
I can see a day when embracing ignorance may literally mean embracing blindness. In that moment, with the cataract removed, we were seeing our past and future selves in each other.
In a way, we were seeing ourselves without time.
Subscribe to get your daily round-up of top tech stories!