Advent of Code 2023 - Day 1

This is not generally true in Elixir - all of the references in this example compile to a single entry in the LitT literal chunk:

defmodule Foo do
  @attr_version %{
    a: 1,
    b: 2,
    c: 3
  }

  def attr_lookup(x), do: Map.get(@attr_version, x)

  def inline_lookup(x), do: Map.get(%{a: 1, b: 2, c: 3}, x)

  def variable_lookup(x) do
    map = %{
      a: 1,
      b: 2,
      c: 3
    }

    Map.get(map, x)
  end
end

The Elixir compiler can safely make this optimization since values can’t ever be mutated - this is different from languages like Ruby where a literal constructed inside a method has to be distinct since it could be subsequently changed. For instance:

class Foo
  ALWAYS_THE_SAME = {a: 1, b: 2, c: 3}

  def self.as_constant
    ALWAYS_THE_SAME
  end

  def self.as_local
    {a: 1, b: 2, c: 3}
  end
end

puts Foo.as_constant.object_id == Foo.as_constant.object_id
puts Foo.as_local.object_id == Foo.as_local.object_id

prints true followed by false, because the result from as_local is a different object every time.

1 Like