Search code examples
erlangerlang-shell

Variables bind once in Erlang


Edit: I changed the title of this question, as it wasn't useful in light of the n00b mistake I had made. The remainder is unchanged, and serves as a cautionary tale!

I am using Erlang OTP version 17.4. Consider the following Erlang shell session where I am experimenting with the trap_exit process flag as explained in "Learn You Some Erlang:Errors and Processes".

First, I set the trap_exit flag to convert exit signals in linked processes to regular messages:

Eshell V6.2  (abort with ^G)
1> process_flag(trap_exit, true).
false

Then I spawn a linked process and terminate it immediately with a call to exit/2:

2> exit(spawn_link(fun() -> timer:sleep(50000) end), kill).
true

Then I read the converted exit message:

3> receive X -> X end.
{'EXIT',<0.61.0>,killed}

All looking good so far, just like the book describes. Now, just for fun, I spawn_link and terminate another process:

4> exit(spawn_link(fun() -> timer:sleep(5000) end), kill).
true

And try to read the converted exit message:

5> receive X -> X end.

At this point the shell hangs. My question is why does the behaviour change on the second go around and where did the exit message go?


Solution

  • Your second receive X -> X end. already has X bound; it is attempting to receive a message exactly matching the one you already saw. Since the pid is going to be different, the message will never match. So it hangs, waiting for one that does match.

    You need to f(X) first.