Skip to content

Foundations of Programming

In this section, we explore what coding actually means, why it has become such a valuable skill in today's world, and the essential building blocks that underlie virtually every modern programming language. We'll look at concepts such as variables, data types, control flow, functions, and how instructions are structured and interpreted by a computer. Grasping these fundamentals is essential, since they form the conceptual groundwork you'll need to make sense of Python specifically, as well as to understand, more broadly, how any computer program is written, translated, and ultimately executed by a machine.

Programming Language

A programming language is a formal system made up of a defined syntax, vocabulary, and set of rules that allows a programmer to express instructions in a way a computer can eventually carry out. These instructions, written by a person, are known as source code, and they must go through a translation process (via a compiler or interpreter) before the computer can actually execute them as a sequence of operations. There are hundreds of programming languages in use today, each with its own strengths, syntax rules, and typical use cases. Python is one widely used example, known for its readable syntax and broad applicability across fields such as web development, data science, automation, and more.

Interpreted vs Compiled Languages

A comparison of how interpreted and compiled programming languages translate and execute source code.

Aspect Interpreted Compiled
Execution process Executed directly by an interpreter, which works through the source code line by line (or statement by statement) Translated in its entirety into machine code by a compiler, before the program is ever run
Timing of translation Translation happens on the fly, at the moment of execution Translation happens upfront, as a separate step completed before execution
Output produced No standalone executable is produced; the source code is required each time the program runs Produces a standalone executable file that the operating system can launch directly
Runtime requirements Requires the interpreter to be present to run the program Does not require the original source code or any translation tool at runtime
Speed Tends to be slower, since translation happens during execution Tends to be faster, since all translation work is completed in advance
Flexibility / development Offers greater flexibility and easier testing during development, since code can be run and tested immediately Less immediately flexible, since a full compilation step is needed before testing changes
Example languages Python (primarily) C, C++
Notable exception / nuance Some Python implementations blend both approaches, compiling to intermediate bytecode which is then interpreted, balancing flexibility with performance Some languages likewise blur the line, showing that the interpreted/compiled distinction isn't always perfectly clean

High-Level vs Low-Level Languages

A comparison of how high-level and low-level programming languages relate to the underlying hardware.

Aspect High-Level Language Low-Level Language
Relationship to hardware Abstracts away low-level machinery such as memory addresses, register allocation, and hardware-specific instructions Sits much closer to the hardware, requiring direct or near-direct management of these details
Readability Code closely resembles human logic and natural language, making it considerably easier to read Code closely mirrors machine operations, making it harder to read and interpret
Ease of writing / debugging / maintaining Easier to write, debug, and maintain over time due to the abstraction from hardware details More difficult to write, debug, and maintain, since hardware-level details must be handled manually
Programmer focus Frees programmers to focus on solving problems, designing algorithms, structuring data, and building functionality Requires programmers to focus on hardware operation, manual memory management, and hardware-specific instructions
Level of control Less direct control over hardware, since these details are handled automatically Far more manual control over hardware, since little is abstracted away
Example languages Python, Java, JavaScript Assembly

General-Purpose vs Domain-Specific Languages

A comparison of general-purpose and domain-specific programming languages.

Aspect General-Purpose Language Domain-Specific Language
Scope of design Built to tackle a wide variety of computational problems Designed with a particular task or domain in mind
Versatility Highly versatile, adaptable across many different fields and problem types Narrowly focused, optimised for a specific purpose rather than broad use
Areas of use Software development, automation and scripting, web development, data science and analytics, finance and quantitative modeling, artificial intelligence and machine learning, and scientific computing, among many other fields A single targeted area, such as querying databases or structuring web pages
Example languages Python SQL (querying databases), HTML (structuring web pages)
Reason for widespread adoption Broad applicability, combined with readable syntax and an extensive ecosystem of libraries Deep suitability and efficiency for its one specific task, rather than broad adoption across fields

Dynamically Typed vs Statically Typed

Aspect Dynamically Typed Statically Typed
When type is determined Automatically, at the moment a value is assigned Explicitly, declared in advance by the programmer
Type flexibility A variable's type can change over its lifetime (e.g. x = 5 then x = "hello") A variable's type is fixed once declared and cannot change afterward
Speed of writing code Faster to write, since no type declarations are needed upfront Slower to write initially, since types must be declared explicitly
Error detection Type-related errors may only surface when the program is run Type-related errors are often caught earlier, during compilation
Example languages Python Java, C

Multi-Paradigm vs Single-Paradigm

Aspect Multi-Paradigm Single-Paradigm
Programming styles supported Supports several styles, such as procedural, object-oriented, and functional, and allows them to be mixed within the same project Restricts programmers to one particular way of structuring and organising code
Flexibility Highly flexible; a project can begin with one style and adopt others as it grows Less flexible; the codebase is generally organised around a single consistent approach throughout
Learning path Beginners can start simple (procedural) and gradually adopt more advanced styles (object-oriented, functional) without switching languages Learners are guided toward one specific way of thinking about program structure
Example Python Languages designed around a single paradigm (e.g. purely functional or purely object-oriented languages)

Procedural vs Object-Oriented vs Functional

Aspect Procedural Object-Oriented Functional
Core organising unit Step-by-step instructions and reusable functions Objects and classes that bundle data and behaviour together Functions treated like mathematical functions
Best suited for Simple, linear tasks and straightforward scripts Modelling more complex, real-world systems Computations favouring predictability and simplicity
Data handling Data and functions are typically kept separate Data (attributes) and behaviour (methods) are combined within objects Favours immutable data, which doesn't change once created
Side effects Can have side effects, since functions may alter shared data Can have side effects, since object state can be modified Favours functions with no side effects, relying instead on inputs and outputs
Typical use case in Python Writing a simple script to process a file line by line Building a class to represent a bank account with balance and transaction methods Using functions like map() or filter() to transform data without altering the original