These questions really strike right at the heart of language design philosophy! Here's my perspective.

In Rust, we try not to be too dogmatic about attributes like "simplicity", "expressivity", and so on. Instead, we're driven as much as possible by use-cases and programmer experience. So, taking higher-kinded types as an example: we've so far avoided adding them, waiting for strong demand and clear use-cases to emerge. While we now have a design that touches on HKT, we're also taking the most simple-minded approach we can that solves real-world use-cases.

This year, we've been really focused on reducing the learning curve, and increasing productivity around Rust. To do that, we've found ways to simplify or clarify existing features that benefit new and existing users alike. In some cases, this means using the information the compiler already has to avoid the need for you to jump through extra hoops. We've done this work with utmost care, ensuring that these improvements don't involve hidden complexities that you have to grapple with eventually. You can read more about the effort here.

The question of expressivity via macros vs the core language is an interesting one. To some degree, we see macros as a way of prototyping things that might become core features eventually; we're developing our async/await story this way.

While Rust libraries definitely do employ macros to do some pretty spectacular things, there are also some particularly common ways to use macros that don't feel so mysterious -- like automatically implementing traits for a particular struct. In my experience, as a client of these macros, I virtually never need to know anything about their implementation.