Socket
Book a DemoInstallSign in
Socket

js-generic-functions

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

js-generic-functions

A CLOS-inspired implementation of generic functions

Source
npmnpm
Version
2.0.4
Version published
Weekly downloads
110
511.11%
Maintainers
1
Weekly downloads
 
Created
Source
  • What is this?
  • Docs

What is this?

An implementation of generic functions based on CLOS and the protocols defined in the Art of the Metaobject protocol, adapted for JS. These adaptations include using the prototype chain instead of classes and additionally providing extensible specializers (as in https://github.com/sbcl/specializable). For the moment, this is only used to provide a Shape specializer, as the details of the interaction between such specializers and subtyping are an open question.

Docs

Basic Usage

import { defgeneric } from "./genfuns.js";

Defining a function works by calling with some information about the function name and arguments. Methods are then added by calling the appropriate methods with a pair of arguments: a list of specializers (prototypes in the simple case, although there are other options) and a function to run if those specializers match.

const example1generic = defgeneric("example1", "a", "b")
  .primary([Number, Object], (n, __) => [1, n])
  .primary([Object, Number], (_, n) => [2, n])
  .primary([Object, Object], (_, __) => [5, null]);

After a generic function has been defined, you can get the function to call it by accessing its attribute.

const example1 = example1generic.fn;

expect(example1(5, {})).toEqual([1, 5]);
expect(example1({}, 6)).toEqual([2, 6]);
expect(example1("hello", {})).toEqual([5, null]);
expect(example1({}, "world")).toEqual([5, null]);
expect(example1({}, {})).toEqual([5, null]);

If a separate reference to the generic function object is maintained, you can add methods like so:

example1generic
  .primary([String, Object], (s, __) => [3, s])
  .primary([Object, String], (_, s) => [4, s]);

expect(example1("hello", {})).toEqual([3, "hello"]);
expect(example1({}, "world")).toEqual([4, "world"]);

Other sorts of specializers

import { Shape, Eql } from "./genfuns.js";
const example2 = defgeneric("example2", "inp")
  .primary([Shape("a", "b")], inp => `a: ${inp.a} b: ${inp.b}`)
  .primary([Shape("a")], inp => `a: ${inp.a} b: <missing>`)
  .primary([Shape(["c", 1])], inp => `c: one`)
  .primary([Shape(["c", 2])], inp => `c: two`)
  .primary([Eql(1)], inp => "one").fn;

expect(example2({ a: 3, q: "whatever" })).toEqual("a: 3 b: <missing>");
expect(example2({ a: 3, b: 4, q: "whatever" })).toEqual("a: 3 b: 4");
expect(example2({ c: 1, q: "whatever" })).toEqual("c: one");
expect(example2({ c: 2, q: "whatever" })).toEqual("c: two");
expect(example2(1)).toEqual("one");

FAQs

Package last updated on 26 Mar 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts