Slices in Elixir

Here’s the translation of the Go code example for slices into Elixir, along with explanations in Markdown format suitable for Hugo:

In Elixir, we use lists and tuples instead of slices. Lists are more flexible and can be used in similar ways to Go’s slices.

defmodule SlicesExample do
  def run do
    # Unlike Go's slices, Elixir lists are always initialized.
    # An empty list is represented as [].
    s = []
    IO.puts("uninit: #{inspect(s)} #{s == []} #{length(s) == 0}")

    # To create a list with a specific length, we can use List.duplicate/2
    s = List.duplicate(nil, 3)
    IO.puts("emp: #{inspect(s)} len: #{length(s)}")

    # We can set and get elements using list manipulation functions
    s = ["a", "b", "c"]
    IO.puts("set: #{inspect(s)}")
    IO.puts("get: #{Enum.at(s, 2)}")

    # length/1 returns the length of the list
    IO.puts("len: #{length(s)}")

    # We can append to lists using the ++ operator
    s = s ++ ["d"]
    s = s ++ ["e", "f"]
    IO.puts("apd: #{inspect(s)}")

    # Lists can be copied using the = operator
    c = s
    IO.puts("cpy: #{inspect(c)}")

    # Slicing in Elixir is done with Enum.slice/3
    l = Enum.slice(s, 2..4)
    IO.puts("sl1: #{inspect(l)}")

    # Slicing up to an index
    l = Enum.slice(s, 0..4)
    IO.puts("sl2: #{inspect(l)}")

    # Slicing from an index to the end
    l = Enum.slice(s, 2..-1)
    IO.puts("sl3: #{inspect(l)}")

    # We can declare and initialize a list in a single line
    t = ["g", "h", "i"]
    IO.puts("dcl: #{inspect(t)}")

    # Comparing lists
    t2 = ["g", "h", "i"]
    if t == t2 do
      IO.puts("t == t2")
    end

    # Creating a list of lists (similar to 2D slices in Go)
    two_d = for i <- 0..2 do
      for j <- 0..(i) do
        i + j
      end
    end
    IO.puts("2d: #{inspect(two_d)}")
  end
end

SlicesExample.run()

This Elixir code demonstrates concepts similar to Go’s slices, using Elixir’s lists and list manipulation functions. Here’s a breakdown of the differences and similarities:

  1. Elixir uses lists instead of slices. Lists in Elixir are always initialized.
  2. We use List.duplicate/2 to create a list with a specific length, similar to Go’s make.
  3. Appending to lists is done with the ++ operator instead of append.
  4. Copying lists is simpler in Elixir, as we can just use the = operator.
  5. Slicing in Elixir is done with Enum.slice/3, which is similar to Go’s slice syntax.
  6. List comparison is done with == in Elixir, similar to Go’s slices.Equal.
  7. Multi-dimensional lists in Elixir are created using list comprehensions, which is more concise than the Go equivalent.

When you run this program, you’ll see output similar to the Go example, demonstrating the various list operations in Elixir.

Note that while Elixir’s lists and Go’s slices serve similar purposes, they have different performance characteristics. Elixir’s lists are implemented as linked lists, while Go’s slices are backed by arrays.

$ elixir slices_example.exs
uninit: [] true true
emp: [nil, nil, nil] len: 3
set: ["a", "b", "c"]
get: c
len: 3
apd: ["a", "b", "c", "d", "e", "f"]
cpy: ["a", "b", "c", "d", "e", "f"]
sl1: ["c", "d", "e"]
sl2: ["a", "b", "c", "d", "e"]
sl3: ["c", "d", "e", "f"]
dcl: ["g", "h", "i"]
t == t2
2d: [[0], [1, 2], [2, 3, 4]]

This example demonstrates how to work with lists in Elixir, which are used in similar ways to slices in Go. Next, we’ll look at Elixir’s equivalent of Go’s maps: the Map data structure.