7

So we're using the very nice ramda library at work, which is great because we're able to use a largely point-free style of code. The problem with this is that there are far fewer places to look when things go wrong that point to something in our code; most run time errors occur because of a misuse of composed ramda functions. Combine this with passing these functions to a framework that uses a lot of redirection (we're on react/redux), and often when something goes wrong, it's deep in library-only code, and it's very hard to find out where I went wrong.

Is there any way to mitigate this problem without moving away from point-free style?

jstaab
  • 3,449
  • 1
  • 27
  • 40

2 Answers2

8

One option is to use R.tap, like so:

const f = R.pipe(
  R.tap(console.log),  // logs x
  g,
  R.tap(console.log),  // logs g(x)
  h,
  R.tap(console.log),  // logs h(g(x))
  i,
  R.tap(console.log),  // logs i(h(g(x)))
  j,
  R.tap(console.log)   // logs j(i(h(g(x))))
);

f(x);

Another option is to use Sanctuary, which raises informative exceptions when a function is applied to arguments of the wrong types.

davidchambers
  • 23,918
  • 16
  • 76
  • 105
  • 3
    Also useful are Raine Virta's [treis](https://github.com/raine/treis) and Seb Insua's [Ramda-debug](https://github.com/sebinsua/ramda-debug). – Scott Sauyet Oct 27 '16 at 20:00
  • I already do use a tapped console log (by the way, your example won't work because `log` isn't bound to `console`) for debugging particular problems. I'm more wondering how to code in a style in general where if a ramda function is called wrong I get a reasonable error. Those libs are really helpful though. Any advantage to them over flow/typescript? – jstaab Oct 27 '16 at 20:21
  • 1
    `R.tap(console.log)` works in Node but not in the browser. `R.tap(console.log.bind(console))` works in both environments, but is a bit annoying to type. One could define an alias for this, of course. :) – davidchambers Oct 27 '16 at 23:31
5

I've run into the same problem with Ramda in my side projects. It's what made me give up on it in production, for now.

As of the time of writing this answer, debugging point-free style programs in JavaScript is very hard to impossible. That's the only reason I'm not using it. Even with good unit test coverage, I've found the development cycle is too long, and debugging to hard.

I'll expand on that: While tools like Ramda-debug and R.tap() exist, they are active debugging tools, that you need to add to your project, and in some cases, add to your code and remove later in production. However, when you get an error message, you don't get a useful stack trace, and you can't step through in a debugger to figure out the flow, you need to know the flow in advance.

Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • Did you ever try something like flow or typescript? – jstaab Oct 27 '16 at 17:13
  • I haven't, I'm looking into TypeScript now, though – Madara's Ghost Oct 27 '16 at 17:31
  • 4
    @jstaab I use TypeScript every day, in conjunction wit Ramda or Lodash/fp. Let me tell you: TS doesn't like functional programming. Defining interfaces for curried functions is possible but rather painful. Either way, it won't help you with debugging. It will only bring some marginal static type safety. There are other advantages though, which are beyond the scope of this question. – RIAstar Oct 28 '16 at 07:24