ronantakizawa/codereview-bench huggingface dataset:
Repository: toss/es-toolkit
File: benchmarks/performance/isMap.bench.ts (TypeScript)

Code before:
import { bench, describe } from 'vitest';
import { isMap as isMapToolkit } from 'es-toolkit';
import { isMap as isMapToolkitCompat } from 'es-toolkit/compat';
import { isMap as isMapLodash } from 'lodash';

describe('isMap', () => {
  bench('es-toolkit/isMap', () => {
    isMapToolkit(new Map());
    isMapToolkit(new Map([['key', 'value']]));
    isMapToolkit(new WeakMap());
    isMapToolkit([]);
    isMapToolkit({});
    isMapToolkit(null);
  });

  bench('es-toolkit/compat/isMap', () => {
    isMapToolkitCompat(new Map());
    isMapToolkitCompat(new Map([['key', 'value']]));
    isMapToolkitCompat(new WeakMap());
    isMapToolkitCompat([]);
    isMapToolkitCompat({});
    isMapToolkitCompat(null);
  });

  bench('lodash/isMap', () => {
    isMapLodash(new Map());
    isMapLodash(new Map([['key', 'value']]));
    isMapLodash(new WeakMap());
    isMapLodash([]);

Review comment (suggestion):
```suggestion
import { isMap as isMapToolkit_ } from 'es-toolkit';
import { isMap as isMapToolkitCompat_ } from 'es-toolkit/compat'
import { isMap as isMapLodash_ } from 'lodash';

const isMapToolkit = isMapToolkit_;
const isMapToolkitCompat = isMapToolkitCompat_ ;
const isMapLodash = isMapLodash_;
```

Code after:
import { bench, describe } from 'vitest';
import { isMap as isMapToolkit_ } from 'es-toolkit';
import { isMap as isMapToolkitCompat_ } from 'es-toolkit/compat'
import { isMap as isMapLodash_ } from 'lodash';

const isMapToolkit = isMapToolkit_;
const isMapToolkitCompat = isMapToolkitCompat_ ;
const isMapLodash = isMapLodash_;

describe('isMap', () => {
  bench('es-toolkit/isMap', () => {
    isMapToolkit(new Map());
    isMapToolkit(new Map([['key', 'value']]));
    isMapToolkit(new WeakMap());
    isMapToolkit([]);
    isMapToolkit({});
    isMapToolkit(null);
  });

  bench('es-toolkit/compat/isMap', () => {
    isMapToolkitCompat(new Map());
    isMapToolkitCompat(new Map([['key', 'value']]));
    isMapToolkitCompat(new WeakMap());
    isMapToolkitCompat([]);
    isMapToolkitCompat({});
    isMapToolkitCompat(null);
  });

  bench('lodash/isMap', () => {
Repository: toss/es-toolkit
File: benchmarks/performance/isSet.bench.ts (TypeScript)

Code before:
import { bench, describe } from 'vitest';
import { isSet as isSetToolkit } from 'es-toolkit';
import { isSet as isSetToolkitCompat } from 'es-toolkit/compat';
import { isSet as isSetLodash } from 'lodash';

describe('isSet', () => {
  bench('es-toolkit/isSet', () => {
    isSetToolkit(new Set());
    isSetToolkit(new WeakSet());
    isSetToolkit([]);
    isSetToolkit({});
    isSetToolkit(null);
  });

  bench('es-toolkit/isSetCompat', () => {
    isSetToolkitCompat(new Set());
    isSetToolkitCompat(new WeakSet());
    isSetToolkitCompat([]);
    isSetToolkitCompat({});
    isSetToolkitCompat(null);
  });

  bench('lodash/isSet', () => {
    isSetLodash(new Set());
    isSetLodash(new WeakSet());
    isSetLodash([]);
    isSetLodash({});
    isSetLodash(null);
  });

Review comment (suggestion):
```suggestion
import { isSet as isSetToolkit_ } from 'es-toolkit';
import { isSet as isSetToolkitCompat_ } from 'es-toolkit/compat';
import { isSet as isSetLodash_ } from 'lodash';

const isSetToolkit = isSetToolkit_;
const isSetToolkitCompat = isSetToolkitCompat_;
const isSetLodash = isSetLodash_;
```

Code after:
import { bench, describe } from 'vitest';
import { isSet as isSetToolkit_ } from 'es-toolkit';
import { isSet as isSetToolkitCompat_ } from 'es-toolkit/compat';
import { isSet as isSetLodash_ } from 'lodash';

const isSetToolkit = isSetToolkit_;
const isSetToolkitCompat = isSetToolkitCompat_;
const isSetLodash = isSetLodash_;

describe('isSet', () => {
  bench('es-toolkit/isSet', () => {
    isSetToolkit(new Set());
    isSetToolkit(new WeakSet());
    isSetToolkit([]);
    isSetToolkit({});
    isSetToolkit(null);
  });

  bench('es-toolkit/isSetCompat', () => {
    isSetToolkitCompat(new Set());
    isSetToolkitCompat(new WeakSet());
    isSetToolkitCompat([]);
    isSetToolkitCompat({});
    isSetToolkitCompat(null);
  });

  bench('lodash/isSet', () => {
    isSetLodash(new Set());
    isSetLodash(new WeakSet());
Repository: toss/es-toolkit
File: src/predicate/isMap.ts (TypeScript)

Code before:
/**
 * Checks if a given value is `Map`.
 *
 * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `Map`.
 *
 * @param {unknown} value The value to check if it is a `Map`.
 * @returns {value is Map<any, any>} Returns `true` if `value` is a `Map`, else `false`.
 *
 * @example
 * const value1 = new Map();
 * const value2 = new Set();
 * const value3 = new WeakMap();
 *
 * console.log(isMap(value1)); // true
 * console.log(isMap(value2)); // false
 * console.log(isMap(value3)); // false
 */

export function isMap(value?: unknown): value is Map<any, any> {
  return value instanceof Map;
}


Review comment (suggestion):
```suggestion
export function isMap(value: unknown): value is Map<any, any> {
```

I think our original library has to accept the argument here.

Code after:
/**
 * Checks if a given value is `Map`.
 *
 * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `Map`.
 *
 * @param {unknown} value The value to check if it is a `Map`.
 * @returns {value is Map<any, any>} Returns `true` if `value` is a `Map`, else `false`.
 *
 * @example
 * const value1 = new Map();
 * const value2 = new Set();
 * const value3 = new WeakMap();
 *
 * console.log(isMap(value1)); // true
 * console.log(isMap(value2)); // false
 * console.log(isMap(value3)); // false
 */

export function isMap(value: unknown): value is Map<any, any> {
  return value instanceof Map;
}
Repository: toss/es-toolkit
File: src/predicate/isSet.ts (TypeScript)

Code before:
/**
 * Checks if a given value is `Set`.
 *
 * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `Set`.
 *
 * @param {unknown} value The value to check if it is a `Set`.
 * @returns {value is Set<any>} Returns `true` if `value` is a `Set`, else `false`.
 *
 * @example
 * const value1 = new Set();
 * const value2 = new Map();
 * const value3 = new WeakSet();
 *
 * console.log(isSet(value1)); // true
 * console.log(isSet(value2)); // false
 * console.log(isSet(value3)); // false
 */

export function isSet(value?: unknown): value is Set<any> {
  return value instanceof Set;
}


Review comment (suggestion):
```suggestion
export function isSet(value: unknown): value is Set<any> {
```

Code after:
/**
 * Checks if a given value is `Set`.
 *
 * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `Set`.
 *
 * @param {unknown} value The value to check if it is a `Set`.
 * @returns {value is Set<any>} Returns `true` if `value` is a `Set`, else `false`.
 *
 * @example
 * const value1 = new Set();
 * const value2 = new Map();
 * const value3 = new WeakSet();
 *
 * console.log(isSet(value1)); // true
 * console.log(isSet(value2)); // false
 * console.log(isSet(value3)); // false
 */

export function isSet(value: unknown): value is Set<any> {
  return value instanceof Set;
}
Repository: toss/es-toolkit
File: src/predicate/isArrayBuffer.ts (TypeScript)

Code before:
/**
 * Checks if a given value is `ArrayBuffer`.
 *
 * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `ArrayBuffer`.
 *
 * @param {unknown} value The value to check if it is a `ArrayBuffer`.
 * @returns {value is ArrayBuffer} Returns `true` if `value` is a `ArrayBuffer`, else `false`.
 *
 * @example
 * const value1 = new ArrayBuffer();
 * const value2 = new Array();
 * const value3 = new Map();
 *
 * console.log(isArrayBuffer(value1)); // true
 * console.log(isArrayBuffer(value2)); // false
 * console.log(isArrayBuffer(value3)); // false
 */

export function isArrayBuffer(value?: unknown): value is ArrayBuffer {
  return value instanceof ArrayBuffer;
}


Review comment (suggestion):
```suggestion
export function isArrayBuffer(value: unknown): value is ArrayBuffer {
```

Code after:
/**
 * Checks if a given value is `ArrayBuffer`.
 *
 * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `ArrayBuffer`.
 *
 * @param {unknown} value The value to check if it is a `ArrayBuffer`.
 * @returns {value is ArrayBuffer} Returns `true` if `value` is a `ArrayBuffer`, else `false`.
 *
 * @example
 * const value1 = new ArrayBuffer();
 * const value2 = new Array();
 * const value3 = new Map();
 *
 * console.log(isArrayBuffer(value1)); // true
 * console.log(isArrayBuffer(value2)); // false
 * console.log(isArrayBuffer(value3)); // false
 */

export function isArrayBuffer(value: unknown): value is ArrayBuffer {
  return value instanceof ArrayBuffer;
}
Repository: toss/es-toolkit
File: src/function/once.ts (TypeScript)

Code before:
/**
 * Creates a function that is restricted to invoking the provided function `func` once.
 * Repeated calls to the function will return the value from the first invocation.
 *
 * @template F - The type of function.
 * @param {F} func - The function to restrict.
 * @returns {() => ReturnType<F>} A new function that invokes `func` once and caches the result.
 *
 * @example
 * const initialize = once(() => {
 *   console.log('Initialized!');
 *   return true;
 * });
 *
 * initialize(); // Logs: 'Initialized!' and returns true
 * initialize(); // Returns true without logging
 */
export function once<F extends (...args: unknown[]) => any>(func: F): () => ReturnType<F> {
  let called = false;
  let cache: ReturnType<F>;

  return function () {
    if (!called) {
      called = true;
      cache = func();
    }

    return cache;
  };
}


Review comment (suggestion):
```suggestion
export function once<F extends () => any>(func: F): () => ReturnType<F> {
```
I think `func` should be a function accepting no arguments.

Code after:
/**
 * Creates a function that is restricted to invoking the provided function `func` once.
 * Repeated calls to the function will return the value from the first invocation.
 *
 * @template F - The type of function.
 * @param {F extends () => any} func - The function to restrict.
 * @returns {F} A new function that invokes `func` once and caches the result.
 *
 * @example
 * const initialize = once(() => {
 *   console.log('Initialized!');
 *   return true;
 * });
 *
 * initialize(); // Logs: 'Initialized!' and returns true
 * initialize(); // Returns true without logging
 */
export function once<F extends () => any>(func: F): F;
/**
 * Creates a function that is restricted to invoking the provided function `func` once.
 * Repeated calls to the function will return the value from the first invocation.
 *
 * @template F - The type of function.
 * @param {F extends (...args: any[]) => void} func - The function to restrict with arguments.
 * @returns {F} A new function that invokes `func` once.
 *
 * @example
 * const log = once(console.log);
 *
 * log('Hello, world!'); // prints 'Hello, world!' and doesn't return anything
 * log('Hello, world!'); // doesn't print anything and doesn't return anything
 */
export function once<F extends (...args: any[]) => void>(func: F): F;
/**
 * Creates a function that is restricted to invoking the provided function `func` once.
 * Repeated calls to the function will return the value from the first invocation.
 *
 * @template F - The type of function.
 * @param {F} func - The function to restrict.
 * @returns {(...args: Parameters<F>) => ReturnType<F>} A new function that invokes `func` once and caches the result.
 *
 * @example
 * const initialize = once(() => {
Repository: toss/es-toolkit
File: src/function/before.ts (TypeScript)

Code before:
 * @param {number} n - The number of times the returned function is allowed to call `func` before stopping.
 * - If `n` is 0, `func` will never be called.
 * - If `n` is a positive integer, `func` will be called up to `n-1` times.
 * @param {F} func - The function to be called with the limit applied.
 * @returns {(...args: Parameters<F>) => ReturnType<F> | undefined} - A new function that:
 * - Tracks the number of calls.
 * - Invokes `func` until the `n-1`-th call.
 * - Returns `undefined` if the number of calls reaches or exceeds `n`, stopping further calls.
 * @throws {Error} - Throw an error if `n` is negative.
 * @example
 *
 * const beforeFn = before(3, () => {
 *  console.log("called");
 * })
 *
 * // Will log 'called'.
 * beforeFn();
 *
 * // Will log 'called'.
 * beforeFn();
 *
 * // Will not log anything.
 * beforeFn();
 */

export function before<F extends (...args: unknown[]) => any>(
  n: number,
  func: F
): (...args: Parameters<F>) => ReturnType<F> | undefined {
  if (!Number.isInteger(n) || n < 0) {
    throw new Error('n must be a non-negative integer.');
  }

  let counter = 0;

  return (...args: Parameters<F>) => {
    if (++counter < n) {
      return func(...args);
    }

    return undefined;
  };
}


Review comment (suggestion):
```suggestion
export function before<F extends (...args: any[]) => any>(
```

Code after:
 * @param {number} n - The number of times the returned function is allowed to call `func` before stopping.
 * - If `n` is 0, `func` will never be called.
 * - If `n` is a positive integer, `func` will be called up to `n-1` times.
 * @param {F} func - The function to be called with the limit applied.
 * @returns {(...args: Parameters<F>) => ReturnType<F> | undefined} - A new function that:
 * - Tracks the number of calls.
 * - Invokes `func` until the `n-1`-th call.
 * - Returns `undefined` if the number of calls reaches or exceeds `n`, stopping further calls.
 * @throws {Error} - Throw an error if `n` is negative.
 * @example
 *
 * const beforeFn = before(3, () => {
 *  console.log("called");
 * })
 *
 * // Will log 'called'.
 * beforeFn();
 *
 * // Will log 'called'.
 * beforeFn();
 *
 * // Will not log anything.
 * beforeFn();
 */

export function before<F extends (...args: any[]) => any>(
  n: number,
  func: F
): (...args: Parameters<F>) => ReturnType<F> | undefined {
  if (!Number.isInteger(n) || n < 0) {
    throw new Error('n must be a non-negative integer.');
  }

  let counter = 0;

  return (...args: Parameters<F>) => {
    if (++counter < n) {
      return func(...args);
    }

    return undefined;
  };
}
Repository: toss/es-toolkit
File: src/compat/array/slice.ts (TypeScript)

Code before:
import { isIterateeCall } from '../_internal/isIterateeCall';
import { toInteger } from '../util/toInteger';

/**
 * Create a slice of `array` from `start` up to, but not including, `end`.
 *
 * It does not return a dense array for sparse arrays unlike the native `Array.prototype.slice`.
 *
 * @template T - The type of the array elements.
 * @param {T[]} array - The array to slice.
 * @param {number} [start=0] - The start position.
 * @param {number} [end=array.length] - The end position.
 * @returns {T[]} - Returns the slice of `array`.
 *
 * @example
 * slice([1, 2, 3], 1, 2); // => [2]
 * slice(new Array(3)); // => [undefined, undefined, undefined]
 */
export function slice<T>(array: readonly T[], start?: number, end?: number): T[] {
  const length = array == null ? 0 : array.length;

  if (end && typeof end !== 'number' && isIterateeCall(array, start, end)) {
    // support for expression like `_.map(slice)`
    start = 0;
    end = length;
  } else {
    start = start == null ? 0 : toInteger(start);
    end = end === undefined ? length : toInteger(end);
  }

  if (start < 0) {
    start = Math.max(length + start, 0);
  } else {
    start = Math.min(start, length);
  }

  if (end < 0) {
    end = Math.max(length + end, 0);
  } else {
    end = Math.min(end, length);
  }

  const resultLength = Math.max(end - start, 0);
  const result = new Array(resultLength);


Review comment (performance):
If `array` is null, why not we return an empty array first? This will help reduce the complexity of the function.

```suggestion
  if (array == null) {
    return [];
  }
  
  const length = array.length;
```

Code after:
import { isIterateeCall } from '../_internal/isIterateeCall.ts';
import { toInteger } from '../util/toInteger.ts';

/**
 * Create a slice of `array` from `start` up to, but not including, `end`.
 *
 * It does not return a dense array for sparse arrays unlike the native `Array.prototype.slice`.
 *
 * @template T - The type of the array elements.
 * @param {T[]} array - The array to slice.
 * @param {number} [start=0] - The start position.
 * @param {number} [end=array.length] - The end position.
 * @returns {T[]} - Returns the slice of `array`.
 *
 * @example
 * slice([1, 2, 3], 1, 2); // => [2]
 * slice(new Array(3)); // => [undefined, undefined, undefined]
 */
export function slice<T>(array: readonly T[], start?: number, end?: number): T[] {
  if (array == null) {
    return [];
  }

  const length = array.length;

  if (end === undefined) {
    end = length;
  } else if (typeof end !== 'number' && isIterateeCall(array, start, end)) {
    // support for expression like `_.map(slice)`
    start = 0;
    end = length;
  }

  start = toInteger(start);
  end = toInteger(end);

  if (start < 0) {
    start = Math.max(length + start, 0);
  } else {
    start = Math.min(start, length);
  }

  if (end < 0) {
    end = Math.max(length + end, 0);
  } else {
Repository: toss/es-toolkit
File: src/compat/array/slice.ts (TypeScript)

Code before:
/**
 * Create a slice of `array` from `start` up to, but not including, `end`.
 *
 * It does not return a dense array for sparse arrays unlike the native `Array.prototype.slice`.
 *
 * @template T - The type of the array elements.
 * @param {T[]} array - The array to slice.
 * @param {number} [start=0] - The start position.
 * @param {number} [end=array.length] - The end position.
 * @returns {T[]} - Returns the slice of `array`.
 *
 * @example
 * slice([1, 2, 3], 1, 2); // => [2]
 * slice(new Array(3)); // => [undefined, undefined, undefined]
 */
export function slice<T>(array: readonly T[], start?: number, end?: number): T[] {
  const length = array == null ? 0 : array.length;

  if (end && typeof end !== 'number' && isIterateeCall(array, start, end)) {
    // support for expression like `_.map(slice)`
    start = 0;
    end = length;
  } else {
    start = start == null ? 0 : toInteger(start);
    end = end === undefined ? length : toInteger(end);
  }

  if (start < 0) {
    start = Math.max(length + start, 0);
  } else {
    start = Math.min(start, length);
  }

  if (end < 0) {
    end = Math.max(length + end, 0);
  } else {
    end = Math.min(end, length);
  }

  const resultLength = Math.max(end - start, 0);
  const result = new Array(resultLength);

  for (let i = 0; i < resultLength; ++i) {
    result[i] = array[start + i];
  }

  return result;
}


Review comment (refactor):
I think the code here is too complex. We have three conditions here: (1) The `if` statement, (2) The first ternary operator, and (3) the second ternary operator. So we have to think about `2^3 === 8` possibilities.

Code after:
/**
 * Create a slice of `array` from `start` up to, but not including, `end`.
 *
 * It does not return a dense array for sparse arrays unlike the native `Array.prototype.slice`.
 *
 * @template T - The type of the array elements.
 * @param {T[]} array - The array to slice.
 * @param {number} [start=0] - The start position.
 * @param {number} [end=array.length] - The end position.
 * @returns {T[]} - Returns the slice of `array`.
 *
 * @example
 * slice([1, 2, 3], 1, 2); // => [2]
 * slice(new Array(3)); // => [undefined, undefined, undefined]
 */
export function slice<T>(array: readonly T[], start?: number, end?: number): T[] {
  if (array == null) {
    return [];
  }

  const length = array.length;

  if (end === undefined) {
    end = length;
  } else if (typeof end !== 'number' && isIterateeCall(array, start, end)) {
    // support for expression like `_.map(slice)`
    start = 0;
    end = length;
  }

  start = toInteger(start);
  end = toInteger(end);

  if (start < 0) {
    start = Math.max(length + start, 0);
  } else {
    start = Math.min(start, length);
  }

  if (end < 0) {
    end = Math.max(length + end, 0);
  } else {
    end = Math.min(end, length);
  }

  const resultLength = Math.max(end - start, 0);
  const result = new Array(resultLength);

  for (let i = 0; i < resultLength; ++i) {
    result[i] = array[start + i];
  }
Repository: toss/es-toolkit
File: src/compat/array/slice.ts (TypeScript)

Code before:
import { isIterateeCall } from '../_internal/isIterateeCall';
import { toInteger } from '../util/toInteger';

/**
 * Create a slice of `array` from `start` up to, but not including, `end`.
 *
 * It does not return a dense array for sparse arrays unlike the native `Array.prototype.slice`.
 *
 * @template T - The type of the array elements.
 * @param {T[]} array - The array to slice.
 * @param {number} [start=0] - The start position.
 * @param {number} [end=array.length] - The end position.
 * @returns {T[]} - Returns the slice of `array`.
 *
 * @example
 * slice([1, 2, 3], 1, 2); // => [2]
 * slice(new Array(3)); // => [undefined, undefined, undefined]
 */
export function slice<T>(array: readonly T[], start?: number, end?: number): T[] {
  if (array == null) {
    return [];
  }

  const length = array.length;

  if (end === undefined) {
    end = length;

Review comment (suggestion):
```suggestion
import { isIterateeCall } from '../_internal/isIterateeCall.ts';
import { toInteger } from '../util/toInteger.ts';
```

Code after:
import { isIterateeCall } from '../_internal/isIterateeCall.ts';
import { toInteger } from '../util/toInteger.ts';

/**
 * Create a slice of `array` from `start` up to, but not including, `end`.
 *
 * It does not return a dense array for sparse arrays unlike the native `Array.prototype.slice`.
 *
 * @template T - The type of the array elements.
 * @param {T[]} array - The array to slice.
 * @param {number} [start=0] - The start position.
 * @param {number} [end=array.length] - The end position.
 * @returns {T[]} - Returns the slice of `array`.
 *
 * @example
 * slice([1, 2, 3], 1, 2); // => [2]
 * slice(new Array(3)); // => [undefined, undefined, undefined]
 */
export function slice<T>(array: readonly T[], start?: number, end?: number): T[] {
  if (array == null) {
    return [];
  }

  const length = array.length;

  if (end === undefined) {
    end = length;