What Even Is A Programming Language
This seems like a crazy question coming from a programmer, most probably directed at other programmers. But think about it for a minute. I don't want to step back too far, to get us into meta-physics, and start questioning the very fabric of reasoning. But let's try at least to break down the concept in lay terms. Let's try to break it down into the most simple concepts we can think of. As if you had to talk about this at the dinner table with your grandma.
Language has words, which you put together to communicate something. The most intuitive instance of language we can think of is spoken language, or better national language. Every nation (which depending on the regional scope branches off into smaller regional classification, with more nuanced differences) has developed their own way of speaking about things. The same things, since we are on the same planet. But there are things, some cultural objects, that some regions value more then others. Some concepts that are simply more familiar than others, or that one culture thinks about differently because of their experiences with it. A word like "Gemütlichkeit" from german, has hardly any direct translation to other languages, because the cultures are different. To understand the word "Gemütlichkeit", you would have to experience it. I don't want to say that this is a feature unique to german. I am sure every language has multiple instances of this principle. Just show that some words convey cultural objects, to justify their existence. However languages have also influenced other languages in the way they speak. Like the Latin languages influencing the south-European / Mediterranean languages, sharing many roots. But even germanic languages have not been untouched, which lead to words like Maximum, or Minimum in a language like German, which usually does not sound at all like other latin languages. Germans even adapted the declination system from Latin, communicating sentence cases by changing the suffixes of verbs, pronouns and nouns.
But this brings us right down to a common ground with programming languages. Languages inspiring other languages, and using similar constructs to appeal to familiarity. Who decides what a word even is? First and foremost words are just symbols. Things that represent other things. They get assigned meaning, rather than intrinsically / naturally carrying it. Then of course words start to inspire other words, just out of convenience, since we are pattern-oriented and can process things easier when we can relate them to familiar material. But think about the idea of words. When you say the word "tree", you are not talking about the literal word "tree", the collection of letters "t, r, e", but the idea of a tree.
Because someone once decided to call that thing a tree. But then new concepts are being associated with it like the word "family tree". Does this mean that my family has a tree in their garden? Or that my family reproduces by planting seeds in the ground? Is my father a plant? No. We abstract the structural features of a tree and apply it to something else. We refer to something organic, with roots, that grows and branches off.
Ok enough of that, for now. So if we now transfer it to programming languages, we have words, or better symbols that convey meaning; concepts. These concepts similar to other languages are abstractions for simpler or different concepts, they refer to. While in "spoken languages" we can only talk about what we know about, therefor about cultural objects present in our culture. In programming languages we can only talk about things that exist in a computer system. They need to be implemented first. A language is just a vehicle to refer to those implemented objects. Let us make an example. In Javascript a common pattern is to use events. Some parts of the system spawn the events, other parts subscribe or "listen" to those events and "handle" the reaction to that event. Since this is not an article about Javascript, I will not go too much into detail. But the environment that supports Javascript (Browser, nodejs, etc...), needs to implement something called the Event loop, that simply spins continuously and asks all the participants in the Event business, if they changed and if they want to spawn an event, and then call all the "listening" participants.
So what I am trying to show here, is that the language itself (the collection of words making up the language) is not responsible for this behavior. It provides you with terminology and a syntax to express this concept, but the environment that processes that language needs to be aware of that concept. The semantics need to be implemented. Some system must exist, which can interpret it (not the technical term, opposed to compile), but rather a synonym for understand, and being able to act on the symbol it carries.
Languages are just abstractions to refer to things that already exist in the environment. Like the national languages being on the same planet, but focusing on different cultural objects, programming languages at the end boil down to the same hardware behavior, but just interpret or are "aware" of different notions about that same thing. So when evaluating a new programming language, we need to look past the similarities or dissimilarities it might have to other languages based on keywords, names, syntax or constructs.
"Oh C and C# are super related, because they share basically the same name. Both have code blocks delimited by curly braces and mark statements with ";" ". But this is very far from the truth. C is a language that directly compiles to binary. It enables you access to memory addresses. It even has the "goto" statement which just enables you to deliberately jump into a segment of code, without following the flow of the program. C# on the other hand doesn't care about manual memory management and is garbage collected. The idea of memory addresses is therefor abstracted away. C# doesn't have a notion of the concept of Memory, similarly how the English don't have a notion of the concept of "Gemütlichkeit". Does it mean that english speaking people don't know how to relax and have a good time? No of course not, but they don't have the necessity to refer to it so precisely.
While C# is running on a virtual machine and compiles to byte code. It shares an environment which is populated by assemblies, this allows code sharing through namespaces that organize the overall program structure. In C you need to manually reference other components (files, libraries, modules), which are "copy and pasted" definitions from one file into another (the essence of the "include" directive), done by the compiler, so that the linker can then find that symbol in another file. The way you build software with one or the other is fundamentally different. And yet both allow you to write general-purpose applications, full of fantastic computations.
So what I am trying to say here is the following: languages are just a collection of symbols arranged in a syntax, which can sometimes look similar, usually trying to make it as accessible as possible to express relationship and operations in computer systems. However they are just accessors to implementations of concepts that can be worlds apart, from one programming language to another. And when you learn a new programming language it is important to look past the syntactical mantle of a language and really understand the concepts that hide behind them. This is what makes a programming language, a "programming" language, otherwise it is just a "language".
This became very apparent to me, when I had to implement my own assembly and high-level language that compiles to it (all-though super stripped down and simple). First I had to model an entire subsystem of functionality in the existing language, so that I later could just refer to that concept in terms of a symbol in the other language. And this notion pops into my mind every time I read or hear phrases like "this language has this and that feature". What is actually meant is, the environment responsible for interpreting that language has that feature, and can therefor understand and execute it. Someone didn't just deliberately say, "ah yes, in my language I want the word event", and it became a feature of that language. But someone had to architect the implementation of that concept and provide a system that is able to execute these semantics. And this makes every different programming language very valuable!
Takeaway
A Programming language is a collection of executable symbols organized in constructs by a syntax to express processes and relationships. But to be able to use a programming language one should be familiar with the concepts that hide behind each symbol and be aware of the environment the language is embedded in, and which system is responsible of interpreting it.