Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/sviridov/anaphora-elixir

The anaphoric macro collection for Elixir
https://github.com/sviridov/anaphora-elixir

Last synced: about 2 months ago
JSON representation

The anaphoric macro collection for Elixir

Lists

README

        

## 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.