Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ramda or not ramda [closed]

In the team we're trying to decide, if we should use ramda in our project, or not. The project is on Typesctipt, with React in the front and Nestjs in the back.

Currently the lists of pros and cons look like this

Pros:

  1. The code is easy to read
  2. The pure functions are easy to test and to refactor

Cons:

  1. Difficult to read, if you are new to ramda
  2. Ramda has problems with types, e.g.
interface Obj {p1: {p2: number}}

const obj: Obj = {
    p1: {
        p2: 1,
    }
}

const value = pathOr(null, ['p1', 'p2'], obj); //type of "value" will be "any"
  1. Using ramda with classes looks awkward, e.g.
class Cl {
  method1() {...}

  method2() {...}

  method3() {
    return compose(
      this.method1.bind(this),
      this.method2.bind(this),
    )()
  }
}

Will be glad to see any considerations on these points, or more pros and cons to add. Thanks.

Updated:

Taking into account geoffrey's comment, when it's impossible not to use classes (like in NestJS), it's probably better to split fp-style functions from class methods, because they are pure functions anyway:

const method1Fn = () => {...};
const method2Fn = () => {...};
const method3Fn = () => compose(
  method1Fn,
  method2Fn,
)

class Cl {
  method3() {
    return method3Fn()
  }
}

or even

class Cl {
  method3 = method3Fn
}

but in this case method3 will be created for every instance of Cl.

like image 276
phaeton Avatar asked Nov 15 '25 19:11

phaeton


2 Answers

Readability in this case is a matter of usage. As long as you keep Ramda's usage to the places were it's easy to use an readable, it won't be a problem.

Examples from this answer

This is very readable:

const siblings = me => reject(equals(me), family(me));

While this overuses Ramda, and is less readable (and would probably require manual types):

const siblings = converge(reject, [unary(equals), family])

Ramda has problems with types, e.g.

Although you can install @types/ramda the inference is partial. You'll probably find yourself adding types manually:

interface Obj {
  p1: { p2: number };
}

const obj: Obj = {
  p1: {
    p2: 1
  }
};

const fn: (obj: Obj) => null | number = pathOr(null, ['p1', 'p2']);

const value = fn(obj);

console.log(value);

Using ramda with classes looks awkward, e.g.

You can use class properties with arrow functions to bind methods, so this is not actually an issue:

class Cl {
  method1 = () => {...}

  method2 = () => {...}

  method3() {
    return compose(
      this.method1,
      this.method2,
    )()
  }
}
like image 84
Ori Drori Avatar answered Nov 18 '25 12:11

Ori Drori


When the codebase grows there will be lot of Ramda and when new developer comes to the project he will be terrified and will need to spend additional time to learn Ramda, which is not ok.

like image 42
T1000 Avatar answered Nov 18 '25 11:11

T1000



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!