Expression.Callbacks (expression v2.49.1)

Copy Markdown

Use this module to implement one's own callbacks. The standard callbacks available are implemented in Expression.Callbacks.Standard.

Using defexpr

defexpr auto-evaluates arguments from their AST form before the body executes:

defmodule MyCallbacks do
  use Expression.Callbacks

  defexpr dice_roll() do
    Enum.random(1..6)
  end

  defexpr greet(name), ctx do
    prefix = ctx.private[:prefix] || "Hello"
    "#{prefix}, #{name}!"
  end
end

Using plain def

Traditional def callbacks still work — defexpr is optional sugar. With plain def, you must manually call eval! on each argument:

defmodule MyCallbacks do
  use Expression.Callbacks

  def dice_roll(_ctx) do
    Enum.random(1..6)
  end
end

Options

  • stdlib: false — don't fall back to Expression.Callbacks.Standard
  • also: [ModuleA, ModuleB] — compose multiple callback modules; dispatch checks each in order before falling back to Standard

Summary

Functions

Convert a string function name into an atom meant to handle that function

Macro for defining expression callback functions with automatic argument evaluation.

Handle a function call while evaluating the AST.

Functions

atom_function_name(function_name)

Convert a string function name into an atom meant to handle that function

Reserved words such as and, if, and or are automatically suffixed with an _ underscore.

defexpr(fa, rest)

(macro)

defexpr(fa, ctx_var, rest)

(macro)

Macro for defining expression callback functions with automatic argument evaluation.

Without context (pure functions)

defexpr upper(text) do
  String.upcase(to_string(text))
end

Generates a standard callback where text is automatically evaluated from its AST form before the body executes.

With context access

defexpr generate_ott(data), ctx do
  with %{number: number} <- ctx.private, ...
end

The second argument names the context variable, giving access to ctx.vars, ctx.private, and the full Expression.Context struct (or plain map for legacy callers).

Variadic functions

@variadic true
defexpr switch(args), ctx do
  # args is a list of all pre-evaluated arguments
end

Reserved words

Expression function names that are Elixir reserved words (and, if, or, not) are automatically suffixed with _ in the generated function name.

handle(module \\ Standard, function_name, arguments, context)

@spec handle(
  module :: module(),
  function_name :: binary(),
  arguments :: [any()],
  context :: map()
) ::
  {:ok, any()} | {:error, :not_implemented}

Handle a function call while evaluating the AST.

Handlers in this module are either:

  1. The function name as is
  2. The function name with an underscore suffix if the function name is a reserved word
  3. The function name suffixed with _vargs if the takes a variable set of arguments

implements(module \\ Standard, function_name, arguments)