What’s in a Language?
A programming language is an interface between humans and computers, that allows us to program computers to perform some task. The purpose of the task is usually to solve some particular problem that the human has. Most languages are Turing complete, which essentially means that they are mostly all equivalent. So what’s the point of creating a new programming language if it’s equivalent to ones that already exist? Turing completeness means that languages are equivalent in terms of the programs they are able to express, but it says nothing about the journey of getting to the finished program.
If you think hard enough about your problem, there are probably some soft requirements that go along with it as well. The solution might require one or more of the following properties:
- it should be flexible to changing requirements,
- it should perform quickly,
- it should be reliable,
- it should be quick or cheap to develop,
- it should be provably correct.
How much you prioritise each of these properties should influence your choice of language, and language designers should know which properties they are trying to optimise for. While most languages are functionally equivalent to each other, new langauges are created all the time because they are supposedly better at one or more of these properties than all others.
At this point I think it’s important to note the difference between a
language and an implementation of a language. Many programming
languages have only one standard implementation (a compiler or
interpreter) and the language is often used interchangably with the
implementation in conversation. But the two are very much distinct,
any many of the properties listed above apply more to the
implementation of a language than to the language itself.
Performance, for example, is much more dependent on the
implementation than the language itself. Some languages are designed
to be easy to implement efficiently, others are designed without
considering performance at all. But still, it makes no sense to
compare the performance of languages themselves—
What properties of a solution or the journey towards creating a solution are desirable, and how might a programming langauge help us optimise these properties? Let’s consider the typical stages in the lifecycle of a program:
- design,
- implementation,
- verification
- execution
- maintenance.
The stages can occur sequentially or in a continuous feedback loop, but this is irrelevant for our discussion. The properties that are desirable for a language are essentially those which make these five stages easier, faster, more accurate, more reliable, or perhaps more enjoyable. Again, we should consider which of these stages is most important to us when choosing or designing a programming language.
Most developer use a software development process or methodology, such as test-driven development, literate programming or refinement. At the language level, in order to bring formal structure to the development process, many use one or more programming paradigms, like object-oriented programming or functional programming. And even lower than this, there are countless design principles, patterns and idioms. All of these should be considered when choosing or designing a programming language.