View Source Matcha (Matcha v0.1.10)

First-class match specifications for Elixir.

synopsis

Synopsis

Matcha offers tight integration with Elixir and match specifications.

Match specifications are a BEAM VM feature that can execute de-structuring, pattern matching, and re-structring operations very close-to-the-metal. They can be used to efficiently:

However, they are notoriously difficult to compose and use. Matcha makes this intuitive with ergonomic macros to compose them, and a high-level API with which to use them.

examples

Examples

# Turn Elixir code into a match specification,
#  then use it to filter/map some data
iex> require Matcha
...> Matcha.spec do
...>   {x, y, z} -> x + y + z
...> end
...> |> Matcha.Spec.run!([
...>   {1, 2, 3},
...>   {1, 2},
...>   {1, 2, 3, 4},
...>   {4, 5, 6}
...> ])
[6, 15]

This is one way to run test and develop match specifications, but they truly shine in table and tracing applications!

guides

Guides

Check out the interactive usage guides, including using Matcha for:

Link to this section Summary

Functions

Builds a Matcha.Pattern that represents a pattern matching operation on a given input.

Builds a Matcha.Spec that represents a destructuring, pattern matching, and re-structuring operation on in-memory data.

Builds a Matcha.Spec that represents a destructuring, pattern matching, and re-structuring operation in a given context.

Traces function calls to module, executing a spec on matching arguments.

Link to this section Functions

Link to this macro

pattern(pattern)

View Source (macro)
@spec pattern(Macro.t()) :: Macro.t()

Builds a Matcha.Pattern that represents a pattern matching operation on a given input.

For more information on match patterns, consult the Matcha.Pattern docs.

examples

Examples

iex> require Matcha
...> pattern = Matcha.pattern({x, y, x})
#Matcha.Pattern<{:"$1", :"$2", :"$1"}>
iex> Matcha.Pattern.match?(pattern, {1, 2, 3})
false
iex> Matcha.Pattern.match?(pattern, {1, 2, 1})
true
@spec spec(Macro.t()) :: Macro.t()

Builds a Matcha.Spec that represents a destructuring, pattern matching, and re-structuring operation on in-memory data.

Identical to calling spec/2 with a :filter_map context. Note that this context is mostly used to experiment with match specs, and you should generally prefer calling spec/2 with either a :table or :trace context depending on which Matcha APIs you intend to use:

  • Use the :trace context if you intend to query data with Matcha.Trace functions
  • Use the :table context if you intend to trace code execution with the Matcha.Table functions

examples

Examples

iex> require Matcha
...> Matcha.spec do
...>   {x, y, x}
...>     when x > y and y > 0
...>       -> x
...>   {x, y, y}
...>     when x < y and y < 0
...>       -> y
...> end
#Matcha.Spec<[{{:"$1", :"$2", :"$1"}, [{:andalso, {:>, :"$1", :"$2"}, {:>, :"$2", 0}}], [:"$1"]}, {{:"$1", :"$2", :"$2"}, [{:andalso, {:<, :"$1", :"$2"}, {:<, :"$2", 0}}], [:"$2"]}], context: Matcha.Context.FilterMap>
Link to this macro

spec(context, spec)

View Source (macro)
@spec spec(Matcha.Context.t(), Macro.t()) :: Macro.t()

Builds a Matcha.Spec that represents a destructuring, pattern matching, and re-structuring operation in a given context.

The context may be :filter_map, :match, :table, :trace, or a Matcha.Context module. This is detailed in the Matcha.Context docs.

For more information on match specs, consult the Matcha.Spec docs.

examples

Examples

iex> require Matcha
...> Matcha.spec(:table) do
...>   {x, y, x}
...>     when x > y and y > 0
...>       -> x
...>   {x, y, y}
...>     when x < y and y < 0
...>       -> y
...> end
#Matcha.Spec<[{{:"$1", :"$2", :"$1"}, [{:andalso, {:>, :"$1", :"$2"}, {:>, :"$2", 0}}], [:"$1"]}, {{:"$1", :"$2", :"$2"}, [{:andalso, {:<, :"$1", :"$2"}, {:<, :"$2", 0}}], [:"$2"]}], context: Matcha.Context.Table>
Link to this macro

trace_calls(module, function, opts \\ [], spec)

View Source (macro)

Traces function calls to module, executing a spec on matching arguments.

Tracing is a powerful feature of the BEAM VM, allowing for near zero-cost monitoring of what is happening in running systems. The functions in Matcha.Trace provide utilities for accessing this functionality.

One of the most powerful forms of tracing uses match specifications: rather that just print information on when a certain function signature with some number of arguments is invoked, they let you:

  • dissect the arguments in question with pattern-matching and guards
  • take special actions in response (documented in Matcha.Context.Trace)

This macro is a shortcut for constructing a spec with the :trace context via Matcha.spec/2, and tracing the specified module and function with it via Matcha.Trace.calls/4.

For more information on tracing in general, consult the Matcha.Trace docs.

examples

Examples

iex> require Matcha
...> Matcha.trace_calls(Enum, :join, limit: 3) do
...>   [_enumerable] -> message("using default joiner")
...>   [_enumerable, ""] -> message("using default joiner (but explicitly)")
...>   [_enumerable, _custom] -> message("using custom joiner")
...> end
...> Enum.join(1..3)
# Prints a trace message with "using default joiner" appended
"123"
iex> Enum.join(1..3, "")
# Prints a trace message with "using default joiner (but explicitly)" appended
"123"
iex> Enum.join(1..3, ", ")
# Prints a trace message with "using custom joiner" appended
"1, 2, 3"