1. The tools we use have a profound (and devious!) influence on our thinking habits, and, therefore, on our thinking abilities.
Yeah, but It's not really insightful, this is basically a rephrasing of "If you have a hammer, everything is a nail".
Thats why it's so important to have many different tools at hand. If you give a life long C programmer the task to parse an string, he will most probably start by writing a low level state based text parser, while if you give the same task to a python programmer, he will probably just write a regex for it. That's the reason why I believe everyone should try out at least a few different paradigms like functional programming, it really broadens your horizon and allows you to think differently about problems.
For example, many computer scientists profess to be followers of Whorf and to be searching for a notation which prevents common programming errors, while at the same time being prepared to countenance syntaxes which can't be parsed easily and semantics which require complex run-time support.
It fully depends on what your needs are. For example, garbage collection is pretty slow, but if you don't need that performance and you simply want to get something done without having to think a. about ownership or b. about memory management, it works great (see Java, the performance penalty is not stopping it from being one of the most prevalent languages).
But even if you are concerned about performance there are many compile time possibilities, like they are employed by rust (and partly C++). Or, my favorite example for this are Null pointers. Null pointer errors are extremely tedious, even in pretty "safe" languages like Java.
But there is no need for them to exist. In for example TypeScript, Swift or Kotlin, there are no Null pointers, there are only Nullable variables. This means, every variable that can become null, must be marked as such. If a variable is marked as null, everywhere where it is used, you need to check if it is assigned (provable at compile time). If you know a variable will never be null, you will not mark it, and then you (and the compiler) knows, what ever happens, in this variable will always be a valid pointer.
All of this happens during compile time, and with this little change, Nullpointer derefenrencing seg-faults are simply not possible anymore. One of the major bug sources simply gone by a better language design without any penalty
Languages are designed with specific goals in mind. For example, haskell applications become huge because haskells lazy evaluation strategy requires a lot of boilerplate code for the compiler to generate. It is also not the fastest, but in haskell you can handle infinitely large objects with ease, something that is not easily possible in other languages.
It's all a matter of requirements. I would never write an OS in Java, but I also wouldn't write a cross plattform gui program in C.