'with' and 'do:' Function Layout

Any tips on making simple functions with with statements look better?

def test, do:
        with x = 1, 
            y = 2,
            do: 
                x + y

I’d like the x and y to line up for example, but doesn’t seem possible without breaking a whitespace rule or a lot of fussing

3 Likes
def test do
  with x = 1,
       y = 2,
       do: x + y
end
3 Likes

I usually go with:

def test do
  with {:ok, x} <- foo,
       {:ok, y} <- bar(x),
   do: {:ok, process(y)}
end
3 Likes

Another option our team has experimented with:

def test do
  with \
    {:ok, x} <- foo,
    {:ok, y} <- bar(x) do
    {:ok, process(y)}
  end
end
3 Likes

oh I like the backslash - thx all!

3 Likes

Is the backslash necessary or will it compile without it?

2 Likes

For do/end handling I newline following do, then two space indentation:

  def get_message(%User{} = user, id) do
    with %Message{} = msg <- Repo.get(Message, id),
         :ok <- MessageAuthorization.authorize(:view, user, msg) do

      {:ok, preload(msg)}
    else
      nil -> {:error, :not_found}
      {:error, :unauthorized} -> {:error, :unauthorized}
    end
  end

1 Like

I go with

with {:ok, foo} <- foo,
     {:ok, bar} <- bar,
  do: foo + bar

as show in the code examples in the documentation for with. That could maybe settle the style? :slight_smile:

1 Like