Packages
croma
0.4.4
0.13.0
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.3
0.7.2
0.7.1
0.7.0
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Elixir macro utilities to make type-based programming easier
Current section
Files
Jump to
Current section
Files
lib/croma/struct_call_syntax.ex
defmodule Croma.StructCallSyntax do
@moduledoc """
This module provides a new syntax with `~>` operator for calls to functions that take structs as 1st arguments.
To enable the syntax `import` this module:
import Croma.StructCallSyntax
This module is not `import`ed by `use Croma`.
It is necessary to explicitly `import` this module.
## Examples
iex> defmodule S do
...> defstruct [:a, :b]
...> def f(s, i) do
...> s.a + s.b + i
...> end
...> end
...> import Croma.StructCallSyntax
...> s = %S{a: 1, b: 2}
...> s~>f(3) # => S.f(s, 3)
6
Note that calling functions with the `~>` syntax involves the following tradeoff:
- pros
- Shorter code
- Flexibility due to dynamic dispatch
- cons
- Run-time overhead due to dynamic dispatch
- Less information available to static analysis tools such as dialyzer
- Confusions due to new syntax
It is recommended that you think carefully about the above pros/cons for using this module.
If all you want is dynamic dispatching based on the receiver's type you can use protocol instead.
"""
@doc """
A macro that provides a syntax that resembles method invocations in typical OOP languages.
The module that defines the target function is extracted from the "receiver" struct (i.e. left hand side of `~>`) at run-time.
The "receiver" is then passed as the 1st argument to the function.
"""
defmacro struct ~> {f, _, atom} when is_atom(atom) do # without parameter list
quote bind_quoted: [struct: struct, f: f] do
%{__struct__: mod} = struct
apply(mod, f, [struct])
end
end
defmacro struct ~> {f, _, args} do # with parameter list
quote bind_quoted: [struct: struct, f: f, args: args] do
%{__struct__: mod} = struct
apply(mod, f, [struct | args])
end
end
end