Programming Computers
Programming is the ability to instruct a machine to perform step by step tasks in such a way that it solves a problem. We put a machine in charge of this because even if the initial problem itself may seem too complex for a machine to solve, the individual steps are not too complex and can be solved by a machine, faster and easier than by a human. This process takes care of the easily predictible and repetitive tasks so that the human can focus on the less easy predictable and more complex tasks. After all, the human understands the whole picture and what those separate steps amount to; the machine does not.
(By Zoran Marincov at Quora)
Variables
A variable is...
Data Types: Atomic and Compound
Data types are the types of data that can be stored in a variable.
Some datatypes are numeric, very much as in mathematics.
- integers: both natural and whole numbers
- floats: decimals, scientific notation, fractions...
- complex: as in mathematics, they have a real and an imaginary part
Most computer languages also have a string or text data type. A string is often enclosed in double quotes, as in "Meet me at eleven." (save in standard SQL, which uses single quotes: 'MY_STRING')
Most computer languages have a Boolean data type too, which can only take on two values: true and false.
Some, but certainly not all, computer languages have a null value to signify that a variable has not been initialized. This is regarded as a high-level feature.
Finally, some computer languages have pointers, that is variables that hold the address of an actual
variable. For instance, int * pInt0; declares variable pInt0 to be a pointer to (the address of) an integer variable. This is considered a low-level feature.
Compound data types
The most common compound data type is the array, a sequence of items which can be address by position.
In Artificial Intelligence a linked list is used instead. To get to the fifth element of a list you need to remove its head five times.
Weakly- and Strongly-Typed Languages*
Early/Historical History Programming Languages
(From Coding From 1849 to 2022: a Guide to The Timeline of Programming Languages, by Severine Hierso, published 06/10/2022)
1957 Fortran
John Backus created FORmula TRANslation or FORTRAN back in 1957. Incredibly, this programming language from the 1950s is still used today in supercomputers and scientific and mathematical computations.
1958 ALGOL and LISP
An algorithmic language created by American and European scientists, ALGOL became the point of origin for world-renowned programming languages such as Pascal, Java, C, and C++.
In the same year, John McCarthy invented the List Processor or LISP. Intended for AI, companies like Boeing and Genworks are still using it.
1959 COBOL
COBOL was developed by a team led by Dr. Grace Murray Hopper; COBOL stands for Common Business Oriented Language. It was designed for credit card transaction processors, traffic signals, and phone calls, and today is used in banking and gaming. Today's virtual PBX system and other modern solutions to communication rest on the shoulders of programming languages like COBOL.
1970 PASCAL
Niklaus Wirth developed PASCAL and named it after Blaise Pascal, the French mathematician. So easy to learn, it was used by Apple early on in its history.
1972 Smalltalk, C, and SQL
Alan Kay, Adele Goldberg, and Dan Ingalls developed Smalltalk at the Xerox Palo Alto Research Centre. It was designed to modify code. Its principles are present in today's Java, Python, and Ruby and are used by companies like CrowdStrike and Logitech.
C was also developed in 1972 by Dennis Ritchie at the Bell Telephone Laboratories. It was designed to be used with the Unix operating system. Based on its forerunner B, languages like C#, Java, JavaScript, Perl, PHP, and Python are all derived from C.
In what could be called a vintage year for coding and programming languages, Raymond Boyce and Donald Chamberlain developed SQL (Structured Query Language) the same year. It was first called SEQUEL, and it was used for viewing and altering information in databases.
These three languages represent a significant leap forward in programming, which has impacted some of the largest tech companies in existence today. Our whole way of using the digital world, from social media to how a business's lead referral program functions, owes a debt to these developments.
1980s ADA
Named after Ada Lovelace, the computing pioneer, ADA was designed by Jean Ichbiah's team at CUU Honeywell Bull. Ada is a high-level programming language, extended from other popular programming languages such as Pascal. ADA is used for air-traffic control in various European countries and space programs.
1983 C++, Objective C
Bjarne Stroustrup modified the C language at Bell Labs. The result was C++, which had some augmentations such as classes and other OOP features, templates, etc. C++ is now used in MS Office, Adobe Photoshop, and various types of high-performance software.
Brad Cox and Tom Love then developed Objective-C, the programming language used for Apple's operating systems.
1987 Perl
Larry Wall developed PERL as a general-purpose, high-level language. He designed it for text editing, but today its primary use is in database applications, data processing, graphic programming, and system administration.
1990 Haskell
Named after the American mathematician Haskell Brooks Curry. Haskell is a primarily mathematical programming language. Used in various industries that need to make complicated calculations, crunch numbers, and keep records.
1991 Python and Visual Basic
The iconic British comedy act Monty Python inspired Python's name. Guido Van Rossum developed this general-purpose, high-level language. Today Python is one of the most popular programming languages worldwide. Giants like Google and Spotify use it.
Visual Basic allows a user to drag and drop sections of code via a user interface (GUI). Parts of Visual Basic are used in applications like Word and Excel.
1993 Ruby
Yukihiro Matsumoto created Ruby as a high-level programming language. Used for web applications development, today it's used by Groupon.
1995 Java, JavaScript, PHP
Created by James Gosling in 1995, Java is one of the world's most famous and popular programming languages. It's a general-purpose, high-level language used in cell phones and parking machines.
JavaScript was created by Brendan Eich. Used for web development, PDF documents, and desktop widgets, it's on almost every major website. Some famous examples are Adobe, Gmail, and Mozilla Firefox.
PHP was known as Personal Home Page
but now stands for Hypertext Preprocessor
. It was developed by Rasmus Lerdorf. It's used for building and maintaining web pages and server-side development. Huge companies like Facebook, Wikipedia, and WordPress use PHP.
Application Programming Interface (API)
An API (Application Programming Interface) is a set of rules and protocols that enable different software applications to communicate and interact with each other. It serves as a bridge between systems, allowing them to exchange data or functionality without needing to understand the details of each other's implementation.
Some well known API's are:
- RESTful
- SOAP (Simple Object Access Protocol) is a protocol for exchanging structured information in the implementation of web services. It uses XML as its message format and relies on application layer protocols like HTTP or SMTP for message negotiation and transmission. SOAP is designed to enable communication between applications running on different operating systems, with different technologies, and written in different programming languages.
Some/Other Programming Languages
Processing
Processing is a free graphics library and integrated development environment (IDE) built for the electronic arts, new media art, and visual design communities with the purpose of teaching non-programmers the fundamentals of computer programming in a visual context.
Processing uses the Java programming language, with additional simplifications such as additional classes and aliased mathematical functions and operations. It also provides a graphical user interface for simplifying the compilation and execution stage.
Latest release: november of 2024. Official site: https://processing.org/
Design Principles: GRASP
GRASP stands for General Responsibility Assignment Software Principles. I think the words that carry the most meaning in this acronym are RA: Responsibility Assignment. This is exactly what we’re talking about.
Design principles, are general guidelines (as opposed to design patterns) to make design robust.
The GRASP principles are 9 principles to assign responsibilities to components in code, and they are presented in Craig Larman’s Applying UML and Patterns book.
They come through experience, in the general sense of the word. It can be one individual’s own trial and errors that makes them realize what options make code more simple. But in the more general sense, design principles stem of our experience as an industry. They are the formalized results of decades of collective experience, as a community of software developers.
The 9 GRASP design principles are:
- Low Coupling
- High Cohesion
- Creator
- Information Expert
- Polymorphism
- Indirection
- Protected Variations
- Pure Fabrication
- Controller
Information Expert
This principle recommends that if you have an operation to do, and this operations needs inputs, then you should consider putting the responsibility of carrying out this operation in the class that contains the inputs for it.
This helps keeping the data local, because if you put the operation somewhere else then the inputs will have to be carried over there, creating a relationship between the class that holds the input data (the information expert
) and that new place. This would create coupling and be detrimental for encapsulation, thus creating complexity.
Granted, it’s a natural thing to do. But formalizing this as a principle still has several benefits. For example, if you feel that a design is not quite right, thinking about the information expert principle can help you pinpoint what was disturbing you in it. Also, it helps expressing your remarks in a code review.
Creator
The Creator Principle gives guidelines as to which class B should be in charge of creating a certain type of objects A. The principle contains a set of conditions to be fulfilled, such as:
- B contains or aggregates instances of A
- B closely uses A
- B has the inputs to construct A
- (and so on)
The more rules are fulfilled, the better B is suited to instantiate objects of type A.
This goes a little further than Information Expert: it’s not just about having the input of the operation of construction, it’s about being close
to the operation.
If you put together two parts of the code that are semantically close (the construction of A, and the code that works a lot with A), then they become easier to reason about than if they were far apart.
Low Coupling
Coupling happens between two parts of the code when one depends on the other. Coupling introduces complexity, if only because the code can then no longer be understood isolation.
Such dependencies can be explicit, in terms of a function call for example, and that’s unavoidable and often OK.
But other types of coupling are less sane and less visible, for example when a part of the code expects that another part has set a data member to a certain value.
The design principle of low coupling encourages to keep coupling low, and it can help in particular to choose between two designs: select the one that introduces the lower amount of coupling.
For more details about the various types of coupling and the various types of problems that coupling generates, refer to this dedicated article on coupling.
Protected Variations
The principle of Protected variations is related to the one of Low Coupling, because it helps to reduce the impacts of the changes of the code of one part A on another part B. The code of part B is protected against the variations of the code of part A, hence the name of the pattern.
How do you achieve such a protection? By organizing the responsibilities around stable interfaces.
This is particularly relevant for code that tends to change often. Introducing an interface between this unstable part of the code and the rest of the codebase helps limiting the rippling effects of those frequent changes.
The principle of protected variations is, according to my understanding, very close to the concept of anti-corruption layer from Domain Driven Design.
Indirection
The Indirection pattern is another way to reduce coupling by creating an intermediary class (or any kind of component) between two classes A and B. This way, the changes in each one of A and B don’t affect the other one. The intermediary class absorbs the impact by adapting its code rather than A or B (or more other classes).
This relates a lot to the Adapter Design Pattern, even though the Adapter design pattern is rather made to connect two existing incompatible interfaces. But it also has the effect of protecting each one against the changes of the other.
Indirection looks a bit like Protected variations, as they both introduce a layer between components in order to reduce coupling.
To my mind, the difference between Protected Variations and Indirection is that Protected Variations is about designing interfaces in the existing components, whereas Indirection is about introducing a new component in the middle.
Polymorphism
The Polymorphism principle is an exhortation to use… polymorphism in your code.
Polymorphism is often seen as having a base class with virtual methods that defines an interface, and derived classes implementing this interface, but this is only one type of polymorphism. There are plenty of types of polymorphism (including templates for example) and I hope we’ll get to dive into this topic at some point on Fluent C++.
The usage for polymorsphism is when there are several ways to accomplish a task, and you want to decouple the clients of this task from the various pieces of code that implement the various ways to perform it.
The Polymorphism principle is very close to the GoF Strategy Pattern, if not identical. It contributes to the Low Coupling principle.
High Cohesion
The principle of High cohesion encourages to focus classes around one responsibility, and to have all its components oriented towards achieving this responsibility. This is the principle of do one thing and do it well
.
The principle of high cohesion also applies to other elements of the code, such as functions, and also modules and systems.
This ties back well with the idea of having a well-organized code: a highly cohesive component lets you label it in your mind with this is the part of the code that does X
. This allows better mental abstractions as well as code abstractions.
Pure Fabrication
It is natural to represent in our code objects that map the reality of the domain that we’re trying to model. For example, if you’re working on a financial application, you can probably expect to encounter some classes called Transaction or Portfolio in the code.
But sometimes you have a responsibility to assign, and it seems to not fit well in any domain class. And according to the principle of High Cohesion above, you shouldn’t force a responsibility into a class that is already doing something else.
That’s when the principle of Pure Fabrication comes into play: create a class that does not map to a domain object, and let it achieve this new responsibility in a cohesive way.
This principle is probably one of the hardest to understand, because it goes against our natural tendency to write code that represents the problem we’re trying to solve.
Controller
Here is an example of a pure fabrication: a UI Controller. This is such a common pattern that it was included in the 9 GRASP principles. Personal opinion: I would have kept this as an example of pure fabrication and not made a principle out of it.
The controller is the first non-UI component that receives the UI event and organizes the operations to react to this event. Indeed, that doesn’t map to any domain object, even if the UI itself can display domain concepts.
There are also other examples of pure fabrications in the GoF design patterns: for example, a Facade object is a pure fabrication.