What are Closures good for? 
Tags: javascript, python, functional, programming
Published: 2020-11-13 21:04:46

# What is a Closure?
A Closure is an inner function that makes reference to the environment in it's outer function. 
A simple closure looks like this: 
```javascript
function outer(){
   let name = "John Doe";
   function inner(){
      return name;
   }
   return inner();
}  
>> outer() // returns "John Doe"
```
> _Closures can be used in JavaScript, Python, Ruby, Swift, C#, Objective C and a few of other languages. I'll stick to using simple JavaScript examples as it's similar to most languages and is easy to understand. 
I'll also give Python examples when the JavaScript approach won't work the same way._ 

`outer` is a regular function, while `inner` is a closure since it was defined inside `outer` and has access to it's variables. 

###Closures have access to: 
1. Their local scope(variables defined inside the inner function)
2. The scope of their outer functions
3. The global scope

Now, let's use a more intuitive example to understand how to use closures:
```javascript
function setGreeting(greeting){
   function setName(name){
      return `${greeting}, ${name}`;
   }
   return setName;
}
```
Quite self-explanatory function, the outer function takes a `greeting` as an argument, and the inner function takes a `name` as an argument and returns the `greeting` and `name` together. 
You might notice that unlike the first example, in this case, the outer function returns the inner function without calling it - _without the parentheses_. 
We'll see how this affects the code and how we call the functions.
```javascript
>> let welcome = setGreeting("Welcome")
>> // This sets greeting="Welcome"
>> typeof(welcome) // returns "function"
>> welcome // prints f setName(name){...}
>> // So welcome is equivalent to setName
>> // We can call it with the "name" argument
>> welcome("John") // prints "Welcome, John"
>> welcome("Joan") // prints "Welcome, Joan"
```
We can see from this that the first call to `setGreeting` sets the greeting, and returns the inner function for use. This means we can use `welcome` just like it were `setName`. This can be very useful in cases where we need multiple functions that do something similar with different contexts, rather than creating a function for each greeting, we create one function to set the greeting, and an inner function to print the greeting and name. 
That might sound like a bit much to take in, so let's look at practical use cases. 
## Creating functions with Context

You're filling a form for all graduating students in your department. There's a lot of details and most of them seem to be general for everyone, like _department_, _isAdult_, _certificate_, _country_, _race_, _faculty_ etc. With only very few unique fields like _fullName_ and _stateOfOrigin_. 
You could easily create a Closure where all the general fields are set by the outer function, and the inner function only takes the unique fields:
```javascript
function setGeneral(general){
   // general is an object containing all general details
   function setUnique(fullName, stateOfOrigin){
      // We use the spread operator "..." 
      // to add fullName and stateOfOrigin to the object
      fillForm({...general, 
         fullName: fullName, 
         stateOfOrigin: stateOfOrigin
         });
   }
   return setUnique;
}
>> cs = {department:"Computer Science",
>> isAdult: true,
>> certificate: "B.Sc. Comp",
>> country: "Nigeria",
>> race: "Negro",
>> faculty: "ICT"};
>> csStudent = setGeneral(cs);
>> // Now we can use csStudent to easily fill forms
>> csStudent("John Doe", "Lagos")
>> csStudent("Ciroma Chukwuma", "Abuja")
```
> _The syntax for Python is similar, using a dictionary, we'd update it with the `fullName` and `stateOfOrigin` keys using `general.update({"fullName":fullName, "stateOfOrigin": stateOfOrigin})`_ 


## Creating private attributes 
Languages like Java give you the option to make certain attributes(properties) private. That's not the case for JavaScript or Python. But we can enforce that using closures.
```javascript
function Person(){
   let name = "";
   let age = 0;
   
   function setName(name){
      name = name;
   }
   function getName(){
      return name;
   }
   function grow(){
      age += 1;
   }
   function getAge(){
      return age;
   }
   
   accessible = {setName: setName,
                 getName: getName,
                 grow: grow,
                 getAge: getAge};
   return accessible;
}
>> john = Person()
>> john.setName("John")
>> john.grow();
>> john.grow();
>> john.getName() // prints "John"
>> john.getAge() // prints 2
>> john.name // undefined
>> john.age // undefined
```
This is a simple Object Oriented application of closures, which can be used to imitate private attributes. 
The function returns an object(dictionary) of functions to be accessible from outside the `Person` function, thus making them accessible by dot notation(_i.e `john.grow()`_). While keeping the attributes not returned - `name` and `age` - inaccessible outside the `Person` function.
> _Python dictionary keys can't be accessed using dots, so here's a way you can do the same in Python_

```python
from types import SimpleNamespace
def Person():
   #same code, but in Python
   def grow():
      nonlocal age
      #python needs to know age is not a local
      #variable before directly operating on it
      age += 1
   accessible = {}#same thing as well
   return SimpleNamespace(**accessible)
# And that's it, SimpleNamespace will make them 
# accessible using dot notation
```
## Summary
With a better understanding of Closures, we can say closures are functions that keep their namespace(variables and or functions) after execution. Making it possible to setup an initial environment first before usage. 
Keep in mind that closures involve multiple functions, making your code a bit slower and more memory consuming. Try to avoid using them if you're not getting the benefits peculiar to Closures. 
Otherwise, enjoy.