The complexity in language theory does not stem from a single concept, but from their mix. If you take something like generics on its own, it is rather simple to add to a language. But once you mix it with other concepts, the complexity rises exponentially.
Generics + subtyping (inheritance) gives rise to a number of complex situations. Java needed to embrace bounded polymorphism in the type system in order to handle this. And we don't know about a simpler type system which is sound and has that particular mix. If you remove subtyping and replace it with another construct, type classes or implicits, then generics are somewhat easier to fit to the language.
CSP turns out to be far more orthogonal, as long as you use a typed channel primitive. Hence, it is easier to fit CSP into an existing model because its composition with other type theoretic constructs is far simpler.
Generics + subtyping (inheritance) gives rise to a number of complex situations. Java needed to embrace bounded polymorphism in the type system in order to handle this. And we don't know about a simpler type system which is sound and has that particular mix. If you remove subtyping and replace it with another construct, type classes or implicits, then generics are somewhat easier to fit to the language.
CSP turns out to be far more orthogonal, as long as you use a typed channel primitive. Hence, it is easier to fit CSP into an existing model because its composition with other type theoretic constructs is far simpler.