The initial distinction is between '''low-level languages''' and '''high-level languages'''.
Low-level languages are generally referred to as '''assembly''' languages. Most instructions in such languages equate directly to a single machine instruction. Each machine architecture has its own assembly language, so programs written in such languages are generally very machine-specific and are not portable. The instructions in such languages are usually fairly cryptic, often using abbreviations such as ADD, JNE, LR, LI, etc. In the early days of computing (up to about 1ate 1950's) most programming was done in assembly language, partly due to the limited power and memory capacity of early computers.
High-level languages generally use a mixture of English words and simple mathematical notation, and are often available with little or no change on many different types of computers. These are often referred to as 3rd-generation languages (the 1st generation was raw binary machine code, the 2nd was assembly language). A single high-level statement may be equivalent to using 3 to 10 assembly language statements, so programming in a high-level language can be much more productive. Example statements include:
X = 5 + Y*3
'''if''' result < 3 '''then''' stop
'''print''' "Hello world"
The two main types of high-level languages are '''imperative''' and '''declarative''', with the first type being far more common. Declarative languages define relationships and facts, ask a question, and leave it to the underlying program implementation and its theorem prover to work out how to derive an answer. An example of such a language is Prolog (Programming in Logic). These languages can be effective in areas such as database analysis, symbolic mathematics, and language parsing. When using an imperative language, the programmer is responsible for giving precise instructions as to exactly what has to be done and in what order. Note that some programs may have a random element included so that the results of a program are not necessarily predictable . One of the key reasons for the success of high-level languages is that they provide a level of abstraction (sometimes several such levels). which means that a programmer can concentrate more on the problem to be solved and less on the detail of how to solve it.
Early high-level programming languages were often intended for use in a particular problem domain:
Successful programming languages evolve over time to become more general-purpose, or form the basis for other languages (e.g. '''C''' -> '''C++'''). The evolution often involves incorporating good features from other languages. The general trend is for languages to become more general-purpose and provide more levels of abstraction. The concepts of structured programming were put on a sound theoretical basis in the early 1970's and these have also influenced the evolution of some programming languages (e.g. Fortran 66 -> Fortran 77). The idea of objects (combining data with the applicable operations) was available in Simula in the mid 1960's, but did not become popular until the advent of C++ in the early 1980's and Java in the mid 1990's; confusingly, Java and C++ have a lot of syntax in common, but the meaning (semantics) may differ drastically for what looks the same when written down.
There are a variety of different programming paradigms (styles of writing programs). Some programming languages really only support a single paradigm while others may support several. Declarative programming has already been mentioned above. Other paradigms include: procedural, functional, event-driven, object-oriented, list processing, and automata-based. Languages associated with computers can also be classified as to whether or not they are Turing-complete, i. e. whether or not they are capable of expressing all possible computations ( assuming enough time and memory). Examples of languages which are not Turing-complete include SQL for describing databases and markup languages such as HTML and XML.
==Implementation of programming languages==