Ts-toolbelt: Curry performance

Created on 3 Apr 2020  ·  11Comments  ·  Source: millsp/ts-toolbelt

🐞 Bug Report

Describe the bug

Any benchmark for the Curry type? My CPU is about to explode when I use the curry function from ramda which uses ts-toolbelt.

@nthypes

Reproduce the bug

// REPL or a link to your repository if applicable.
// A *self-contained* demonstration of the problem.

Expected behavior

Possible Solution

Screenshots

Additional context

needs investigation perf

Most helpful comment

Building types for curry is extremely complex, as we have to handle many things like partial arguments with R._ and also handle the possibility to leave arguments out... This leads to an extremely complex type that cannot be unfolded easily.

I'm closing this, as I'm not able to solve your use case, will notify when I moved forward in generating the new types.

Again, sorry

Cheers

All 11 comments

Hey @nthypes, can you provide additional context?

  • Your code
  • TS version
  • Ramda version (types)

It's incredible slow and it's not working for real production project! I catch it easy on latest versions of TypeScript and Ramda.
(Now it: Typescript 3.9.3 / Ramda 0.27.0 / @types/ramda 0.27.6)

Note: I force install to @types/ramda latest ts-toolbelt (6.9.0), it doesn't help

Simple code:

import * as R from 'ramda';

const fn1 = R.curry((a: string, b: number) => {
  return true;
});

const fn2 = R.curry((f1: typeof fn1, f2: typeof fn1) => {
  return true;
});

const fn3 = R.curry((f1: typeof fn2, f2: typeof fn2) => {
  return true;
});

fn3(
  fn3(
    fn3()
  )
)

Errors:

test.ts:16:3 - error TS2321: Excessive stack depth comparing types 'GapsOf<?, L2>' and 'GapsOf<?, L2>'.

16   fn3(
     ~~~~
17     fn3()
   ~~~~~~~~~
18   )
   ~~~

test.ts:16:3 - error TS2321: Excessive stack depth comparing types 'GapsOf<L1, ?>' and 'GapsOf<L1, ?>'.

16   fn3(
     ~~~~
17     fn3()
   ~~~~~~~~~
18   )
   ~~~

test.ts:16:3 - error TS2589: Type instantiation is excessively deep and possibly infinite.

16   fn3(
     ~~~~
17     fn3()
   ~~~~~~~~~
18   )

Indeed, thanks for reporting this!

Sometimes hiding behind interfaces instead of types helps the compiler.. (had the same issue in @morphic-ts..)

Thanks for the advice, I'm looking into it right now

@darky you have found a sad limitation of this type. I went back to previous versions, and this seems to be a bug. Unfortunately, I don't know how to solve this.

Luckily, I am working on new curry types (generated) that will be lighter on the CPU... But I can give you a date for this, sorry.

The only thing I can recommend you is to

const fn1 = R.curry((a: string, b: number) => {
  return true;
}) as any;

Building types for curry is extremely complex, as we have to handle many things like partial arguments with R._ and also handle the possibility to leave arguments out... This leads to an extremely complex type that cannot be unfolded easily.

I'm closing this, as I'm not able to solve your use case, will notify when I moved forward in generating the new types.

Again, sorry

Cheers

This looks like the same issue that I've been having (when trying to assign a curried function to a variable with an F.Curry type), I've already created reproduction here:
https://github.com/philipbulley/ramda-ts-curry-bug — no worries though and good work in getting so far with such a mind-bending type.

Good news everyone, with the upcoming [email protected] feature https://github.com/microsoft/TypeScript/issues/5453, concat (which curry relies on) is going to get much more performant (as well as prepend, append...) which should bring better overall performance for curry and the rest of the library.

However, this still doesn't resolve the issue pointed out by @darky

Work is being done on next branch.

@philipbulley Yes, typescript fails at unfolding the type because of it's complexity. This is also why there is no UnCurry type. Sorry about this.

Ping veryone, I can confirm that @darky's example now works. UnCurry works too. Feedback is appreciated!

Was this page helpful?
0 / 5 - 0 ratings