Skip to main content

memo

deno land deno doc GitHub release (latest by date) codecov License

test NPM standard-readme compliant semantic-release: angular

Memoization tools, TC39 proposal-function-memo implementation.

Install

deno.land:

import * as mod from "https://deno.land/x/memoization@$VERSION/mod.ts";

npm:

npm i @miyauci/memo

Usage

Returns the proxy function whose call is monitored. It calls at most once for each given arguments.

import { memo } from "https://deno.land/x/memoization@$VERSION/mod.ts";

function f(x: number): number {
  console.log(x);
  return x * 2;
}

const fMemo = memo(f);
fMemo(3); // Prints 3 and returns 6.
fMemo(3); // Does not print anything. Returns 6.
fMemo(2); // Prints 2 and returns 4.
fMemo(2); // Does not print anything. Returns 4.
fMemo(3); // Does not print anything. Returns 6.

Either version would work with recursive functions:

import { memo } from "https://deno.land/x/memoization@$VERSION/mod.ts";

const fib = memo((num: number): number => {
  if (num < 2) return num;

  return fib(num - 1) + fib(num - 2);
});

fib(1000);

Custom cache

To control the cache, specify cache.

The cache must implement the following interfaces:

interface MapLike<K, V> {
  get(key: K): V | undefined;

  has(key: K): boolean;

  set(key: K, value: V): void;
}

By default, an unlimited cache is used by WeakMap.

import {
  type MapLike,
  memo,
} from "https://deno.land/x/memoization@$VERSION/mod.ts";

declare const lruCache: MapLike<object, unknown>;
declare const fn: () => unknown;

const $fn = memo(fn, lruCache);

Keying

Cache keys are this and arguments represented by composite keys.

The equivalence of composite key is the Same-value-zero algorithm. By default, all arguments are used for the cache key.

Specify keying to change the representation of arguments used for cache keys.

import {
  type MapLike,
  memo,
} from "https://deno.land/x/memoization@$VERSION/mod.ts";

declare const respond: (request: Request) => Response;

const $respond = memo(
  respond,
  undefined,
  ([request]) => [request.method, request.url],
);

Polyfill

Polyfill affects the global object. You must be very careful when using it.

import "https://deno.land/x/memoization@$VERSION/polyfill.ts";

const fib = ((num: number): number => {
  if (num < 2) return num;

  return fib(num - 1) + fib(num - 2);
}).memo();

fib(1000);

API

See deno doc for all APIs.

Contributing

See CONTRIBUTING.md

License

MIT © 2023 Tomoki Miyauchi