
Security News
Software Engineering Daily Podcast: Feross on AI, Open Source, and Supply Chain Risk
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.
js-generic-functions
Advanced tools
#+TITLE: README for js-generic-functions #+AUTHOR: Ed L #+HTML_HEAD: #+EXPORT_FILE_NAME: docs/index.html
[[https://www.npmjs.com/package/js-generic-functions][https://img.shields.io/npm/v/js-generic-functions.svg]] [[https://circleci.com/gh/fiddlerwoaroof/js-generic-functions.svg?style=svg]]
** 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
#+NAME: imports #+BEGIN_SRC js import { defgeneric } from "./genfuns.js"; #+END_SRC
Defining a function works by calling src_js{defgeneric} 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.
#+NAME: basic-definition #+BEGIN_SRC js const example1generic = defgeneric("example1", "a", "b") .primary([Number, Object], (n, __) => [1, n]) .primary([Object, Number], (, n) => [2, n]) .primary([Object, Object], (, __) => [5, null]); #+END_SRC
After a generic function has been defined, you can get the function to call it by accessing its src_js{.fn} attribute.
#+NAME: call-the-function #+BEGIN_SRC js 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]); #+END_SRC
If a separate reference to the generic function object is maintained, you can add methods like so:
#+NAME: add-methods #+BEGIN_SRC js 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"]); #+END_SRC
*** Other sorts of specializers #+NAME: specializer-import #+BEGIN_SRC js import { Shape, Eql } from "./genfuns.js"; #+END_SRC
#+NAME: specializer-examples
#+BEGIN_SRC 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: "); 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"); #+END_SRC
#+BEGIN_SRC js :tangle src/doc.test.js :comments noweb :noweb tangle :exports none <> <>
describe("defgeneric", () => { test("methods get called appropriately", () => { <>
<<call-the-function>>
<<add-methods>>
<<sample1>>
});
test ('specializers work as expected', () => {
<<specializer-examples>>
})
}); #+END_SRC
FAQs
A CLOS-inspired implementation of generic functions
We found that js-generic-functions demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

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.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.

Security News
GitHub has revoked npm classic tokens for publishing; maintainers must migrate, but OpenJS warns OIDC trusted publishing still has risky gaps for critical projects.

Security News
Rust’s crates.io team is advancing an RFC to add a Security tab that surfaces RustSec vulnerability and unsoundness advisories directly on crate pages.