For many domains, being able to implement a domain-specific language with a set of expressive rules for the domain is an incredible productivity boost and also prevents many mistakes because you cannot represent them.
Not being able to manipulate the AST means that you are restricted on the embedded DSLs that you can provide. And embedded DSLs encompasses code generation for:
- state machines
- parsing grammars (PEGs for example)
- shader languages
- numerical computing (i.e. having more math like syntax to manipulate indices)
- deep learning (neural network DSL)
- HTML templates / generators
- monad composition
There is a reason most people are not building in Assembly anymore, there is a right-level of abstraction for every domain. A language that provides building block for domain expert to build up to the right level of abstraction is very valuable.
Low-level languages (aka "systems programming" languages) already suffer from various constraints that increase their accidental complexity. Is it really necessary to complicate those particular languages further to support embedded DSLs?
I don't think there's a universal right or wrong answer here, but there is certainly a big question.
It's very easy to come up with examples of terrible abuse of these features that lead to bad code (like for instance if somebody was insane enough to overload the binary shift operator << to, I don't know, write to an output or something) but it also gives a lot of power to write concise and expressive code.