First Class Functions
Tags: javascript, programming, react, webdev
Published: 2023-07-03 07:49:08

Today I am talking about first class functions.  First class is a good thing.  When we get on a plane we want to fly first class.  Being first class means to be the best. According to MDN web docs:

> A programming language is said to have First-class functions when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.
  
Fundamentally this is a fairly straightforward concept.  Functions can be passed as arguments and/or returned as values.  Functions can take other functions as arguments.  My purpose is to show illustrative examples that I have implemented in my applications. 

However, let's look at some examples of first class functions that we may have taken for granted.

The first example consists of array iterator methods.  These methods include `.map()`, `.find()`, and  `.filter()`.  These are functions that take a callback function as arguments and return values in an array.

```
array.map(element=>doSomethingWithThis(element))
array.find(element=>returnBooleanValueOf(element))
array.filter(element=>returnBooleanValueOf(element))
```

The second example is our `useEffect()` method that we typically use for network requests.  This function also takes a callback function, typically with a fetch request, as an argument.

```
useEffect(()=>{
  fetch(/'fromThisURL')
  .then(res=>res.json())
  .then(data=>doSomethingWithThis(data)
},[])
```

Other examples are our `setInterval()` and `setTimeout()` functions.  These functions take a function as the first argument and a time interval (an integer in milliseconds) as a second argument. 

```
setInterval(()=>doSomethingAtEachTimeInterval, timeInterval)
setTimeOut(()=>doSomethingAfterTimeInterval, timeInterval)
```
Now, let's move on to an example that illustrates how using functions as variables can allow us to perform powerful feats.  One of these feats is sorting through an array of members to find a particular member by a group to which the artist belongs.  These members are busy and happen to belong to multiple artist groups. 
This list of objects looks like this.

```
[
  {
    "id": 36,
    "name": "Irene",
    "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e3/Irene_Bae_at_fansigning_event_on_August_18%2C_2015_02.png/170px-Irene_Bae_at_fansigning_event_on_August_18%2C_2015_02.png",
    "artists": [
      {
        "id": 8,
        "name": "Red Velvet",
        "genre": "K-pop"
      },
      {
        "id": 78,
        "name": "Irene",
        "genre": "K-pop"
      }
    ]
  },
  {
    "id": 38,
    "name": "Wendy",
    "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Wendy_at_Incheon_Airport_on_September_9%2C_2019.jpg/220px-Wendy_at_Incheon_Airport_on_September_9%2C_2019.jpg",
    "artists": [
      {
        "id": 8,
        "name": "Red Velvet",
        "genre": "K-pop"
      },
      {
        "id": 66,
        "name": "GOT the beat",
        "genre": "K-pop"
      },
      {
        "id": 71,
        "name": "Wendy",
        "genre": "K-pop"
      }
    ]
  },
  {
    "id": 39,
    "name": "Joy",
    "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Joy_for_Marie_Claire_Korea_on_October_25th_2022.jpg/220px-Joy_for_Marie_Claire_Korea_on_October_25th_2022.jpg",
    "artists": [
      {
        "id": 8,
        "name": "Red Velvet",
        "genre": "K-pop"
      },
      {
        "id": 72,
        "name": "Joy",
        "genre": "K-pop"
      }
    ]
  }]
```
The first thing that needs to be done here find the matching attribute (member.artists.name).  What I did was create a function to find a match by iterating through the array of each artist to find a match.

```
    function findMatch(array, attribute, filter){
        const match = array.find(element=> element[attribute].toLowerCase().includes(filter.toLowerCase()))
        return !!match
    }
```
As one can see, `findMatch` takes three arguments, the previously mentioned array of members, the attribute (member.artists) to filter by, and the name that is used to perform the query(a state variable).

Now this is where we demonstrate the power of first class functions.  I will pass `findMatch` as an argument into a filter function (`filteredByArtist`) to find members that match the name of the artist.  Right here we have two first class functions, one which a passed as a variable and the one taking a function as a variable.

```
const filteredByArtist = filteredByGenre.filter(member=> findMatch(member.artists, "name", artist))
```
Now what would happen if I wanted to find artist(s) with the name "Got The Beat".  After entering the name "Got The Beat", storing it in state and passing it an an argument we end up returning a value like this.


```
//our query

const filteredByArtist = filteredByGenre.filter(member=> findMatch(member.artists, "name", "Got The Beat"))

//our result

{
    "id": 38,
    "name": "Wendy",
    "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Wendy_at_Incheon_Airport_on_September_9%2C_2019.jpg/220px-Wendy_at_Incheon_Airport_on_September_9%2C_2019.jpg",
    "artists": [
      {
        "id": 8,
        "name": "Red Velvet",
        "genre": "K-pop"
      },
      {
        "id": 66,
        "name": "GOT the beat",
        "genre": "K-pop"
      },
      {
        "id": 71,
        "name": "Wendy",
        "genre": "K-pop"
      }
    ]
  }
```

With a little DOM manipulation we get something that looks like this.


![Wendy from Got The Beat](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jyj199em8l7hihbglv43.png)

First class functions are a beautiful thing.  This is one of the things that make JavaScript and its associated frameworks (in this case React) great to work with. One can build powerful applications by implementing this feature.  Until next time, stay classy.