title: Erlang: Why can't I register self()?
body: <p>This line fails with a <code>badarg</code> exception:</p>
  
  <pre><code>register(myproc, self()),
  </code></pre>
  
  <p>The documentation says that <code>self/0</code> returns a pid and that <code>register/2</code> takes a pid. So what gives?</p>
  
  <p><strong>Edit:</strong> No, seriously, it's not already registered, it's not a reserved atom, and it works when I register it from the process that's spawning it.</p>
  
  <p>Oh weird! Okay, I got some more clues. When I move the call to <code>register()</code> around to different places, sometimes it works and sometimes it breaks. Here's my sample code. Run it before you call me crazy. :-)</p>
  
  <pre><code>-module(pingpong).
  -export([start/1,  ping/2, pong/0]).
  
  ping(N, Pong_Pid) -&gt;
      link(Pong_Pid), 
      pingr(N, Pong_Pid).
  
  pingr(0, _) -&gt;
      io:format("Ping exiting~n", []),
      exit(ping);
  
  pingr(N, Pong_Pid) -&gt;
      Pong_Pid ! {ping, self()},
      receive
          pong -&gt;
              io:format("Ping received pong~n", [])
      end,
      pingr(N - 1, Pong_Pid).
  
  pong() -&gt;
      %% This one works.
      %%register(pong, self()),
      process_flag(trap_exit, true), 
      pongr().
  
  pongr() -&gt;
      %% This one fails.
      register(pong, self()),
      receive
          {ping, Ping_PID} -&gt;
              io:format("Pong received ping~n", []),
              Ping_PID ! pong,
              pongr();
          {'EXIT', From, Reason} -&gt;
              io:format("pong exiting, got ~p~n", [{'EXIT', From, Reason}])
      end.
  
  start(Ping_Node) -&gt;
      PongPID = spawn(pingpong, pong, []),
      spawn(Ping_Node, pingpong, ping, [3, PongPID]).
  </code></pre>