Confused about why my `with` statement is not compiling:

  def subscribe(params) do 
    with params <- params,
      {:has_tickers, true} <- {:has_tickers, Map.has_key?(params, "tickers")},
      {:has_fields, true} <- {:has_fields, Map.has_key?(params, "fields")},
      {:all_list, true} <- {:all_list, Enum.all?(params, fn {_, p} -> is_list(p) end)} do
        com({:blp, [:barsubscribe, Map.put_new(params, :options, [])]}) # add options if not there
    else
      {:has_tickers, false} -> {:error, "No tickers provided"}
      {:has_fields, false} -> {:error, "No fields provided"}
      {:all_list, false} -> {:error, "All parameters must be lists"}
      _ -> {:error, "Unknown error"}
    end
  end

The above compiles, but this doesn’t:

  def subscribe(params) do 
    with 
      {:has_tickers, true} <- {:has_tickers, Map.has_key?(params, "tickers")},
      {:has_fields, true} <- {:has_fields, Map.has_key?(params, "fields")},
      {:all_list, true} <- {:all_list, Enum.all?(params, fn {_, p} -> is_list(p) end)} do
        com({:blp, [:barsubscribe, Map.put_new(params, :options, [])]}) # add options if not there
    else
      {:has_tickers, false} -> {:error, "No tickers provided"}
      {:has_fields, false} -> {:error, "No fields provided"}
      {:all_list, false} -> {:error, "All parameters must be lists"}
      _ -> {:error, "Unknown error"}
    end
  end

Why do I explicitly have to do include the params <- params clause?

Put the first clause on the line with the ‘with’

2 Likes

If you want the clauses on their own lines, you can use parens. The first paren must touch the with, though.

with(
  1 <- 1,
  2 <- 2
) do
  thing()
end

Also, if you use the formatter this will keep do on its own line.

4 Likes

For the future, it’s generally a good idea to post the error you receive when asking why something isn’t working. Makes it easier for those trying to help you.

6 Likes