Abstraction to the next level up is classically how language paradigms have progressed. From flicking switches that represent bits, to assembly language, to C, to memory managed languages, etc. Programming languages are not for the computer, they're for the computer programmers' weak grey matter between their ears. Future languages should be entirely about improved coping strategies for us.

Higher level abstractions allow the programmer to do more with fewer instructions. The closest we've got to that right now is monadic programming in Haskell (and other languages with first-class support for monads). They allow encapsulation of common patterns (if/then/else, exception handling, state management, environment passing, list processing, etc.). But it would be naive to think we're done.

Anybody who works on web-applications over a long time will realise we've run out of luck with our current languages. Code-bases that only grow and projects that never end. I work on a code-base of 15 million+ lines of code, and the language gives very little help in terms of managing that. Especially when the monolith gets broken up into services.

We need:

* Abstraction from the network to easily support distributed applications. Erlang has its actor system, which is the closest to this, I think. The standard criticism is that because networks can fail you can't build a one-size fits all system. Looking at the actor model it's clearly possible to build something that fits most common use-cases for distributed applications.

* Abstraction from error handling

* Abstraction from complex control flows over time - i.e. code where one line runs, then the next line might run 6 months later

* Abstraction from threads:
- No mutable data
- Built in support for synchronisation, coordination, and resolution. For example, types that support vector-clocks transparently, or the ability to have locally synchronised versions of something on a server, etc.

* Improved type systems that allow for easy type-driven development, so the compiler is enforcing the business rules of the system. Languages with dependent type systems are closest to this, but still often feel quite clunky. Perhaps even ban the use of types like int, string, etc. directly - you can only alias them into new-types like: Metres, PersonName, etc. so you're forced into using stronger types (although someone would probably just alias `int` to `Int` to get around it).

* Adaptive type systems that can describe a network of services. They would fail to compile if you send the wrong message to a service, and fail to compile if, a service which should be available, isn't.

* Something that's as simple to understand as Python for new devs.

* No null

* OO to die in a fire

I've personally had to build all the stuff above to facilitate the scale of our system - and by scale, I mean scale of code-base; any language that makes this stuff transparent and picks good safe default behaviours will speed up the process of writing new code and maintaining old code.

One thing that's of note when each paradigm comes along is how there's a mass of devs from the old paradigm that say "that's not real programming"; I think we'll only be at the next paradigm when we have that moment.