title: Elixir: How to deal with optional / default parameters in functions and nil values?
body: <p>I have a general question about default parameters and nil values. Suppose I have two functions. One calls the other (which is a helper function). Both have an optional parameter. </p>
  
  <p>The helper function just joins a list to a string with a joiner. The joiner is passed to the first function inside an opts keyword list. The passing of the joiner is optional, it defaults to <code>"AND"</code></p>
  
  <pre><code>defmodule ParamTest do
    def func_1(list, opts \\ []) do
      helper(list, opts[:joiner])
      # Do something else with the result
    end
  
    defp helper(list, joiner \\ "AND") do
      Enum.join(list, " #{joiner} ")
    end
  end
  
  # Example 1
  ["el 1", "el 2"] 
  |&gt; ParamTest.func_1(joiner: "AND")
  # Result "el 1 AND el 2"
  
  # Example 2
  ["el 1", "el 2"] 
  |&gt; ParamTest.func_1
  # Result: "el 1  el 2"
  # But it should be also "el 1 AND el 2"
  </code></pre>
  
  <p>The problem is: opts[:joiner] will be nil in the second example. But it is still present so the default value will not be used.</p>
  
  <p>One possible solution would be to use <code>case</code>: </p>
  
  <pre><code>defmodule ParamTest do
    def func_1(list, opts \\ []) do
      case is_nil(opts[:joiner]) do
        true -&gt; helper(list)
        false -&gt; helper(list, opts[:joiner])
      end
      # Do something else with the result
    end
  
    defp helper(list, joiner \\ "AND") do
      Enum.join(list, " #{joiner} ")
    end
  end
  </code></pre>
  
  <p>Another way would be to use two function definitions for helper and use pattern matching:</p>
  
  <pre><code>defmodule ParamTest do
    def func_1(list, opts \\ []) do
      case is_nil(opts[:joiner]) do
        true -&gt; helper(list)
        false -&gt; helper(list, opts[:joiner])
      end
    end
  
    defp helper(list, nil) do
      Enum.join(list, " AND ")
    end
  
    defp helper(list, joiner \\ "AND") do
      Enum.join(list, " #{joiner} ")
    end
  end
  </code></pre>
  
  <p>But I have the feeling that this is not very elegant and could get messy in more complex situations. </p>
  
  <p>What is a better solution for this scenario?</p>