## Anaphora [![Build Status](https://travis-ci.org/sviridov/anaphora-elixir.svg)](https://travis-ci.org/sviridov/anaphora-elixir) [![license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](https://github.com/sviridov/anaphora-elixir/blob/master/LICENSE) [![hex.pm](http://img.shields.io/badge/hex.pm-0.1.2-brightgreen.svg)](https://hex.pm/packages/anaphora)
`Anaphora` is the anaphoric macro collection for [Elixir](https://github.com/elixir-lang/elixir/). An anaphoric macro is one that deliberately captures a variable (typically `it`) from forms supplied to the macro.
### Getting Started
- Add the `Anaphora` dependency to your `mix.exs` file:
```elixir
def deps do
[{:anaphora, "~> 0.1.2"}]
end
```
- After you are done, run `mix deps.get` in your shell.
### Provided API
#### alet
`alet` is basic anaphoric macro. It's not very useful in user code but other anaphoric macros are built on top of it. `alet` binds result of the expression to the `it` variable (via `case`) in the scope of the body:
```elixir
defmodule User do
use Anaphora
...
def user_email(user_id) do
alet fetch_user(user_id) do
if it, do: it.email, else: raise "Failed to fetch user"
end
end
end
```
#### aif
Works like `if`, except that result of the condition is bound to `it` (via `alet`) for the scope of the then and else clauses:
```elixir
defmodule User do
use Anaphora
...
def user_email(user_id) do
aif fetch_user(user_id), do: it.email, else: raise "Failed to fetch user"
end
end
```
#### acond
Works like `cond`, except that result of each condition is bound to `it` (via `alet`) for the scope of the corresponding body:
```elixir
defmodule Notification do
use Anaphora
...
def send_notification(user, message) do
acond do
user.email -> send_notification_by_email(it, message)
user.phone -> send_notification_by_sms(it, message)
:else -> raise "Unable to send notification"
end
end
end
```
#### acase
Works like `case`, except that result of the key expression is bound to `it` (via `alet`) for the scope of the cases.
#### afn
Works like `fn`, except that anonymous function is bound to `it` (via `blood magic`) for the scope of the function body:
```elixir
import Anaphora
in_order_tree_traversal = afn do
{left, center, right}, callback ->
it.(left, callback)
callback.(center)
it.(right, callback)
nil, _ -> nil
end
in_order_tree_traversal.({{nil, 1, nil}, 2, {nil, 3, {nil, 4, nil}}}, &IO.puts/1)
# => 1, 2, 3, 4
```
**warning:** Invocation of `it` takes a lot of time. Don't use `afn` in performance critical code. It will be fixed after [Elixir](https://github.com/elixir-lang/elixir/) `1.0` release.
#### aand
Evaluates each clause one at a time and binds result to `it`. As soon as any clause evaluates to `nil` (or `false`), `aand` returns `nil` without evaluating the remaining clauses. If all clauses but the last evaluate to true values, `aand` returns the results produced by evaluating the last clause:
```elixir
defmodule Notification do
use Anaphora
...
def send_email_to_user(user_id, message) do
aand do
fetch_user(user_id)
it.email
send_email(it, message)
end || raise "Unable to send email"
end
end
```
### License
Anaphora source code is released under The MIT License. Check LICENSE file for more information.