Pointers in Erlang

Erlang doesn’t have pointers in the same way as languages like C or Go. Instead, it uses immutable data and pattern matching. However, we can demonstrate similar concepts using processes and message passing.

-module(references).
-export([start/0]).

zero_value(Value) ->
    0.

zero_ref(Pid) ->
    Pid ! {set, 0}.

start() ->
    I = 1,
    io:format("initial: ~p~n", [I]),

    ZeroedValue = zero_value(I),
    io:format("zero_value: ~p~n", [I]),

    Pid = spawn(fun() -> loop(I) end),
    zero_ref(Pid),
    Pid ! {get, self()},
    receive
        {value, ZeroedRef} ->
            io:format("zero_ref: ~p~n", [ZeroedRef])
    end,

    io:format("process: ~p~n", [Pid]).

loop(Value) ->
    receive
        {set, NewValue} ->
            loop(NewValue);
        {get, From} ->
            From ! {value, Value},
            loop(Value)
    end.

In this Erlang example, we’ve created analogous concepts to demonstrate the difference between passing by value and passing by reference:

  1. The zero_value/1 function represents passing by value. It takes a value and returns 0, but this doesn’t affect the original value.

  2. The zero_ref/1 function represents passing by reference. It takes a process ID (Pid) and sends a message to set the value to 0.

  3. In the start/0 function:

    • We create an initial value I = 1.
    • We call zero_value(I), which doesn’t change I.
    • We spawn a new process that holds our value and can be updated.
    • We call zero_ref(Pid) to set the value in the spawned process to 0.
    • We then request the value from the process to show it has been changed.
  4. The loop/1 function represents our mutable state, which can be updated by sending messages.

To run the program:

$ erlc references.erl
$ erl -noshell -s references start -s init stop
initial: 1
zero_value: 1
zero_ref: 0
process: <0.80.0>

In this output:

  • zero_value/1 doesn’t change the original value of I.
  • zero_ref/1 changes the value held by the spawned process to 0.
  • The last line shows the Pid of the spawned process, which is Erlang’s equivalent of a memory address in this context.

This example demonstrates how Erlang uses processes and message passing to manage state, which is conceptually similar to using pointers in languages like C or Go.