I tend to this space for pet projects and the learning process, but today I will use it to vent a bit.

Before I jump into it, please, bear in mind I don't hold any particular grudge against functional programming –  or Ramda, for what it matters. My problem is not the paradigm, is the abuse of it.

In my latest gig, my team inherited a codebase that was heavily fp oriented.

It took me a bit to figure out my way around the code, and whlist I'm surely not the best programmer around, I also have quite a few years of experience and developed a decent code sense, so it was particularly frustrating not being able to just dive in.

The contractors setting it up used another repo as a blue print, and embraced fp in full, but in the meantime the company had moved away from it and our repo is kind of a unique in its kind.

Given that, it wasn't a particularly hard decision to comply to the direction set by the company and start our quest to burn Ramda with fire. And whilst I'm enjoying doing it, it's of course a strategic decision, not something we would've done in autonomy if the company hadn't already done that evaluation.

Enough with the anticipation, let's dive into the code...

const getMessageSender = R.pipe(
A rather simple example of something that could've been more readable
const getMessageSender = chunk => this.sns.publish({ Message: chunk.toString() })

const getApiClient = ({ config, sns }) =>
    R.bind(config.get, config),
    R.tap(options => logger.debug({ options }, 'Initialising api client')),
    R.mergeRight({ logger, sns }),

const client = getApiClient(options)()
Something slightly more complex, or is it?
const getApiClient = ({ config, sns }) => () => {
  const configObj = config.get('api')
  logger.debug({ options }, 'Initialising api client')
  return api.getClient({ config: configObj, logger, sns })

const client = getApiClient(options)

const stripTypePrefix = R.pipe(
      R.slice(1, 2),
    R.slice(2, Infinity)
 const stripTypePrefix = s => `${s.slice(1, 2).toLowerCase()}${s.slice(2)}`; 

const calcCacheTTL = (now, overhead) =>
    R.reduce(R.add, 0)
Take a minute, try to figure out what it does before looking at the spoiler
const calcCacheTTL = (now, extra) => ({ expires_at }) => expires_at - now + extra

My team went to the process of defining our coding principles. The second up – after Resiliance, which is key for the success of our platform – is Maintainability, so you can see why the code needs to evolve to enable it.