Чем nil, false и :false отличаются друг от друга?

В Elixir (и в языке Erlang, на котором он основан), значения nil, false и :false — это разные сущности, хотя могут казаться схожими, особенно для тех, кто пришёл из языков с нестрогой типизацией вроде JavaScript или Python. Каждый из этих элементов имеет собственный тип и поведение, особенно в условиях, проверках и логических операциях.

1. nil

  • Тип: Это атом, обозначающий "отсутствие значения" (:nil).

  • Тип данных в Elixir: atom()

  • Логическое поведение: В логическом контексте считается ложью, как и false.

  • Используется как: пустое значение, аналог null в других языках.

x = nil
is_nil(x) # true
x == nil # true
if x, do: "yes", else: "no" # "no"
  • nil часто возвращается:

    • если поиск не дал результата (например, в Map.get/3)

    • если переменная не инициализирована

    • при отсутствии значения у опционального аргумента функции

2. false

  • Тип: булев тип (boolean())

  • Значение: булево ложное значение, противоположность true

  • **Используется в логических операциях
    **

x = false
is_boolean(x) # true
x == false # true
if x, do: "yes", else: "no" # "no"
  • В логических выражениях участвует наряду с true. Используется как результат сравнений, проверок и булевой логики:
Enum.any?(\[\], fn x -> x > 0 end) # false
  • Отличие от nil: false — логическая ложь, а nil — отсутствие значения, но оба интерпретируются как ложь в if, unless.

3. :false

  • Тип: атом с именем :false (аналог строкового значения 'false', но атомизированный)

  • НЕ является булевым значением! Это обычный атом, такой же как :ok, :error, :true, :ready, и т.п.

  • Логическое поведение: В отличие от false, **в логическом контексте считается истиной.

x = :false
is_atom(x) # true
x == false # false
if x, do: "yes", else: "no" # "yes"
  • Может использоваться как тег состояния, флаг, ключ в мапе и т.д., но не как булев тип.

Сравнение по типам

Значение Тип Логическое значение Комментарий
false boolean() Ложь Логическое значение
--- --- --- ---
nil atom() Ложь Отсутствие значения
--- --- --- ---
:false atom() Истина Просто атом с именем false
--- --- --- ---

Сравнение через == и ===

nil == false # false
nil == :false # false
false == :false # false
false === false # true
false === :false # false

Оператор === — строгий: сравнивает и тип, и значение. == — не строгий, но всё равно не приводит :false к false.

Использование в case, cond, if

if nil, do: "yes", else: "no" # "no"
if false, do: "yes", else: "no" # "no"
if :false, do: "yes", else: "no" # "yes"

Примеры практического отличия

def check_input(val) do
case val do
nil -> "Input is nil"
false -> "Input is false"
:false -> "Input is :false atom"
_ -> "Something else"
end
end
check_input(nil) # "Input is nil"
check_input(false) # "Input is false"
check_input(:false) # "Input is :false atom"

Заключение по сравнению (но без вывода, как просили)

  • false — булев тип, участвует в логике

  • nil — отсутствие значения, также ложь в логике

  • :false — обычный атом, может быть использован как метка, но не как false в логике

Это различие критично для правильной работы условных конструкций и сопоставления с образцом.