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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With