[something(X) || X <- L]
, is a list comprehension. L
is a list of elements, and this expression creates a list of new elements, forming each element by invoking something() on it.
[something(X,Y) || X <-L, Y<-M]
is similar, but an element is created for the Cartesian product of each element in X and Y.
[something(X) || X <-L, Expr]
is a filter expression. Same as the first one, but it is executed only for elements of L, where Expr is true for the given X.
[something(X) || {X,..} <-L, Expr]
is another kind of filter. In the list comprehension only those elements are taken that can be matched by the element.
One more thing to know is that this can not only be used for generating another list, but also for executing a command for each element. If the result of the list comprehension is not matched, the compiler will know not to generate a list at all. This behavior can be used to mimic foreach
from other languages.
Some examples:
1> [ X*2 || X <- [1,2,3] ].
[2,4,6]
2> [ X*Y || X <- [1,2], Y <- [3,4,5] ].
[3,4,5,6,8,10]
3> [ X*3 || X <- [1,2,3,4], X rem 2 == 0 ].
[6,12]
4> [ X || {a,X} <- [{a,1},{a,2},{b,3},{c,4}] ].
[1,2]
So your code generates the Cartesian product of all {Pid1a, V1a} elements from PV1a and Pid2 elements from P2, except for those elements where Pid1a equals Pid2, and for each of these pairs sends the {delete, V1a} message to Pid2.