I disagree with the statement that programming with plain threads and locks is somehow archaic. No, it is simply programming at a lower level of abstraction. In some cases it is more efficient and your specifications may require it. Think of state-heavy applications, and the interface between the module modifying internal program state (which may be done using actors or STM) and the module that performs external IO. In this case, you may need a lock to get a consistent snapshot of the data from your program's state to export it to an external source and in some cases it is more efficient to do so by locking the structure in memory.
Finally, locks don't always grow your complexity exponentially. What grows your complexity is when you have many different types of locks. Let's say we have an address book database program that implements concurrency by using threads. It is simple and inefficient to have a single global write lock. On the other end of the spectrum you have the ability to lock any field of any record, or the whole record, or a set of records, or a set of fields of a set of records, or records that don't even exist yet (gap lock) or the whole database. In-between, you have the ability to place a lock on the entire database or on just one record. You have to make the tradeoff between your time as a programmer and the efficiency of the code.
STM is a cool tool, but does have performance penalties [1]. It may be appropriate in some cases, and inappropriate at others, just like the actor model.
[1] http://en.wikipedia.org/wiki/Software_transactional_memory#P...