Hello to all. I publish excerpts from the introductory course of our
company on industrial programming. If the excerpts seem interesting to the habocommunity, I will continue to publish
other pieces.
This course is designed primarily for junior developers and allows you to increase the level of argumentation in holivarah on the topic "why PHP (Java, Perl, Bash) sucks."
This course deals with a streaming programming model based on a Turing computer, the history of the emergence of modern PL, as well as the area of their applicability. As well as clearly and clearly explains what OOP and functional programming.
')
Part One: How Languages Appeared and Why
Part Two: The principle of maintaining functionalityPart Three: Syntactic Sugar or the History of the Development of LanguagesHow did languages appear and why
A language is needed to process data and present the result of processing in one form or another.
A computer always has a data source and a data sink. By and large, the computer simply pours information from several sources into several sinks, making transformations along the way.
A programming language is a language by which we set the rules for converting information into a form that is convenient for us or for a computer and nothing more. In fact, all programming languages can be reduced to operation on a Turing machine.
Turing Machine
The Turing machine is an endless magnetic tape (remember the year when Turing was working - the magnetic tape was then a very progressive device). The tape is divided into logical cells - consecutive sections of tape, on which one or another signal can be recorded (for example, ASCII characters).
The machine can move the tape left or right by one cell, read the current segment, or write something in the current segment. Each operation starts with the machine reading the value of the current cell, checking what this value means using the jump table and performing two actions: writing a new character to the same cell and shifting one cell to the left or shifting the cell to the right.
After performing these two actions, the cycle repeats, no data is transferred between cycles. In each specific cycle, the machine processes only the symbol that it counts from the current cell. Once again - the symbol from the cell, which she counted last time, the machine does not remember.
The program on the Turing machine is defined as a table of transitions: if the character is A, then left shift, if B is right shift, if C is written in cell D and move left, if E, then stop work (and so on until the characters run out ).
One of the main definitions set by the Turing machine is the execution context:
The execution context of a program is the collection of all data defining its behavior.
Paradigms for setting rules
As can be seen from the example of the Turing machine, the YP is manipulated not by data, but by data conversions. But the rules for processing somehow need to be presented and defined. At the moment, found two ways to specify the rules for processing - this is an imperative and declarative form of writing rules.
Declarative form
The first form is called declarative. A good example of this type of description of transformations is algebraic notation: a belongs to the segment [b, c] (postulate this fact), d belongs to the line (a, b) if the condition d = f (a, b) is satisfied (also postulate this fact) .
Well-known declarative modules for you are the rules for describing HTML and CSS pages. In the latter, for example, it may be postulated that if an element is included in a particular class, then it is necessary to paint it in red.
Declarative PL describes not the steps to be taken to get a result, but what is required to be obtained as a result.Declarative PLs pay special attention to the input data and the final result of the program. The data conversion process receives less attention.
Mandatory form
The second form of the rules is called imperative. The theoretical model for imperative programming was the Turing machine.
Imperative form: this is a list of orders expressed in the imperative. For example, assign a to the value (cb) / 2. Or if a is equal to b, then proceed to the execution of the following commands otherwise - other commands. Attention in the imperative form is given not to the data itself, but to the process of processing this data.
The imperative language is focused on the description of the process of changing information, and not on the result of the conversion.The execution of the program is reduced to the sequential execution of operators in order to convert the source data into results.
Interestingly, the rules for imperative languages are set in a declarative form: here, they say, we have such rules for transitions and information processing.
Information Processing Paradigms
In addition to the method of specifying the rules of PL, they also differ in their approach to the processed data. If you look closely at the information that PL transforms, you can see that it is of two types: discrete and continuous.
Discrete Event Model
A classic example of a discrete representation of information is the same Turing machine. All information, both supplied to it and the result of processing, is divided into equal parts.
Another example of a discrete representation is the processing of an incoming stream of digital audio data. To read such a stream, a periodically filled array of numbers is used — the data buffer, which is then processed and transformed.
It is easy to see that in the case of a discrete presentation of information, the cyclical nature of the program is set by the input method itself: read a byte - did the processing - spat out the result.
But what happens if the pieces of information are not equal in size? For example, a long text is sent to the input of the program, but the program should operate not with letters-symbols, but with words?
To solve such problems, the concept of an event is introduced. The event occurs in response to any recognized sequence read from the data source.
If we look at an example with text and words, then we read the data byte by byte and write it in a replenishable memory buffer. And we do this as long as we do not read a space or a dot in the data stream, which will mean the occurrence of the “end of word” event.
After the occurrence of the “end of word” event, we can be sure that we have the whole word in the buffer. Now we can analyze it, understand what it means, apply the specified processing rules, prepare a new buffer for reading the next word, etc.
In the discrete-event approach of information processing, the functioning of the system is represented as a chronological sequence of events. The event occurs at a certain point in time and changes the state of the system.The onset of an event means for the program one very important action: the program changes its own state (execution context). After the occurrence of an event, the program can work based on this knowledge that this event has occurred. For example, if we have found the word “abyrvalg”, now we can use the knowledge that it exists further when performing the work.
Continuous Data Model
The approach to programming - “events happen and we must respond to this” is ubiquitous and seems now something natural, but this is not at all the case. Many things are more natural to describe in continuous data.
For example, the classical school task of filling a pool with water at specified intervals (a pool into which one pipe pours water and another diverts) is much easier solved with the help of algebraic declarative languages, as the difference between the solutions of the water supply and drain functions.
Also, when using continuous data, it is much easier to solve problems related to vector graphics. For example, to draw a circle on the screen using discrete data processing, it is necessary to operate on the pixels and calculate the position of each pixel that satisfies the condition of the circle. The circle is then represented as an array of pixels. In the case of the use of a programming language that works with vector data, it is sufficient to indicate the function of the circle and the parameters for it.
Operating with continuous data, we lose the concept of an event.Where we need events and the order of operations on the pieces of data, it is most convenient to apply a discrete event approach to processing. These are tasks of reacting to events from the user, interpreting and isolating events from the incoming data stream, sequentially transforming pieces of information.
In the same place where we need the picture “as a whole”, the approach of analytic languages is most convenient: it is the acquisition of data slices, the description of data structures, the solution of mathematical functions, the description of graphics, the continuous transformations of one incoming stream into another.