I use a separate tool to call a lot of functions written in C. That tool is called “Python”. Or “Ruby”.
Sometimes I use a separate tool to call functions written in Python (or JavaScript, or...) and that tool is called PostgreSQL.
Sometimes I use Ruby to call C to call Postgres to call JS.
> Now that we have better languages, why not use them to write the OS bottom-up?
What better languages for implementing an OS? Lisp? We had that before C. Rust? Either way—and I like both languages—I don't want to use either for a shell. Red? Maybe, but I don't think we're to the point of a Red OS yet, and while it's probably eventually usable for that purpose, I don't see it as necessarily ideal for OS implementation though it might be tolerable as a shell language.
There is a long history of alternative shells csh, tcsh, zsh, fish, etc. All with various level of abstraction and various amounts of "programming language type constructs" (for lack of a better term).
At the end of the day, long arguments have been had over which is the better shell. It's all just personal preference. Hence it can be set in /etc/passwd per user.
You prefer python? chsh is there to change it.
Space on a line is limited and one directional, so thr tools naturally evolved towards strange single line incantations instead of full fledged programs.
Commodore Pet did it right by introducing a navigable terminal where you could move between lines and don't need to open an editor to write multiline programs.
Modern CLIs can usually emulate at least a few of the old scrolling character matrix displays, but only a few bash commands (e.g. top) use the extra features.
I’m not saying POSIX shells are without fault but they weren’t just created because C is too low level; they were created because people used a terminal who weren’t always techies so Bell Labs created a language which anyone could easily write simple programs with. Granted that need has dissipated a little but your solution of having one language to rule them all creates more problems than it solves (really the only problem it solves is OCD for a few LISP enthusiasts).
The reason there are so many different programming languages isn’t just an element of NIH; some languages do genuinely handle some use cases better than some other languages. Plus there is always going to be an element of user preference. So your idea of a perfect system would be hell for a great many other people - myself included (and I do generally enjoy functional programming).
Compare Rust, which tries to keep allocations (and the size/asymptotic complexity of allocations) explicit and visible.
[1] The optimizer catches some cases, but not all of them.