Home

Awesome

HappyWith

Travis Hex.pm

Tiny syntax sugar around Elixir's with special form.

Why ?

Because I'm happy on how Elixir's with special form works, and can get used to the <- arrow but I still dont like to place commas between all the with expressions.

Back then before elixir 1.2 release, I implemented happy using case expressions, it leaked variables as normal case expressions would do, and overriding the standard = operator turned out to have some unexpected issues. Also, after using standard with a bit, I really got to like it, except for the fact of having to place commas after expressions, so I wrote happy_with which is a very tiny macro that just rewrites to Elixir's standard with special form.

This package implements the tags feature originally found in happy_path.

For more examples see docs

Installation

Available in Hex, the package can be installed as:

  1. Add happy_with to your list of dependencies in mix.exs:
def deps do
  [{:happy_with, "~> 1.0"}]
end

Usage

import HappyWith

happy_with macro

happy_with do
  {:ok, friend} <- retrieve_friend
  String.downcase(friend)
else
  _ -> "nobody"
end

rewrites into standard with form. Only the last expression in the happy_with block is given to with's do.

with({:ok, friend} <- retrieve_friend)
do
  name = String.downcase(friend)
else
  _ -> "nobody"
end

IMHO the first one reads better.

Examples

Rewrites the given block and else clauses into Elixir's standard with form.

iex> import HappyWith
iex> happy_with do
...>   {:ok, name} <- {:ok, "joSE"}
...>   lower = String.downcase(name)
...>   lower
...> end
"jose"

You can also provide else clauses to the with form.

iex> import HappyWith
iex> happy_with do
...>   {:ok, name} <- {:error, :nobody}
...>   _never_reached = String.downcase(name)
...> else
...>   {:error, _} -> "luis"
...> end
"luis"

You can also use tags a feature from the happy project.

iex> import HappyWith
iex> happy_with do
...>   @something {:ok, name} when is_binary(name) and length(name) > 3 <- {:error, :nobody}
...>   _never_reached = String.downcase(name)
...> else
...>   {:something, {:error, _}} -> "could not fetch name"
...> end
"could not fetch name"