Lecture
A computer program is a sequence or set of instructions written in a programming language that a computer is meant to carry out. Computer programs are one component of software, which also includes documentation and other intangible components.
A computer program is a set of instructions and commands written in a programming language and intended to perform a particular task or a series of tasks on a computer. The program defines the sequence of actions the computer must perform in order to process data, interact with the user, or carry out other functions.
Key characteristics of computer programs:
Instructions: A program contains instructions that tell the computer which operations to perform. These instructions may include arithmetic and logical operations, conditional statements, loops, and many other commands.
Programming language: Programs are written in a particular programming language, which may be high-level (for example, Python, Java, C++) or low-level (for example, Assembly).
Compilation or interpretation: Programs may be compiled (converted into machine code ahead of time) or interpreted (executed on the fly by an interpreter).
Purpose: Computer programs can be developed for a variety of purposes, such as data processing, building graphical applications, controlling hardware, creating websites, artificial intelligence, games, and much more.
Platform: Programs can be developed for a specific operating system (for example, Windows, macOS, Linux), or they can be cross-platform, which allows them to run on different systems.
Interface: Many programs have a graphical user interface (GUI) for interacting with users, although text-based and console programs also exist.
Examples of computer programs include operating systems, text editors, browsers, antivirus programs, computer games, image-processing applications, and many others. Programs are a key element of modern computers and enable them to perform a wide variety of tasks.
A computer program in its human-readable form is called source code. Executing source code requires another computer program, because computers can execute only their own machine instructions. Consequently, source code can be translated into machine instructions by a language compiler. (Assembly language programs are translated by an assembler.) The resulting file is called an executable. Alternatively, source code can be executed inside a language interpreter.
If an executable is requested for execution, the operating system loads it into memory and starts a process. The central processing unit will soon switch to this process so that it can fetch, decode, and then execute each machine instruction.
If source code is requested for execution, the operating system loads the corresponding interpreter into memory and starts a process. The interpreter then loads the source code into memory in order to translate and execute each statement. Running source code is slower than running an executable. Moreover, the interpreter must be installed on the computer.

Brian Kernighan's "Hello, World!" program (1978)
The «Hello, World!» program is used to illustrate a language's basic syntax. The syntax of BASIC (1964) was deliberately limited to make the language easier to learn. For example, variables are not declared before use. In addition, variables are automatically initialized to zero.
Once the mechanics of basic computer programming have been learned, more sophisticated and powerful languages become available for building large computer systems.

an example of a computer program written in an IDE
Describing a program can be an important stage of development, documentation, or communication about a software product. There are several ways of describing a program, which may be used in different contexts. Here are some of them:
Technical description: This kind of description focuses on the technical aspects of the program. It may present the following elements:
User interface description: If your program has a graphical user interface (GUI), the interface description may include:
Functional description: This is a description that emphasizes what the program does and which tasks it solves. It may include:
Description of data flows and interactions: For complex programs, especially multitasking and multithreaded applications, a description of data flows and interactions can be important. This includes:
Testing and debugging description: This is a description containing information about test cases, the testing process, and debugging methods. It can be useful for testers and developers.
User documentation: If the program is intended for a broad audience, the description of the program for end users includes:
Comments in the code: Comments in a program's source code can also be considered a form of description. They explain how individual parts of the code work, what a particular function does, and which data is processed.
The choice of an appropriate way to describe a program depends on the goals, the audience, and the context in which the description will be used. A combination of different kinds of descriptions may be the most effective way to present a complete and understandable picture of the program.
Improvements in software development are the result of improvements in computer hardware. At every stage in the history of hardware, the tasks of computer programming changed dramatically.

Lovelace's description from Note G
In 1837, the Jacquard loom inspired Charles Babbage to attempt to build an Analytical Engine. The names of the computing device's components were borrowed from the textile industry. In the textile industry, yarn was brought from the store to be milled. The device had a «store» consisting of memory to hold 1,000 numbers of 50 decimal digits each. Numbers from the «store» were transferred to the «mill» for processing. It was programmed using two sets of punched cards. One set directed the operation, and the other supplied the variables. However, after more than 17,000 pounds of British government money, thousands of cogwheels and mechanisms never fully worked together.
Ada Lovelace worked for Charles Babbage on a description of the Analytical Engine (1843). The description contains Note G, which fully details a method for calculating Bernoulli numbers using the Analytical Engine. This note is recognized by some historians as the world's first computer program. Other historians hold that Babbage himself wrote the first computer program for the Analytical Engine. It lists a sequence of operations for computing the solution of a system of two linear equations.

In 1936, Alan Turing introduced the universal Turing machine — a theoretical device capable of simulating any computation. It is a finite-state machine with an infinitely long read/write tape. The machine can move the tape back and forth, changing its contents as it carries out an algorithm. The machine starts in an initial state, performs a sequence of steps, and halts when it reaches a halting state. All modern computers are Turing complete.

Glenn A. Beck changing a tube in ENIAC
The Electronic Numerical Integrator and Computer (ENIAC) was built between July 1943 and the autumn of 1945. It was a Turing-complete, general-purpose computer that used 17,468 vacuum tubes to build its circuits. At its core it was a series of Pascalines wired together. Its 40 units weighed 30 tons, occupied 1,800 square feet (167 m2), and consumed $650 per hour (in 1940s currency) of electricity while idle. It had 20 base-10 accumulators. Programming ENIAC took up to two months. Three function tables were on wheels and had to be rolled to fixed function panels. The function tables were connected to the function panels by plugging heavy black cables into plugboards. Each function table had 728 rotating knobs. Programming ENIAC also involved setting some of its 3,000 switches. Debugging a program took a week. From 1947 to 1955 it operated at the Aberdeen Proving Ground, calculating hydrogen bomb parameters, predicting weather patterns, and producing firing tables for aiming artillery guns.
Instead of plugging cords and flipping switches, a stored-program computer loads its instructions into memory in exactly the same way that it loads its data into memory. As a result, a computer could be programmed quickly and could perform calculations at very high speed. Presper Eckert and John Mauchly built ENIAC. The two engineers introduced the stored-program concept in a three-page memo dated February 1944. Later, in September 1944, Dr. John von Neumann began working on the ENIAC project. On June 30, 1945, von Neumann published the First Draft of a Report on the EDVAC, which equated the structures of the computer with the structures of the human brain. [22] The design became known as the von Neumann architecture. The architecture was used simultaneously in the designs of the EDVAC and EDSAC computers in 1949.
The IBM System/360 (1964) was a family of computers, each having the same instruction set architecture. The Model 20 was the smallest and cheapest. Customers could upgrade and keep the same application software. The Model 195 was the most premium. Every System/360 model featured multiprogramming — having several processes in memory at once. When one process was waiting for input/output, another could compute.
IBM planned for each model to be programmed using PL/1. A committee was formed that included COBOL, Fortran, and ALGOL programmers. The goal was to design a comprehensive, easy-to-use, extensible language that would replace Cobol and Fortran. The result was a large and complex language that took a long time to compile.

Manual input switches on a Data General Nova 3, manufactured in the mid-1970s.
Computers manufactured before the 1970s had front-panel switches for manual programming. The computer program was written on paper for reference. An instruction was a configuration of on/off settings. After setting the configuration, an execute button was pressed. This process was then repeated. Computer programs were also entered automatically via paper tape, punched cards, or magnetic tape. After the medium was loaded, the starting address was set with switches and the execute button was pressed.

A VLSI integrated circuit die
An important milestone in software development was the invention of the very-large-scale integration (VLSI) circuit (1964). After the Second World War, vacuum tube technology was replaced by point-contact transistors (1947) and bipolar junction transistors (late 1950s) mounted on a printed circuit board. In the 1960s, the aerospace industry replaced the printed circuit board with the integrated circuit.
Robert Noyce, co-founder of Fairchild Semiconductor (1957) and Intel (1968), achieved a technological improvement that refined the production of field-effect transistors (1963). The goal is to alter the electrical resistivity and conductivity of a semiconductor junction. First, natural silicate minerals are converted into polysilicon rods using the Siemens process. [31] The Czochralski process then turns the rods into a monocrystalline silicon boule crystal. The crystal is then sliced thin to form a wafer substrate. A planar photolithography process then combines unipolar transistors, capacitors, diodes, and resistors on the wafer to build a matrix of metal-oxide-semiconductor (MOS) transistors. The MOS transistor is the primary component of integrated circuits.
Initially, the functions of integrated circuit chips were fixed during manufacture. In the 1960s, control of the electrical flow moved to programming a matrix of read-only memory (ROM). The matrix resembled a two-dimensional array of fuses. The process of embedding instructions in the matrix consisted of burning away the unneeded connections. There were so many connections that firmware programmers wrote a computer program on another chip to control the burning. The technology became known as Programmable ROM. In 1971, Intel installed the computer program onto the chip and named it the Intel 4004 microprocessor.

The IBM System/360 (1964) processor was not a microprocessor.
The terms «microprocessor» and «central processing unit» (CPU) are now used interchangeably. However, processors predate microprocessors. For example, the IBM System/360 (1964) processor was made from circuit boards containing discrete components on ceramic substrates.

An artist's rendering of the Sacramento State University Intel 8008 microcomputer (1972)
The Intel 4004 (1971) was a 4-bit microprocessor designed to run the Busicom calculator. Five months after its release, Intel launched the Intel 8008, an 8-bit microprocessor. Bill Pentz led a team at Sacramento State to build the first Intel 8008-based microcomputer: the Sac State 8008 (1972). [37] Its purpose was to store patient medical records. The computer supported a disk operating system to work with a 3-megabyte Memorex hard disk. [29] It had a color display and a keyboard combined into a single console. The disk operating system was programmed using IBM Basic Assembly Language (BAL). The medical records application was programmed using a BASIC interpreter. However, the computer turned out to be an evolutionary dead end because it was extremely expensive. In addition, it was built in a state university lab for a specific purpose. Nevertheless, the project contributed to the development of the Intel 8080 instruction set (1974).

The first IBM personal computer (1981) used the Intel 8088 microprocessor.
In 1978, the modern software development environment began when Intel upgraded the Intel 8080 to the Intel 8086. Intel simplified the Intel 8086 to produce the cheaper Intel 8088. [38] IBM adopted the Intel 8088 when it entered the personal computer market (1981). As consumer demand for personal computers grew, so did Intel's microprocessor development. The sequence of development is known as the x86 series. The x86 assembly language is a family of backward-compatible machine instructions. Machine instructions created in earlier microprocessors were retained as microprocessors were upgraded. This allowed consumers to buy new computers without having to buy new application software. The main instruction categories are:

The DEC VT100 (1978) was a widely used computer terminal.
VLSI circuits allowed the programming environment to move from the computer terminal (until the 1990s) to a computer with a graphical user interface (GUI). Computer terminals limited programmers to a single shell running in a command-line environment. In the 1970s, full-screen source code editing became possible through a text-based user interface. Whatever technology is available, the goal is to program in a programming language.
The features of a programming language exist to provide building blocks that can be combined to express programming ideals. Ideally, a programming language should:
The programming style of a programming language that provides these building blocks can be classified into programming paradigms. For example, different paradigms may differ in:
Each of these programming styles has contributed to the synthesis of the various programming languages.
A programming language is a set of keywords, symbols, identifiers, and rules by which programmers can communicate instructions to the computer. They follow a set of rules called syntax.
Programming languages take their foundation from formal languages. The purpose of defining a solution in a formal language is to produce an algorithm that solves the underlying problem. An algorithm is a sequence of simple instructions that solve a problem.
The evolution of programming languages began when EDSAC (1949) used the first stored computer program in its von Neumann architecture. EDSAC was programmed in a first-generation programming language.
A key characteristic of an assembly language program is that it forms a one-to-one mapping with its corresponding machine language target.

A computer program written in an imperative language.
Imperative languages specify a sequential algorithm using declarations, expressions, and statements:
var x: integer;2 + 2x := 2 + 2; if x = 4 then do_something();FORTRAN (1958) was introduced as «IBM Mathematical FORmula TRANslating System». It was designed for scientific calculations, without facilities for handling strings. Along with declarations, expressions, and statements, it supported:
It succeeded because:
However, non-IBM vendors also wrote Fortran compilers, but with a syntax that was likely to fail on the IBM compiler. The American National Standards Institute (ANSI) developed the first Fortran standard in 1966. In 1978, Fortran 77 became the standard until 1991. Fortran 90 supports:
COBOL (1959) stands for «COmmon Business Oriented Language». Fortran manipulated symbols. It was soon realized that symbols did not have to be numbers, so strings were introduced. [55] The United States Department of Defense influenced COBOL's development, with Grace Hopper being a major contributor. Statements were English-like and verbose. The goal was to design a language in which managers could read programs. However, the lack of structured statements prevented this goal from being achieved.
COBOL's development was tightly controlled, so no dialects arose that would require ANSI standards. As a consequence, it did not change for 15 years, until 1974. The 1990s version did introduce substantial changes, such as object-oriented programming.
ALGOL (1960) stands for «ALGOrithmic Language». It had a profound influence on programming language design. Designed by a committee of European and American programming language experts, it used standard mathematical notation and had a readable, structured design. Algol was the first to define its syntax using Backus-Naur form. This led to syntax-directed compilers. It added features such as:
Direct descendants of Algol include Pascal, Modula-2, Ada, Delphi, and Oberon on one branch. On another branch, the descendants include C, C++, and Java.
BASIC (1964) stands for «Beginner's All-Purpose Symbolic Instruction Code». It was developed at Dartmouth College to teach all of its students. If a student did not move on to a more powerful language, they would still remember Basic. A Basic interpreter was installed in the microcomputers released in the late 1970s. As the microcomputer industry grew, so did the language.
Basic pioneered the interactive session. It offered operating system commands within its environment:
However, Basic's syntax was too simple for large programs. Recent dialects added structure and object-oriented extensions. Microsoft Visual Basic is still widely used and provides a graphical user interface.
The C programming language (1973) got its name because the language BCPL was replaced by B, and AT&T Bell Labs named the next version «C». Its purpose was to write the UNIX operating system. [50] C is a relatively small language, which makes compilers easy to write. Its growth mirrored the growth of hardware in the 1980s. Its growth is also due to the fact that it has the capabilities of assembly language but uses a high-level syntax. It added advanced features such as:

A computer's memory map
C allows the programmer to control which region of memory data should be stored in. Storing global variables and static variables requires the fewest clock cycles. The stack is used automatically for standard variable declarations. Heap memory is returned into a pointer variable from the function. malloc()
main() function. Global variables are visible to main()and to all other functions in the source code.On the other hand, variable declarations inside main(), other functions, or inside { } block delimiters are local variables. Local variables also include formal parameter variables. Parameter variables are enclosed in the parentheses of function definitions. They provide the interface to the function.
staticprefix are also stored in the global and static data region. Unlike global variables, static variables are visible only inside the function or block. Static variables always retain their value. An example of their use would be the function int increment_counter(){static int counter = 0; counter++; return counter;} staticprefix, including formal parameter variables, are called automatic variables and are stored on the stack. They are visible inside the function or block and lose their scope when the function or block is exited.malloc()library function for allocating dynamic memory. Filling the heap with data is an additional copy operation. Variables stored on the heap are passed economically to functions using pointers. Without pointers, the entire block of data would have to be passed to the function via the stack.In the 1970s, software engineers needed language support to break large projects down into modules. One obvious feature was the physical decomposition of large projects into separate files. A less obvious feature was the logical decomposition of large projects into abstract data types. At the time, languages supported concrete (scalar) data types such as integers, floating-point numbers, and character strings. Abstract data types are structures of concrete data types given a new name. For example, a list of integers could be called integer_list.
In object-oriented jargon, abstract data types are called classes. However, a class is only a definition; no memory is allocated. When memory is allocated to a class and bound to an identifier, it is called an object.
Object-oriented imperative languages developed by combining the need for classes and the need for safe functional programming. In an object-oriented language, a function is assigned to a class. The assigned function is then called a method, a member function, or an operation. Object-oriented programming is performing operations on objects.
Object-oriented languages support syntax for modeling subset/superset relationships. In set theory, an element of a subset inherits all the attributes contained in the superset. For example, a student is a person. Therefore the set of students is a subset of the set of people. As a result, students inherit all the traits common to all people. In addition, students have unique traits that other people do not have. Object-oriented languages model subset/superset relationships using inheritance. Object-oriented programming became the dominant language paradigm by the end of the 1990s.
C++ (1985) was originally called «C with Classes». It was designed to extend C's capabilities by adding the object-oriented facilities of the language Simula.
Imperative languages face one serious criticism: assigning an expression to a non-local variable may produce an unintended side effect. Declarative languages generally omit the assignment statement and control flow. They describe what computation should be performed, not how to compute it. The two broad categories of declarative languages are functional languages and logic languages.
The principle of a functional language is to use lambda calculus as a guide to well-defined semantics. In mathematics, a function is a rule that maps elements of an expression to a range of values. Consider the function:
times_10(x) = 10 * x
The expression is mapped by the function to a range of values. One of the values is 20. This happens when x is 2. Thus the application of the function is written mathematically as: 10 * xtimes_10()
times_10(2) = 20
A functional language compiler will not store this value in a variable. Instead, it pushes the value onto the computer's stack before returning the program counter to the calling function. The calling function then pops the value off the stack.
Imperative languages support functions. Consequently, functional programming can be achieved in an imperative language if the programmer maintains discipline. However, a functional language imposes this discipline on the programmer through its syntax. Functional languages have syntax specifically designed to emphasize the what.
A functional program is developed with a set of primitive functions followed by a single driver function. Consider the snippet:
function max(a,b){/* code omitted */}
function min(a,b){/* code omitted */}
function difference_between_largest_and_smallest(a,b,c) {
return max(a,max(b,c)) - min(a, min(b,c));
}
The primitives are max()and min(). The driver function is difference_between_largest_and_smallest().
Executing:
put(difference_between_largest_and_smallest(10,4,7));
will output 6.
Functional languages are used in computer science research to explore new language features. Moreover, the absence of side effects has made them popular in parallel and concurrent programming. However, application developers prefer the object-oriented features of imperative languages.
Lisp (1958) stands for «LISt Processor». It is designed for list processing. A complete data structure is formed by building lists. A tree data structure is built in memory. Internally, the tree structure is a fine fit for recursive functions. [80] The syntax for building a tree consists of enclosing space-separated elements in parentheses. The following is a list of three elements. The first two elements are themselves two-element lists:
((A B) (HELLO WORLD) 94)
Lisp has functions for extracting and reconstructing elements. The function head()returns a list containing the first element of a list. The function tail()returns a list containing everything except the first element. The function cons()returns a list that is the union of other lists. Consequently, the following expression will return the list x:
cons(head(x), tail(x))
One drawback of Lisp is that when many functions are nested, the parentheses can become confusing. Modern Lisp environments help ensure that parentheses match. In addition, Lisp supports the imperative language operations of the assignment statement and goto loops. Furthermore, Lisp is not concerned with the data types of elements at compile time. Instead, it assigns (and may reassign) data types at run time. Assigning a data type at run time is called dynamic binding. [84]Although dynamic binding increases the language's flexibility, programming errors may persist until late in the software development process.
Writing large, reliable, and readable programs in Lisp requires forethought. With proper planning, a program may turn out to be much shorter than an equivalent imperative language program. Lisp is widely used in the field of artificial intelligence. However, its use was accepted only because it contains imperative language operations, which make unintended side effects possible.
Prolog (1972) stands for «PROgramming in LOGic». It is a logic programming language based on formal logic. The language was developed by Alain Colmerauer and Philippe Roussel in Marseille, France. It is an implementation of the selective linear definite clause method, first proposed by Robert Kowalski and others at the University of Edinburgh.
The building blocks of a Prolog program are facts and rules. Here is a simple example:
A practical application of Prolog is knowledge representation and problem solving in the field of artificial intelligence.
Object-oriented programming is a programming method for performing operations (functions) on objects. The basic idea is to group the characteristics of a phenomenon into an object container and to give the container a name. The operations on the phenomenon are also grouped into the container. Object-oriented programming developed by combining the need for containers and the need for safe functional programming. This programming method is not necessarily limited to an object-oriented language. In an object-oriented language, the object container is called a class. In a non-object-oriented language, a data structure (also known as a record) can become the object container. To turn a data structure into an object container, operations must be written specifically for that structure. The resulting structure is called an abstract data type. However, inheritance will be missing. Nevertheless, this shortcoming can be overcome.
The formal strategy for building object-oriented objects is as follows:
For example:
The syntax of a programming language is a list of production rules that govern its form. The form of a programming language is the correct placement of its declarations, expressions, and statements. A language's syntax is complemented by its semantics. Semantics describes the meanings attributed to the various syntactic constructs. A syntactic construct may need a semantic description because the form may be open to an incorrect interpretation. Moreover, different languages may have the same syntax; however, their behavior may differ.
A language's syntax is formally described by listing production rules. Although the syntax of natural language is extremely complex, a subset of English might have the following list of production rules:
The words shown in bold are known as «non-terminals». The words in single quotes are known as «terminals».
From this list of production rules, complete sentences can be formed through a series of substitutions. The process consists of replacing non-terminals with either a valid non-terminal or a valid terminal. The substitution process is repeated until only terminals remain. One valid sentence is:
However, another combination results in an invalid sentence:
Consequently, semantics is needed to correctly describe the meaning of the eating action.
One method of listing production rules is called Backus–Naur form (BNF). BNF describes the syntax of a language and itself has a syntax. This recursive definition is an example of a metalanguage. BNF syntax includes:
::=which translates as consists of [a], when a non-terminal is to its right. It translates as «is» when a terminal is to its right.|which translates as or.<and >which surround non-terminals.Using BNF, a subset of English might have the following list of production rules:
< sentence > ::= < noun-phrase >< verb-phrase >
< noun-phrase > ::= < article >< adjective >< noun >
< verb-phrase > ::= < verb >< noun-phrase >
< article > :: = the < adjective
> ::= big | small
< noun > ::= cat | mouse
< verb > ::= eats
Using BNF, a signed integer has the list of production rules:
< signed-integer > ::= < sign >< integer >
< sign > ::= + | -
< integer > ::= < digit > | < digit >< integer >
< digit > ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Note the recursive production rule:
< integer > ::= < digit > | < digit >< integer >
This opens up an infinite number of possibilities. Consequently, semantics is needed to describe a limit on the number of digits.
Note the possibility of a leading zero in the production rules:
< integer > ::= < digit > | < digit >< integer >
< digit > ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Consequently, semantics is needed to describe that leading zeros should be ignored.
Two formal methods are available for describing semantics. These are denotational semantics and axiomatic semantics

Before programming languages existed, Betty Jennings and Fran Bilas programmed ENIAC by moving cables and setting switches.
Software engineering comprises the various methods for producing quality software. Computer programming is the process of writing or editing source code. In a formal setting, a systems analyst gathers information from managers about all of the organization's processes that need to be automated. This specialist then prepares a detailed plan for the new or modified system. The plan is analogous to an architect's blueprint
The systems analyst's goal is to deliver the right information to the right person at the right time. The decisive factors in achieving this goal are:
Achieving the target metrics must be balanced against all costs, including:
Applying a systems development process will mitigate the axiom: the later in the process an error is discovered, the more expensive it is to fix.
The waterfall model is one implementation of the systems development process. As the waterfall designation suggests, the main phases overlap one another:
A programmer is the specialist responsible for writing or modifying source code to implement the detailed plan. A team of programmers will likely be needed, since most systems are too large for a single programmer to handle. However, adding programmers to a project cannot shorten the completion time. Instead, it may reduce the system's quality. To be effective, software modules must be defined and distributed among the team members. In addition, team members must communicate with each other meaningfully and efficiently.
Computer programmers may program in the small: programming within a single module. The module will most likely call modules located in other source code files. Consequently, programmers may program large software modules so that they fit together effectively. Programming in the large involves participating in the design of an application programming interface (API).
Modular programming is a method for refining programs in an imperative language. Refined programs can reduce the size of the software, separate responsibilities, and thereby mitigate software aging. A software module is a sequence of statements bounded within a block and collectively identified by a name. Modules have a function, a context, and logic:
A module's name should be determined first by its function, and then by its context. Its logic should not be part of the name. For example, function compute_square_root( x )or function compute_square_root_integer( i : integer )are appropriate module names. However, function compute_square_root_by_division( x )is not.
The degree of interaction within a module is its level of cohesion. Cohesion is a judgment of the relationship between a module's name and its function. The degree of interaction between modules is the level of coupling. Coupling is a judgment of the relationship between a module's context and the elements on which
продолжение следует...
Часть 1 The Computer Program: Its Characteristics and Ways to Describe It
Часть 2 Functional categories - The Computer Program: Its Characteristics and Ways
Comments