Formalisms in concurrent and/or distributed programming? My background came from imperative languages, primarily C, C++, and Python. I picked up Scala, Erlang, and a bit of Haskell a few years later and have since become very interested in functional programming and the formalisms behind it.

I am also interested in concurrent and distributed programming and have been looking into formalisms behind that, especially those that have seen at least a tiny bit of the "light of day" (e.g. real world use, or at least an implementation somewhere). So far I know of Communicating Sequential Processes, the Actor model, Algebra of Communicating Processes, and the Calculus of Communicating Systems. Among these I know the Actor model has realized itself in languages like Erlang, Scala, and Haskell.

I am wondering if there are foundations I should learn and practice before tackling these fields, if there is a "classic" one that I should study first, and if there are any other popular ones that I may have missed?
The most widely used formalism is the $\pi$-calculus by Milner, Parrow and Walker. It is an extension of CCS, and comes in many variants, some of which (the asynchronous $\pi$-calculus) attempt to be a formalisation of the actor model. There are now many typing disciplines for $\pi$-calculi, the simplest of which are probably Honda's session types. Such types are slowly diffusing from research papers to research implementations.