Is shooting yourself in the foot Functional Programming?
Tags: javascript, functional, rant, devrant
Published: 2020-10-05 15:10:50

Please do not do the following anti-patterns and call it _Functional Programming_ or _Functional style_ or _Modern JS Syntax_!

## Anonymous functions galore
Yeah, anonymous functions look mathy-nerdy, but they are just functions without a name. So the following things do not have any value:

### Exporting anonymous functions 🥺
Only a true incarnation of evil would write a code that cannot be ever safely searched in a codebase:

```javascript
// in evil-function.js file
// this looks so mathy, I am mentally superior to my peers
export default (name) => console.log(`Try importing this with your IDE, ${name}`);

// in any other file
import evilFunction from './evil-function';

// in another file (note `el typo`)
import evilFunctino from './utils/evil-function';
```

So an IDE would figure out your intent through having a sort of map of all available items: reserved words, objects defined in available scopes at the cursor, named exports and default exports with names. 

_Named exports_. 

Does it a ring a bell? I also made one more _real-life twist_ to it: the guy who had been unlucky enough to having to work with that horrible function has made a _typo_. Now when colleague B comes over to investigate a bug related to `evil-function`, they would search for `import evilFunction` to find all usages. And usages they will find except the one(s) with the typo 🥺. Or when somebody used a synonym like `satanicFunction`.

Usually the people who also claim that they don't use `TypeScript` because they write code faster than to know what is the exact input and exact output of their functions don't think there is any problem with this. 

Sigh.

### Composing anonymous functions
How the hell should I know what this train-wreck does if I don't look up every goddamn return value of every goddamn function involved:

```javascript
const myComputedValue = (stuff) => (_, factoryFn) => 
addLayer(stuff)({ 
  x: 134, 
  y: 134}
)({ moreStuff: stuff.otherStuff })
(factoryFn('LayerObject'), true);
```

What on Earth this shit does? This is **_not_ Functional Programming**, this is [code-obfuscation](https://en.wikipedia.org/wiki/International_Obfuscated_C_Code_Contest).

Why do I need to skip a parameter with `_`? What if I forgot the parameter order and pass `(factoryFn, _)`? Why is not the **design of the function's interface** force me to specify my parameters?

Look:
```javascript
function objectCreator({ options, factoryFn } = { 
  options: { cloneValues: true } 
}) {
   // ...
}

// usage:
objectCreator({ factoryFn }); // can't miss it

// the equivalent of objectCreator(factoryFn, _) would be this nonsense:
// you would never write it...
objectCreator({ options: factoryFn, factoryFn: undefined }); 

```

Note that we have improved the interface of the function: the order of parameters now can be _freely interchanged_, values not being used can also be _omitted_. 

In short: the parameter list is now _commutative_.

Moving on to the nameless functions returned, why don't you return something more meaningful that can be _chained_?

```javascript
const prepareForUpload = (x, y) => { 
   const transformedValue = { name: x, value: y };
  
   return (x) => api.upload(x);
};

// What does the second thing do?
// You have to check the function definition.
prepareForUpload('Robert', '2$')();

// or do this:
function prepareForUploadWithObject(x, y) {
  const transformedValue = { name: x, value: y };
  
  return {
    upload: () => api.upload(transformedValue)
  }
}

// clear immediately
prepareForUploadWithObject('Robert', '200$').upload();

```

Is version two still pass as Functional Programming? YES! But much clearer on what it really does!

So please don't do this, functions returning functions that can be called without ever specifying what the hell they do is the `ultimate cringe`.

> If you are too busy to type some extra characters you will be very busy double checking everything.

### Naming anonymous function
Technically there is nothing wrong with using them _if you are aware what anonymous functions are and what not_. But why do you name something that was meant not to have a name?

```javascript
const anonymousWorkerFunction = (stuff) => {
  //... 20 lines of code
};

// vs
function doSomeWork(stuff) {
  //... 20 lines of code
}
```

`const` variables only exist in the block they are defined and also they are not even hoisted - it means if you want to use `anonymousWorkerFunction` before you defined it, you will get a juicy `Uncaught ReferenceError: Cannot access 'anonymousWorkerFunction' before initialization`.

There are special cases where using them makes total sense: see this excellent [opinion piece](https://davidwalsh.name/i-dont-hate-arrow-functions) by Kyle Simpson, also known as `getify`.