The Computer Tongue
This article is part of a series, access the series index.
Binary is great and all, but how do we get the computer to do what we want? We’ve discussed how binary representations are fed into a processor which takes that input and goes through a series of steps depending on that input to create an output, but how do we actually make that happen? To do so you would choose a programming language, or create your own, dependent on the desired level of control over the machine.
What Is A Programming Language?
Wikipedia.org defines a programming language very well, so I’m just going to quote it here:
“A programming language is an artificial language designed to express computations that can be performed by a machine, particularly a computer.”
A programming language is what you use to tell the computer what you want it to do. It is ‘processed’ by a program known as a compiler or interpreter and turned into something the computer can understand. An example might be:
a = 1
b = 2
c = a + b
This would print 3, as a + b = 1 + 2 = 3. As you can see a programming language is a set of instructions that tell the computer what to do.
The most basic programming language is set by the processor. The specifications of the processor tell us what binary representations will cause the processor to do what. We then use the binary representations and string them together into a series of steps to achieve our end goal. In the early days of computers, this was achieved by inputting the instructions directly into the front panel. This was known as first-generation programming (language).
This type of programming is rarely done at the bit by bit level today and instead is usually deployed using an ‘assembler’. An assembler pieces together assembly language (a programming language) to create the processor specific instructions. As any assembly language is simply a set of mnemonics for the processor instructions with the only added benefit of an assembler it is known as a second-generation programming language.
Just as there is assembly language, there are ‘higher level’ languages. These programming languages were characterized by refinements to the process of programming that were geared towards the programmer rather than the machine. Characteristically a third-generation programming language has the computer take care of certain automated details so that a programmer no longer has to. Examples of such languages are Fortran, and COBOL, but you may recognize their more popular cousins such as C, Java, and Python.
Once you start getting higher than third-generation programming languages you start entering into the reverse trend of further specialization rather than generalization. Don’t take that as a 100% blanket statement, though, as there are exceptions. A fourth-generation programming language is generally oriented towards problem solving and systems engineering. They are designed as mechanisms to reduce programming effort further, usually by being designed with a specific purpose (environment) in mind. They often take a form of specification and then generate the programming necessary to solve the problem. This is an oversimplification, but that’s the general idea.
Similarly, a fifth-generation programming language is based around using constraints given to the program to solve the problem rather than a predefined algorithm supplied by a human programmer. If you think about it this would be an obvious solution for artificial intelligences. It’s much akin to how the computer in Star Trek tends to solve problems automagically. Unfortunately, these programs are very difficult to write and only a small handful exist with limited capabilities.
But what makes up a programming language?
First, programming languages can only be built up from what you can enter into the computer. By that I mean, if the computer’s only form of input were eight switches, the programming language would be built out of what you could do with those eight switches. Luckily for us modern computers today have a mouse and a keyboard, as discussed in a previous article.
A programming language is made up of two parts: a syntax, and semantics.
Syntax defines how input must be formatted. Since most programming languages are made up of what you can enter into the keyboard then syntax becomes a set of rules on how you can arrange pieces of text into an understandable piece of programming (a statement, or expression). The syntax is defined both lexically, and grammatically. We’ll cover the mechanics of these two in a separate article. In short, however, we’ll say that syntax is commonly defined by using “Backaus-Naur Form”. We’ll talk more about this form in another article as well. In the meantime here’s a quick example of such a definition:
integer ::= ['0'-'9']+
identifier ::= ['A'-'Z''a'-'z'].*
string ::= '"' ['A'-'Z''a'-'z''0'-'9']*'"'
argument ::= integer | identifier | string
funcdef ::= 'function' identifier '(' (argument ',')* ');'
Please excuse any errors I may have made as I don’t often write in this form. This form would accept the following line:
function aFunction("green", 123, myVar);
Above you’ll see though a not particularly useful, but illuminating example. An integer can be 1, 14, 555, etc. An identifier can be a letter followed by other letters and numbers, and would form something like a variable. A string is a series of letters and numbers enclosed in double quotes. Any of these three can be an argument, which could then fit into a function definition. Like I said, please excuse any errors (or tell me about them in the comments). This is just a simplified example. Please don’t feel discouraged if you don’t understand the above. In time you will, I just thought it was important to show that construction in the introduction so you could contemplate it ahead of time.
So that would be the syntax. Semantics is part of the programming of the compiler, the program that processes the programming language. Semantics are the various rules by which the input program (or code) must abide by, such as proper variable handling and typing. Semantics define the contexts by which you would write a program, and in turn, give your statements meaning. Are you trying to assign a value to a place in memory from another place in memory, or from a function?
This article was meant only as an introduction to programming languages, and not as an end all of information. Many of the topics in this article will be covered in greater detail in later articles so that you may learn about programming languages in much more detailed fashion and from the ground up. In the meantime, I hope this was somewhat helpful.
If you appreciate my tutorials please help support me through my Patreon.