Code evolution

There is a bit of a revolution happening on the quiet in the development world. Partly led by the paradigm of DevOps, with infrastructure-as-code and configuration scripting. This revolution is changing the face of programming. That said, this revolution is more of a cyclic return to an earlier age. Those who have been in Development for a while have heard of Functional programming. It has a long and venerable history and can trace its origins to the concepts of Lambda calculus, which provided a formal framework for describing functions and their evaluation in mathematical logic. Now you might argue that is not a programming language and you would be correct, but Lambda Calculus forms the basis of almost all current functional programming languages. Now a history lesson is great but what exactly does this have to do with DevOps? Before we move on to that question we should answer the question.

What is Functional Programming?

Function Code

At its core Functional Programming is a declarative language rather than an imperative one. But qhat is a declarative language and an imperative one?

imperative programming is like how you do something, and declarative programming is more like what you do.”

Imperative vs. Declarative

This definition doesn’t at first glance does not appear to help, it is opaque. But once you actually understand the difference between the two paradigms it makes perfect sense. Now this may seem like a chicken and egg statement. And this twitter thread seems to back this up. At its core a declarative language defines the desired end state or WHAT you want to achieve and doesn’t care about the processes or steps taken to get there and an imperative language is more concerned with the steps to achieve the result. Time for a metaphor to help understand this, using this post by TylerMcginnis.

An imperative approach (HOW): “I see that table located under the Gone Fishin’ sign is empty. My husband and I are going to walk over there and sit down.”

A declarative approach (WHAT): “Table for two, please.”

Now we can see that the imperative approach now appears convoluted and the declarative approach is short and to the point.

This is Functional programming at its core. But why is this of interest to DevOps surely this is a developer’s issue? Possibly, but have a look at our series of posts on Terraform. Do you notice anything about that code? Yes that’s right: it just defines the desired end state, Terraform has no concern with how this state is achieved but is only concerned with the end-result!

Citizen Developers

The success of low and no-code platforms like BettyBlocks, OutSystems and Mendix has shown there’s a need for lowering the barriers to start developing applications, so that even non-developers can create business applications. This movement has taken hold in IaC too with Terraform, Puppet and modern scripting languages such as PowerShell and to Python taking a declarative approach rather than the traditional Object Orientated approach to programming where each task is defined, this leads to much clearer and readable code. (that said both PowerShell and Python can also use a traditional imperative approach).

Code evolution

Think of it as the coders’ version of abstraction. We started with Machine-code, actually coding to the hardware. The first layer of abstraction was Assembly, then we moved up into procedural code, then Object Oriented and finally we are now at Functional. Each move has taken us further from the 1 and 0’s that silicon hardware uses, but closer to natural human thinking. This opens up the skills for software development to other groups, such as application owners, system operators and engineers, and other non-developer roles.

How does Functional code differ from interpretive code?

This does not explain why functional coding languages exist. This is probably better to see some code that does something; let’s have a look at creating a S3 bucket.

Using AWS CLI (in imperative language) you issue the following commands

$ aws s3api create-bucket –bucket “MyBucketName”

With Terraform use in your script or module the following

resource "aws_s3_bucket" "b" {
  bucket = "MyBucket"
  acl    = "private"
  tags = {
    Name        = "MybucketName"
    Environment = "Dev"
  }
}

When you look at this simple example you may think well the first command looks a lot more simple, and you would be correct. But try to issue the AWS CLI command a second time and you will return an error because the bucket is already present. The Terraform code will just return a statement that there will be no changes.

For AWS CLI to achieve the same result:

$ BUCKET_NAME="mybucketname"$ if ! `aws s3api list-buckets --query Buckets[*].Name | grep $BUCKET_NAME > /dev/null`; then aws s3api create-bucket --bucket $BUCKET_NAME; else echo "Bucket already exists, continuing..."; fi

Now this is a little more complicated and we are only looking at a simple bucket creation task. This leads very nicely into our next question.

Why should I use Functional Programming?

Quite simply; it is more in line with how humans think and understand their world around themselves. You are more focused on the result rather than the way of getting there. When you make a cake you get eggs, flour, water, sugar etc and mix them together to get the desired cake.

Every time you want to make a Victoria Sponge cake you will use the same ingredients, but if you want to make a black forest gateau, the ingredients are different, but similar.

Functional programming is similar, every time you write a new program, some things are repeatable. With a functional approach your ability to re-use the code to do the same actions as a function is vastly improved. Instead of having to rewrite everything from scratch, core components can be re-used. Another side effect of this is that a functional approach leads to much cleaner, more readable code.

For those that are already developers this can be a seismic shift in thought processes, but for those new to coding, for example operational staff who are building out infrastructure, it is a much easier concept to grasp than object orientated or imperative coding methods.

Similarly, in no/low code applications, functional programming lets business-oriented people be citizen developers, taking control over the development process.

Summary

Summary

The rise of functional coding dovetails seamlessly into DevOps and the development of Infrastructure as Code. The majority of modern methods of delivery use to a greater or lessor extent the concepts of Functional Code.

Terraform and Cloud-Formation being declarative languages lend well towards immutability, meaning that your infrastructure has another layer of protection against drift and unauthorized changes as your infrastructure state cannot change once provisioned and any unauthorized changes are easily reverted to the single source of truth your infrastructure state. This is also makes it easier to maintain stability between your test, staging and production infrastructure, and the ability to role back confidently to a know good state is a joy to behold.