This is my own thesis and not really researched in the sense that I can point to any other articles, but it's what I've synthesized from my time as a programmer and studying CS.
There are many camps of programming thought, but I'm going to distill them here to two.
Mechanical: This is, fundamentally, the Turing machine. Assembly, C, Fortran, others, sit in this camp. They're very much concerned with the mechanical act of computation. We don't have high level abstractions (ok, we do, but they're very limited). This doesn't bar us from performing incredible feats of computation or computational thinking. But it does make some things more difficult, particularly the task of viewing the code and understanding what it was intended to model. There's a strong disconnect, then, between our high level concept of the system being developed (specification, requirements) and the low level implementation.
Mathematical: This is lambda calculus. Haskell, erlang, lisp, others, sit in this camp. They're more concerned with mathematical or symbolic understandings of computation. They tend to be less concerned with low level performance (though may still achieve it quite well) and low level implementation details (I don't care if my custom type BTree is implemented as an array under the hood, I care that it behaves in a way that satisfies its definition). This makes translation from specification to implementation almost trivial. With some care, you can practical document both at once with languages like Prolog or Haskell in a single document. The drawback is primarily one of performance. But that can be handled via implementations (FFI, smarter compilers, access to low-level primitives or "unsafe" code).
Hybrid: I'm not sure where to place OO, so I'm going to place it here. In theory, most OO languages should be able to deal with both quite well. In practice, they have historically sat too close to the mechanical side. Or abused the mathematical side to create horribly inefficient models. They offer the, theoretical, abstraction levels of functional languages, but the procedural components (the methods defined in the classes) to have fine control over performance.
You can, technically, achieve any computational task in any language. But the levels of abstractions they provide allow certain domains of problems to be solved almost trivially.
I could make a functional model of a radio system. A functional language or an OO language makes this effort almost trivial. I don't care about the underlying performance, this is a model so I can demonstrate sending messages between two radios and between components within the radios. I need to know that the specification itself is consistent, and, as a bonus, this model can be turned into a simulator for situations where we want more radios than we physically have or can set up in the lab.
Implementing this in C, from a performance perspective for the latter part, makes some sense. But it makes demonstrating that the high level specification and requirements are satisfied and implemented almost impossibly difficult.