git.fiddlerwoaroof.com
name mode size
..
Lato-Black.eot 100644 239 kb
Lato-Black.ttf 100644 570 kb
Lato-Black.woff 100644 290 kb
Lato-Black.woff2 100644 173 kb
Lato-BlackItalic.eot 100644 247 kb
Lato-BlackItalic.ttf 100644 602 kb
Lato-BlackItalic.woff 100644 303 kb
Lato-BlackItalic.woff2 100644 181 kb
Lato-Bold.eot 100644 250 kb
Lato-Bold.ttf 100644 587 kb
Lato-Bold.woff 100644 302 kb
Lato-Bold.woff2 100644 181 kb
Lato-BoldItalic.eot 100644 260 kb
Lato-BoldItalic.ttf 100644 608 kb
Lato-BoldItalic.woff 100644 316 kb
Lato-BoldItalic.woff2 100644 189 kb
Lato-Hairline.eot 100644 219 kb
Lato-Hairline.ttf 100644 552 kb
Lato-Hairline.woff 100644 268 kb
Lato-Hairline.woff2 100644 158 kb
Lato-HairlineItalic.eot 100644 234 kb
Lato-HairlineItalic.ttf 100644 574 kb
Lato-HairlineItalic.woff 100644 287 kb
Lato-HairlineItalic.woff2 100644 170 kb
Lato-Heavy.eot 100644 250 kb
Lato-Heavy.ttf 100644 589 kb
Lato-Heavy.woff 100644 303 kb
Lato-Heavy.woff2 100644 180 kb
Lato-HeavyItalic.eot 100644 260 kb
Lato-HeavyItalic.ttf 100644 606 kb
Lato-HeavyItalic.woff 100644 315 kb
Lato-HeavyItalic.woff2 100644 190 kb
Lato-Italic.eot 100644 262 kb
Lato-Italic.ttf 100644 624 kb
Lato-Italic.woff 100644 321 kb
Lato-Italic.woff2 100644 191 kb
Lato-Light.eot 100644 247 kb
Lato-Light.ttf 100644 603 kb
Lato-Light.woff 100644 304 kb
Lato-Light.woff2 100644 177 kb
Lato-LightItalic.eot 100644 259 kb
Lato-LightItalic.ttf 100644 614 kb
Lato-LightItalic.woff 100644 318 kb
Lato-LightItalic.woff2 100644 188 kb
Lato-Medium.eot 100644 246 kb
Lato-Medium.ttf 100644 586 kb
Lato-Medium.woff 100644 299 kb
Lato-Medium.woff2 100644 178 kb
Lato-MediumItalic.eot 100644 261 kb
Lato-MediumItalic.ttf 100644 613 kb
Lato-MediumItalic.woff 100644 318 kb
Lato-MediumItalic.woff2 100644 190 kb
Lato-Regular.eot 100644 248 kb
Lato-Regular.ttf 100644 593 kb
Lato-Regular.woff 100644 302 kb
Lato-Regular.woff2 100644 178 kb
Lato-Semibold.eot 100644 251 kb
Lato-Semibold.ttf 100644 600 kb
Lato-Semibold.woff 100644 306 kb
Lato-Semibold.woff2 100644 180 kb
Lato-SemiboldItalic.eot 100644 261 kb
Lato-SemiboldItalic.ttf 100644 616 kb
Lato-SemiboldItalic.woff 100644 320 kb
Lato-SemiboldItalic.woff2 100644 191 kb
Lato-Thin.eot 100644 245 kb
Lato-Thin.ttf 100644 597 kb
Lato-Thin.woff 100644 299 kb
Lato-Thin.woff2 100644 176 kb
Lato-ThinItalic.eot 100644 257 kb
Lato-ThinItalic.ttf 100644 614 kb
Lato-ThinItalic.woff 100644 316 kb
Lato-ThinItalic.woff2 100644 187 kb
README.org
#+TITLE: README for js-generic-functions #+AUTHOR: Ed L #+HTML_HEAD: <link rel="stylesheet" href="./colors.css" /> #+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: <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"); #+END_SRC #+BEGIN_SRC js :tangle src/doc.test.js :comments noweb :noweb tangle :exports none <<imports>> <<specializer-import>> describe("defgeneric", () => { test("methods get called appropriately", () => { <<basic-definition>> <<call-the-function>> <<add-methods>> <<sample1>> }); test ('specializers work as expected', () => { <<specializer-examples>> }) }); #+END_SRC