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
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
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 withMatcha.Trace
functions - Use the
:table
context if you intend to trace code execution with theMatcha.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>
@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>
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"