Slices in Erlang

In Erlang, there isn’t a direct equivalent to Go’s slices. However, we can use lists to demonstrate similar concepts. Lists in Erlang are immutable, so operations that modify the list actually return a new list.

-module(lists_example).
-export([main/0]).

main() ->
    % Unlike Go slices, Erlang lists are not typed by their elements.
    % An empty list is represented as [].
    S = [],
    io:format("uninit: ~p ~p ~p~n", [S, S =:= [], length(S) =:= 0]),

    % To create a list with a specific length, we can use a list comprehension
    S1 = [[] || _ <- lists:seq(1, 3)],
    io:format("emp: ~p len: ~p~n", [S1, length(S1)]),

    % We can set elements in a list using list comprehension or manual construction
    S2 = ["a", "b", "c"],
    io:format("set: ~p~n", [S2]),
    io:format("get: ~p~n", [lists:nth(3, S2)]),

    % length returns the length of the list
    io:format("len: ~p~n", [length(S2)]),

    % To add elements to a list, we use the ++ operator
    S3 = S2 ++ ["d"],
    S4 = S3 ++ ["e", "f"],
    io:format("apd: ~p~n", [S4]),

    % To copy a list, we can simply assign it to a new variable
    C = S4,
    io:format("cpy: ~p~n", [C]),

    % List slicing can be done using lists:sublist/3
    L1 = lists:sublist(S4, 3, 3),
    io:format("sl1: ~p~n", [L1]),

    % This gets all elements up to (but not including) the 5th element
    L2 = lists:sublist(S4, 1, 5),
    io:format("sl2: ~p~n", [L2]),

    % This gets all elements from the 3rd element to the end
    L3 = lists:nthtail(2, S4),
    io:format("sl3: ~p~n", [L3]),

    % We can declare and initialize a list in a single line
    T = ["g", "h", "i"],
    io:format("dcl: ~p~n", [T]),

    % Erlang doesn't have a built-in function to compare lists for equality,
    % but we can define our own
    T2 = ["g", "h", "i"],
    case T =:= T2 of
        true -> io:format("t == t2~n");
        false -> io:format("t != t2~n")
    end,

    % Lists can be composed into multi-dimensional data structures
    TwoD = [[I + J || J <- lists:seq(0, I)] || I <- lists:seq(0, 2)],
    io:format("2d: ~p~n", [TwoD]).

To run this program, save it as lists_example.erl and use the Erlang shell:

$ erl
1> c(lists_example).
{ok,lists_example}
2> lists_example:main().
uninit: [] true true
emp: [[],[],[]] 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],[0,1],[0,1,2]]
ok

Note that while Erlang lists are different from Go slices in many ways (immutability being a key difference), we’ve tried to demonstrate similar concepts where possible. Erlang’s functional nature means that operations which would modify a slice in Go instead return a new list in Erlang.

Erlang doesn’t have a direct equivalent to Go’s slices package, but many list operations can be performed using functions from the lists module.

For more complex data structures or when performance is a concern, you might want to consider using Erlang’s arrays or other data types provided by the standard library.