Predicator.FunctionProvider behaviour (predicator v6.0.0)

Copy Markdown View Source

Behaviour for a module that supplies callable functions to the evaluator.

A provider names its functions by binding each name to an {arity, atom} pair - the atom is the name of a def on the same module, with signature (args :: [Types.value()], context) :: {:ok, Types.value()} | {:error, binary()}. Naming the implementation by atom, rather than exposing a closure directly, is what lets a caller resolve module and atom separately - apply/3 against the pair - instead of carrying a function() value around.

Predicator.Context.new/2's :providers option resolves a list of provider modules into the evaluator's dispatch map; the four builtin modules (SystemFunctions, DateFunctions, JSONFunctions, MathFunctions) are the default provider list, named by builtin_providers/0.

Summary

Types

A function's binding: its accepted arity/arities, and the atom naming its implementation.

A function name, as it appears in a predicator expression.

Callbacks

Returns the functions this provider exposes, keyed by name.

Functions

The four builtin provider modules, in shadowing order.

Types

entry()

@type entry() :: {Predicator.Evaluator.function_arity(), atom()}

A function's binding: its accepted arity/arities, and the atom naming its implementation.

name()

@type name() :: binary()

A function name, as it appears in a predicator expression.

Callbacks

functions()

@callback functions() :: %{required(name()) => entry()}

Returns the functions this provider exposes, keyed by name.

Each value is {arity, atom}, where atom names a public function on the same module accepting (args, context) and returning {:ok, Types.value()} | {:error, binary()}.

Functions

builtin_providers()

@spec builtin_providers() :: [module()]

The four builtin provider modules, in shadowing order.

Predicator.Context.new/2 resolves this list first when builtins: true (the default), so a later entry - a :providers module, then the inline :functions map - overrides a same-named builtin. This is the one place the default list is written down; conformance tooling that needs "every registered name" calls Predicator.Context.new().functions rather than duplicating it.