A new language today shouldn't really implement Python metaprogramming, because Python already does that.
Honestly, I don't think I'll ever create my own general-purpose language precisely _because_ I already know languages that are perfectly tailored to my use. If I start thinking of "what would my dream language look like", I start mentally re-creating Python. And sometimes, I might be in a different mood, and I'll think "wait, I'll make a statically-typed, AOT version of Python that I can use as a systems programming language instead of C/C++", and I end up mentally re-creating Nim, even to the point of going "well, I'll borrow the static typing part from Modula-3 because Modula-3 is cool and Python has a lot of Modula-3 in it already...", which is basically what Nim did.
There might be a lot to be said for rust-style immutable-by-default.
Ie often you have to get the complex data structures right (lots of logic, not much computation) to set up your computations on the simple ones (eg lots of number crunching on your arrays).
(Haskell also allows mutability that is visible to the semantics of the program, that's where the famous monads come in.)
I'm honestly not fond of languages like Rust that try to restrict mutability. The only one of the new breed of languages I've found that I really like is Nim.
Practically speaking, Python is still slower than a lot of languages that use predominantly immutable data structures. I think you'd want to go to a systems programming language for raw speed anyway.
Obviously programs that rely on communicating by mutating parts of a dictionary would have to be rewritten to use an immutable, persistent map—but they could still maintain similar performance.
[1]: Namely "adaptive radix trees" as described in “The adaptive radix tree: Artful indexing for main-memory databases” by V. Leis, A. Kemper, and T. Neumann <http://www3.informatik.tu-muenchen.de/~leis/papers/ART.pdf>
[2]: A persistent adaptive radix tree in Java: https://github.com/ankurdave/part
On the other hand, stating "they could still maintain similar performance" for immutable dictionaries is misleading at best (you are right for dictionary sizes approaching 0). Anyone can look up benchmarks on the Internet showing real-world performance of immutable data structures and make their mind up if they actually can deliver in their particular use cases.
Mutability could be always used to boost performance on Von Neumann architecture if you know what you are doing. It's just becoming impractical due to increased complexity, pervasive security paranoia and the fact that there are very few people that can get things done right. If you want to contribute to advance your case, please create a competing computer architecture as fast as Von Neumann's, physically possible, but based on immutability.
For the extreme case, see the EQUIVALENCE statement in old Fortran.
Reference counting and caching are probably the only areas where immutability can help for most programs.
Immutability is in fashion nowadays due to functional programming being in fashion despite the inability to ever achieve "pure" functional programming in reality - I/O is by default "dirty" (I really hate these charged words in computing), no amount of flatmapping (i.e. monads) is going to help with that.
Certainly this abstraction can stretch pretty well. Esp. when your language / framework can optimize immutable data structures under the covers (mutable and reuse.) But the abstraction is just that an abstraction for a mutable platform.
The platforms of today (VMs, operating systems, hardware, storage) are not immutable and notoriously full of side effects and undefined behavior. So these immutable language / frameworks end up being good tools at one extreme (high level data processing), bad at the other (system level languages) and vary on a case by case basis.
In today's todays platforms if you want to allocate an object in your language think of the layers and layers of side effects that will happen. 1. The allocator/GC system allocates it from some kind of pool possibly. Lots of side effects there (like operating on a pool, triggering some kind of collection / cleanup, requesting a large mapping from the OS. 2. Then at the OS level accessing mapped memory has all sorts of side effect (paging, lazy initialization, etc). 3. At the hardware levels there's lots of side effects: instruction cache, multiple layers of data caches, TLB, DMA.
In conclusion, for some kinds of problems you don't need to worry about these details and for others you can't afford to ignore them.
I guess there are subsets of problems where immutability is a good idea (anything needing state, 'Undo' capabilities), neutral, and a bad idea (number crunching, data processing, 'traditional'(??) programming).
I have been wowed by the beauty of the immutable approach in web apps, but definitely subscribe to the right technique for a task. I can't imagine doing the data processing in physics using an immutable language...
There are specialized high-performance structures that are mutable (e.g. disruptor in HFT trading) optimizing all the way down to CPU cache lines to achieve unbelievable speeds, yet they work nicely if the objects they refer to are immutable.
So just take all advices to switch to immutability with a grain of salt and learn to figure out which approach is suitable for what part of your system to have it both performing well and being able to conceptualize and maintain the code nicely ;-)
There is another use spurred by React: when you have a new state to represent, you have to diff it against current state to know exactly what changed and work only on this diff. "Immutable" structures make this trivial.