Blurring Language Boundaries
You even had languages like C# and .NET that were specially made for a particular environment (vs. Java).
But the language boundaries are blurring quickly.
Intermediate languages – This idea has been around forever, and the most famous implementation is probably the Common Intermediate Language Runtime (CIL) that targets the Common Language Runtime (CLR) for .NET. You had languages like C#, F#, IronRuby, IronPython that compiled down to the CIL and were runnable via the CLR.
The evolution of this is WebAssembly (Wasm) which is a compilation target for LLVM-based languages.
Generated code – There are more libraries that will automatically scaffold client/server stubs for multiple languages – see OpenAPI or
Transpilation – A final emerging one is source-to-source compilation. Translating one language to another. This is sometimes a lossy translation – what does it mean to translate a Python class to a Go struct? In the past, this was painstakingly done by hand (albeit a great way to practice your programming). Now, the latest LLMs are pretty good at keeping semantic meaning and transpiling code (better than most humans I'm sure). For many libraries, we might see polyglot representations via LLMs.
While the trend has generally been fewer languages over the years, maybe we'll go back to having a widespread number of languages that all can interact with each other. Or, maybe we'll just have one meta-language that can call everything.