A programming language is a formal language used to express computations, including algorithms, operations on data, and interactions with a computer. It provides rules for constructing programs and interpreting their meaning. Programming languages also communicate computational ideas between people: their notation allows programmers to describe procedures, organize abstractions, and reason about behavior independently of a particular execution. Their study is a branch of computer science. (cs.princeton.edu)
Syntax and semantics
A language’s syntax specifies how valid expressions and statements are formed. Its lexical rules identify elements such as names, keywords, numeric literals, and operators; grammatical rules determine how these elements combine. For example, a language may require parentheses around function arguments or indentation to delimit blocks. A parser analyzes this structure, often producing a tree representation for subsequent processing. (docs.python.org)
Semantics specifies what those structures mean. This includes how expressions produce values, how statements change program state, and how function calls and errors behave. Operational semantics describes execution through computational steps; denotational semantics assigns mathematical meanings to programs; axiomatic semantics describes properties that can be established about their execution. Consequently, syntactically valid code is not necessarily meaningful or correct: it may violate type rules or compute an unintended result. (cs.princeton.edu)
A language definition and a language implementation are distinct. The definition establishes permitted structure and behavior, while an implementation supplies software or hardware that realizes them. Language specifications may leave some details implementation-dependent, including aspects of program representation, optimization, and diagnostic messages. (haskell.org)
Abstraction and historical development
Early electronic computers were programmed using machine code, whose instructions correspond closely to a machine’s architecture. Assembly language introduced symbolic notation for instructions and addresses. Higher-level languages subsequently allowed programmers to express operations without specifying every underlying machine instruction. This separation made source programs easier to transfer between machines with suitable implementations. (ibm.com)
Fortran, commercially released by IBM in 1957, was an important early high-level language for scientific and numerical computation. Its compiler translated mathematical notation into executable instructions, demonstrating that higher-level programming could produce efficient machine code. Lisp, whose implementation began in autumn 1958, developed a different approach centered on symbolic expressions, list structures, function composition, and recursion. These developments established contrasting traditions in language design. (ibm.com)
Abstraction also operates within programs. Functions, modules, classes, and user-defined types allow complex behavior to be assembled from components with defined interfaces. These mechanisms support information hiding and reuse, important concerns in software engineering. (cs.princeton.edu)
Programming paradigms
A programming paradigm is a characteristic approach to structuring computations. These categories overlap rather than forming an exclusive classification of languages. (cs.princeton.edu)
- Imperative programming describes commands that change state. Assignments, conditional branches, and loops specify how computation proceeds. Procedural programming organizes such commands into reusable procedures.
- Functional programming emphasizes evaluating expressions and composing functions. Functions may themselves be passed as arguments or returned as results. Purely functional languages, such as Haskell, distinguish ordinary value computation from effects such as input and output.
- Object-oriented programming organizes software around objects that combine state with associated operations. Classes and related mechanisms define interfaces and relationships among objects.
- Declarative programming emphasizes describing required relationships or results rather than prescribing every execution step. Logic programming expresses facts and rules, with a language implementation supplying the search process. (cs.princeton.edu)
Languages may be general-purpose or specialized for particular tasks. SQL, for example, provides constructs for defining, modifying, and querying a database. Specialization concerns a language’s intended domain, whereas a paradigm concerns its organization of computation. (postgresql.org)
Types and memory management
A type system classifies values and constrains the operations applicable to them. Types may describe numbers, text, functions, or structured collections. Static typing checks relevant constraints before execution; dynamic typing performs relevant checks during execution. Haskell exemplifies static typing with type inference, while Python uses dynamic typing. Inference means that a programmer need not explicitly write every type annotation; it does not make a language dynamically typed. (haskell.org)
Type checking can reject certain invalid combinations, but it does not establish that a program satisfies its intended purpose. A well-typed computation may still encounter an execution error or contain an incorrect algorithm. (haskell.org)
Languages also differ in memory management. Some require explicit allocation and release, while garbage collection automatically identifies memory that is no longer needed. Rust instead uses ownership rules and compile-time checks to govern memory use without requiring a tracing garbage collector. Memory management and typing are related design concerns but describe different aspects of program behavior. (doc.rust-lang.org)
Implementation and standardization
A compiler translates a program into another representation while preserving its specified meaning. The output may be machine code or an intermediate instruction format. An interpreter executes a program representation by implementing its operations. These techniques can be combined; compilation and interpretation are not mutually exclusive properties of a language. (cs.princeton.edu)
Java illustrates this distinction. Source programs can be compiled into bytecode for a virtual machine. The Java Virtual Machine specification defines the instruction format and behavior without requiring a particular execution technology: implementations may interpret instructions or translate them into native machine code. Other languages can also target that format. (docs.oracle.com)
Language references and standards establish shared rules that support portability across implementations. Standard libraries specify reusable facilities beyond the core language. Nevertheless, implementation-specific extensions and differences in supported features can affect compatibility; portability depends on the precise language and library facilities a program uses. (cs.princeton.edu)