\href{https://github.com/zkat/genfun}{\texttt{ {\ttfamily genfun}}} is a Javascript library that lets you define generic functions\+: regular-\/seeming functions that can be invoked just like any other function, but that automatically dispatch methods based on the combination of arguments passed to it when it\textquotesingle{}s called, also known as multiple dispatch.

It was inspired by \href{http://slatelanguage.org/}{\texttt{ Slate}}, \href{http://en.wikipedia.org/wiki/CLOS}{\texttt{ CLOS}} and \href{http://github.com/zkat/sheeple}{\texttt{ Sheeple}}.\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11091}{}\doxysection{Install}\label{md_sfcode_node_modules_genfun_README_autotoc_md11091}
{\ttfamily \$ npm install genfun}\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11092}{}\doxysection{Table of Contents}\label{md_sfcode_node_modules_genfun_README_autotoc_md11092}

\begin{DoxyItemize}
\item \href{\#example}{\texttt{ Example}}
\item \href{\#api}{\texttt{ API}}
\begin{DoxyItemize}
\item \href{\#genfun}{\texttt{ {\ttfamily Genfun()}}}
\item \href{\#addMethod}{\texttt{ {\ttfamily gf.\+add()}}}
\item \href{\#callNextMethod}{\texttt{ {\ttfamily Genfun.\+call\+Next\+Method()}}}
\item \href{\#noApplicableMethod}{\texttt{ {\ttfamily Genfun.\+no\+Applicable\+Method()}}}
\end{DoxyItemize}
\item \href{\#performance}{\texttt{ Performance}}
\end{DoxyItemize}\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11093}{}\doxysubsection{Example}\label{md_sfcode_node_modules_genfun_README_autotoc_md11093}
Various examples are available to look at in the examples/ folder included in this project. Most examples are also runnable by just invoking them with node.


\begin{DoxyCode}{0}
\DoxyCodeLine{import Genfun from "{}genfun"{}}
\DoxyCodeLine{}
\DoxyCodeLine{class Person \{\}}
\DoxyCodeLine{class Dog \{\}}
\DoxyCodeLine{}
\DoxyCodeLine{const frobnicate = Genfun()}
\DoxyCodeLine{}
\DoxyCodeLine{frobnicate.add([Person], (person) => \{}
\DoxyCodeLine{  console.log('Got a person!')}
\DoxyCodeLine{\})}
\DoxyCodeLine{}
\DoxyCodeLine{frobnicate.add([Dog], (dog) => \{}
\DoxyCodeLine{  console.log('Got a dog!')}
\DoxyCodeLine{\})}
\DoxyCodeLine{}
\DoxyCodeLine{frobnicate.add([String, Person, Dog], (greeting, person, dog) => \{}
\DoxyCodeLine{  console.log(person, ' greets ', dog, ', \(\backslash\)'' + greeting + '\(\backslash\)'')}
\DoxyCodeLine{\})}
\DoxyCodeLine{}
\DoxyCodeLine{const person = new Person()}
\DoxyCodeLine{const dog = new Dog()}
\DoxyCodeLine{}
\DoxyCodeLine{frobnicate(person) // Got a person!}
\DoxyCodeLine{frobnicate(dog) // Got a dog!}
\DoxyCodeLine{frobnicate('Hi, dog!', person, dog); // \{\} greets \{\}, 'Hi, dog!' }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11094}{}\doxysubsection{API}\label{md_sfcode_node_modules_genfun_README_autotoc_md11094}
The basic API for {\ttfamily Genfun} is fairly simple\+: You create a new {\ttfamily genfun} by calling {\ttfamily Genfun()}, and add methods to them. Then you call the {\ttfamily genfun} object like a regular function, and it takes care of dispatching the appropriate methods!\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11095}{}\doxysubsubsection{$<$tt$>$\+Genfun()$<$/tt$>$}\label{md_sfcode_node_modules_genfun_README_autotoc_md11095}
Takes no arguments. Simply creates a new {\ttfamily genfun}. A {\ttfamily genfun} is a regular function object with overriden function call/dispatch behavior.

When called, it will look at its arguments and determine if a matching method has been defined that applies to {\bfseries{all}} arguments passed in, considered together.

New methods may be added to the {\ttfamily genfun} object with \href{\#addMethod}{\texttt{ {\ttfamily gf.\+add()}}}.

If no method is found, or none has been defined, it will invoke \href{\#noApplicableMethod}{\texttt{ {\ttfamily Genfun.\+no\+Applicable\+Method}}} with the appropriate arguments.

Genfuns preserve the value of {\ttfamily this} if invoked using {\ttfamily .call} or {\ttfamily .apply}.\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11096}{}\doxyparagraph{Example}\label{md_sfcode_node_modules_genfun_README_autotoc_md11096}

\begin{DoxyCode}{0}
\DoxyCodeLine{var gf = Genfun()}
\DoxyCodeLine{}
\DoxyCodeLine{//... add some methods ..}
\DoxyCodeLine{}
\DoxyCodeLine{// These calls are all identical.}
\DoxyCodeLine{gf(1, 2, 3)}
\DoxyCodeLine{gf.call(null, 1, 2, 3)}
\DoxyCodeLine{gf.apply(null, [1, 2, 3]) }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11097}{}\doxysubsubsection{$<$a name=\char`\"{}add\+Method\char`\"{}$>$$<$/a$>$ $<$tt$>$gf.\+add($<$selector$>$, $<$body$>$)$<$/tt$>$}\label{md_sfcode_node_modules_genfun_README_autotoc_md11097}
Adds a new method to {\ttfamily gf} and returns {\ttfamily gf} to allow chaining multiple {\ttfamily add}s.

{\ttfamily $<$selector$>$} must be an array of objects that will receive new {\ttfamily Role}s (dispatch positions) for the method. If an object in the selector is a function, its {\ttfamily .prototype} field will receive the new {\ttfamily Role}. The array must not contain any frozen objects.

When a {\ttfamily genfun} is called (like a function), it will look at its set of added methods and, based on the {\ttfamily Role}s assigned, and corresponding prototype chains, will determine which method, if any, will be invoked. On invocation, a method\textquotesingle{}s {\ttfamily $<$body$>$} argument will be the called with the arguments passed to the {\ttfamily genfun}, including its {\ttfamily this} and {\ttfamily arguments} values\`{}.

Within the {\ttfamily $<$body$>$}, \href{\#callNextMethod}{\texttt{ {\ttfamily Genfun.\+call\+Next\+Method}}} may be called.\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11098}{}\doxyparagraph{Example}\label{md_sfcode_node_modules_genfun_README_autotoc_md11098}

\begin{DoxyCode}{0}
\DoxyCodeLine{var numStr = Genfun()}
\DoxyCodeLine{}
\DoxyCodeLine{numStr.add([String, Number], function (str, num) \{}
\DoxyCodeLine{  console.log('got a str:', str, 'and a num: ', num)}
\DoxyCodeLine{\})}
\DoxyCodeLine{}
\DoxyCodeLine{numStr.add([Number, String], function (num, str) \{}
\DoxyCodeLine{  console.log('got a num:', num, 'and a str:', str)}
\DoxyCodeLine{\})}

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11099}{}\doxysubsubsection{$<$a name=\char`\"{}call\+Next\+Method\char`\"{}$>$$<$/a$>$ $<$tt$>$\+Genfun.\+call\+Next\+Method(\mbox{[}...$<$arguments$>$\mbox{]})$<$/tt$>$}\label{md_sfcode_node_modules_genfun_README_autotoc_md11099}
{\bfseries{NOTE}}\+: This function can only be called synchronously. To call it asynchronously (for example, in a {\ttfamily Promise} or in a callback), use \href{\#getContext}{\texttt{ {\ttfamily get\+Context}}}

Calls the \char`\"{}next\char`\"{} applicable method in the method chain. Can only be called within the body of a method.

If no arguments are given, {\ttfamily call\+Next\+Method} will pass the current method\textquotesingle{}s original arguments to the next method.

If arguments are passed to {\ttfamily call\+Next\+Method}, it will invoke the next applicable method (based on the {\bfseries{original}} method list calculation), with {\bfseries{the given arguments}}, even if they would otherwise not have triggered that method.

Returns whatever value the next method returns.

There {\bfseries{must}} be a next method available when invoked. This function {\bfseries{will not}} call {\ttfamily no\+Applicable\+Method} when it runs out of methods to call. It will instead throw an error.\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11100}{}\doxyparagraph{Example}\label{md_sfcode_node_modules_genfun_README_autotoc_md11100}

\begin{DoxyCode}{0}
\DoxyCodeLine{class Foo \{\}}
\DoxyCodeLine{class Bar extends Foo \{\}}
\DoxyCodeLine{}
\DoxyCodeLine{var cnm = Genfun()}
\DoxyCodeLine{}
\DoxyCodeLine{cnm.add([Foo], function (foo) \{}
\DoxyCodeLine{  console.log('calling the method on Foo with', foo)}
\DoxyCodeLine{  return foo}
\DoxyCodeLine{\})}
\DoxyCodeLine{}
\DoxyCodeLine{cnm.add([Bar], function (bar) \{}
\DoxyCodeLine{  console.log('calling the method on Bar with', bar)}
\DoxyCodeLine{  return Genfun.callNextMethod('some other value!')}
\DoxyCodeLine{\})}
\DoxyCodeLine{}
\DoxyCodeLine{cnm(new Bar())}
\DoxyCodeLine{// calling the method on Bar with \{\}}
\DoxyCodeLine{// calling the method on Foo with "{}some other value!"{}}
\DoxyCodeLine{// => 'some other value!' }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11101}{}\doxysubsubsection{$<$a name=\char`\"{}get\+Context\char`\"{}$>$$<$/a$>$ $<$tt$>$\+Genfun.\+get\+Context()$<$/tt$>$}\label{md_sfcode_node_modules_genfun_README_autotoc_md11101}
The {\ttfamily context} returned by this function will have a {\ttfamily call\+Next\+Method} method which can be used to invoke the correct next method even during asynchronous calls (for example, when used in a callback or a {\ttfamily Promise}).

This function must be called synchronously within the body of the method before any asynchronous calls, and will error if invoked outside the context of a method call.\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11102}{}\doxyparagraph{Example}\label{md_sfcode_node_modules_genfun_README_autotoc_md11102}

\begin{DoxyCode}{0}
\DoxyCodeLine{someGenfun.add([MyThing], function (thing) \{}
\DoxyCodeLine{  const ctx = Genfun.getContext()}
\DoxyCodeLine{  return somePromisedCall(thing).then(res => ctx.callNextMethod(res))}
\DoxyCodeLine{\}) }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11103}{}\doxysubsubsection{$<$a name=\char`\"{}no\+Applicable\+Method\char`\"{}$>$$<$/a$>$ $<$tt$>$\+Genfun.\+no\+Applicable\+Method($<$gf$>$, $<$this$>$, $<$args$>$)$<$/tt$>$}\label{md_sfcode_node_modules_genfun_README_autotoc_md11103}
{\ttfamily Genfun.\+no\+Applicable\+Method} is a {\ttfamily genfun} itself, which is called whenever {\bfseries{any {\ttfamily genfun}}} fails to find a matching method for its given arguments.

It will be called with the {\ttfamily genfun} as its first argument, then the {\ttfamily this} value, and then the arguments it was called with.

By default, this will simply throw a No\+Applicable\+Method error.

Users may override this behavior for particular {\ttfamily genfun} and {\ttfamily this} combinations, although {\ttfamily args} will always be an {\ttfamily Array}. The value returned from the dispatched {\ttfamily no\+Applicable\+Method} method will be returned by {\ttfamily genfun} as if it had been its original method. Comparable to \href{http://ruby-doc.org/core-2.1.0/BasicObject.html\#method-i-method_missing}{\texttt{ Ruby\textquotesingle{}s {\ttfamily method\+\_\+missing}}}.\hypertarget{md_sfcode_node_modules_genfun_README_autotoc_md11104}{}\doxysubsection{Performance}\label{md_sfcode_node_modules_genfun_README_autotoc_md11104}
{\ttfamily Genfun} pulls a few caching tricks to make sure dispatch, specially for common cases, is as fast as possible.

How fast? Well, not much slower than native methods\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{Regular function: 30.402ms}
\DoxyCodeLine{Native method: 28.109ms}
\DoxyCodeLine{Singly-\/dispatched genfun: 64.467ms}
\DoxyCodeLine{Double-\/dispatched genfun: 70.052ms}
\DoxyCodeLine{Double-\/dispatched genfun with string primitive: 76.742ms }

\end{DoxyCode}
 