1
p(M, C, B, I) when B =:= 32#3J ->
    receive {_} -> a
    after 27#5C ->
        C ! { self(), { M, (B * 13#37) rem 35#7B, I }} end;

This is a part of code that expects input. I understand that it needs to look like (num,num,115,num) to pass the first part, but I don't understand what happens after that with the receive and the after part, can anybody explain?

I tried reading documentation of erlang and just couldn't understand that part of the code.

Steve Vinoski
  • 19,847
  • 3
  • 31
  • 46
ohno
  • 11
  • 1

1 Answers1

1

Here's what a receive expression looks like:

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
after
    ExprT ->
        BodyT
end

In erlang, a receive waits for a message to be sent to the process executing the receive. The message has to match a Pattern, in your case{_}, for the Body of the matching clause to execute (otherwise the receive waits indefinitely for a matching message). The term {_} matches any message that consists of a tuple, {}, with a single term inside the tuple, _. The notation _ matches anything, so the tuple could contain a nested tuple, a list, a string, a number...anything. So, the tuple {[1,a,"hello"]} would match, but not the tuple {a, 2}.

receive..after works exactly as receive, except that if no matching message has arrived within ExprT milliseconds, then BodyT is evaluated instead.

Here's your code:

p(M, C, B, I) when B =:= 32#3J -> 
    receive 
        {_} -> 
            a 
    after 27#5C -> 
        C ! { self(), { M, (B * 13#37) rem 35#7B, I }} 
end;

Integers can be expressed in the format: base#value, and 27#5C is the same as the decimal number 147.

In this line:

C ! { self(), { M, (B * 13#37) rem 35#7B, I }}

the variable C will contain a process identifier, called a "pid" in erlang, and the operator ! sends a message to the process specified on the left hand side. The right had side is the message that is sent to process C, which in this case is a tuple containing the current process identifier, self(), as the first term, and another tuple as the second term.

Your code consists of a function that contains a receive statement, where the receive has a 147 millisecond timeout. After the receive line executes, if there's a message currently in the process mail box that matches {_} or if the process receives a message that matches {_} within the next 147 milliseconds, then the function returns the atom a, otherwise the function sends a message to another process and returns the same message--because ! returns the right hand side.

In erlang, you can easily start 1 million processes on a basic laptop, and the processes can send each other messages and the processes can receive particular messages and execute code in response to those messages.

7stud
  • 46,922
  • 14
  • 101
  • 127