Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSDoc with and Immutable.js datastructures in annotations

Tags:

I am returning Immutable.js List data structure from function.

PHPStorm is automatically attaching following @returns {*|List<T>|List<any>}.

Eslint is giving me warning Unresolved variable of type 'T'. Where can I find documentation to annotations for Immutable.js?

How can I describe in @returns annotation shape of the List that would pass in Eslint?

/**
 * @param n
 * @returns {*|List<T>|List<any>}
 */
const getList = (n) => {
  let list = Immutable.List()

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      list = list.push(Immutable.List.of(i, j))
    }
  }

  return list
}
like image 745
Marcel Mandatory Avatar asked Jul 11 '16 14:07

Marcel Mandatory


1 Answers

Although I am not familiar with Immutable.js, the problem is that T is a template that must be defined in your documentation. See, what your function is really returning is a List of List of numbers. So T resolves to List<Number> and your fixed documentation would be something like:

/**
 * @param {Number} n
 * @return {List<List<Number>>}
 */

And you can just get rid of * and List<any> as possible return types, since your function is clearly always returning a list of list of numbers.

And that's it.


On the algorithmic complexity

On a side note, please bear in mind that you wrote a function whose processing time increases quadratically with the parameter n. If you find yourself frequently calling the function passing the same value, consider memoizing its return value:

const memoizedLists = new Map();

/**
 * @param {Number} n
 * @return {List<List<Number>>}
 */
function getList(n) {
    // try to find a previous run for this same value
    let result = memoizedLists.get(n);

    if (!result) {
        // compute it otherwise
        result = Immutable.List();

        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                result.push(Immutable.List.of(i, j));
            }
        }

        // memoize it for a future invocation
        memoizedLists.set(n, result);
    }

    return result;
}

Moreover, not only time but memory use is also increasing quadratically. Depending on how you're using it, you probably want to make your function into a generator function instead, which will "magically" make it use constant space, i.e., no matter how big n gets, your function will continue to use just the same amount of memory. Here's your function turned into a generator function:

/**
 * @generator
 * @param {Number} n
 * @yields {List<Number>}
 */
function *getList(n) {
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            yield Immutable.List.of(i, j);
        }
    }
}

To be able to use it as a generator, you need to call it on demand. For instance, if you're printing those pairs of numbers to some output:

for (const pair of getList(4)) {
    console.info(`...and here comes another pair: [${pair}]`);
}
like image 88
Lucio Paiva Avatar answered Sep 28 '22 02:09

Lucio Paiva