Rete.IR.Expr (Rete v0.5.0)

Copy Markdown View Source

A compile-time generated named function that lives in the ruleset module.

Expressions are the only executable part of the IR. The compiler emits them as public, side-effect-free functions, in the module that used Rete.Ruleset. This lets them be captured, compared, and shared between rules.

:code is a stable, readable unique id. Two structurally identical conditions in one module context produce the same code. This is what lets the network share nodes. :kind fixes the calling convention: :alpha is (fact) -> bindings_map | nil, :test is (bindings_map) -> boolean, and :join_filter is (token_bindings, fact_bindings) -> boolean. :fun is nil until the expression is escaped. :__ast__ is compile-time only.

:share says whether two modules that produce this code may be put on one node. It states the conclusion, not the reason. Today one reason sets it: an unqualified call hashes as its bare name, so ok?(amt) under two different imports gives one code for two functions. A later reason to refuse a share sets the same field.

Rete.DSL.Codegen decides it while :__ast__ is still in hand, because escape/1 drops the AST and Rete.Compiler.disambiguate_codes/1 runs after that. It defaults to false, so an expression built somewhere this is not set is kept apart rather than merged on an assumption nobody checked.

Summary

Types

What an expression is used for; fixes its calling convention.

t()

Types

kind()

@type kind() :: :alpha | :test | :join_filter

What an expression is used for; fixes its calling convention.

t()

@type t() :: %Rete.IR.Expr{
  __ast__: %{args: Macro.t(), body: Macro.t()} | nil,
  arity: 1 | 2,
  code: atom(),
  fun: (... -> any()) | nil,
  kind: kind() | nil,
  name: atom(),
  share: boolean()
}