Paradigms -- The Architecture of Programming Languages

Analysis Requirements & Principles architecture:
Paradigms
substance:
Abstractions
structure:
Domains
building blocks: Features surface:
Syntactics
Defining PLs Language
List
foundational safety flexibilized

  1. Paradigms (Introduction)
  2. Ontological Foundation: Models-of-Computation Paradigms
  3. Semantic Relation: Computer Programming or Code/Execution Paradigms
  4. Software Decomposition Paradigms

 
If you know further references, please don't hesitate to tell me (Ulf Schünemann), likewise if you have any suggestions.

[3KBM] Conrad Bock: Three Kinds of Behavioral Models; JOOP July/Aug 1999.
[DevSWforUI] ...

ADD: set oriented programming in SETL (procedural), Miranda (functional), Z (specification) ...

ADD: conceptual programming: A Conceptual Perspective on the Comparison of Object-Oriented Programming Languages

ADD: William Kent: Participants and performers: a basis for classficing o-o languanges; 67-70 in: H Kilov, B Harvey (eds): Proc of WS on Specification of Behavior Semantics in O-O Information Modeling (at OOPSAL'93).


Paradigms

«[Thomas] Kuhn used the term [paradigm] ... to describe a set of theories, standards and methods that together represent a way of organizing knowledge; that is, a way of viewing the world. Kuhn's thesis was that revolutions in science occured when an older paradigm was reexamined, rejected and replaced by another.
It is in this sense, as a model or example, and as an organizational approach, that Robert Floyd used the term in his 1979 ACM Turing Award lecture, which was titled "The Paradigms of Programming" [Floyd 79]. A programming paradigm is a way of conceptualizing what it means to perform computation, and how tasks that are to be carried out on a computer should be structured and organized» [Leda, p 3].
C.f. "paradigma" in science theory.

«[E]ach [programming] language comes along with a certain mindset or worldview, that is, a certain way of thinking, which can be hard to change, because one is not even aware of having it - it just "seems natural" and goes without question» [Goguen]

We will distinguish the following paradigms of
models of computation: code execution: software decomposition:
  • impersonal requests: imperative update
  • dataflow: applicative
    - pure functional (incl. relational)
    - applicative procedural
  • interacting-components:
    - message-passing
    - multi-agent
  • change propagation
  • algorithmic
    - imperative
    - procedural
    - structured
    - monadic
  • declarative:
    - relational (incl. logic)
    - applicative (functional)
  • rule-based (production systems)
  • applicative
  • algorithmic (incl. imperative)
  • structured (functional, procedural)
  • around hidden data:
    - data hiding
    - data type abstraction
    - object-oriented
  • When ``the imperative paradigm'' is opposed to ``the functional paradigm'' usually the combination of update model + algorithmic code + algorithmic/procedural decomposition is opposed to the combination of applicative model + functional code + applicative/functional decomposition. However, model, code and decomposition can also be combined differently, and there are also mixed models, mixed code, and mixed decomposition.

    For an overview on paradigms (imperative, object-oriented, functional, relational) and their influence see chapter 1 of [Leda].

    The object-oriented paradigm
    model of computation:
    object systems / message passing systems
    abstractions:
    object + class + subclassing
    decomposition:
    class modules
    execution:
    algorithmic & applicative

    The procedural paradigm
    model of computation:
    imperative & applicative
    abstractions:
    procedural abstraction
    decomposition:
    structured
    execution:
    algorithmic & applicative


    Ontological Foundation: Models-of-Computation Paradigms

    By subscribing to a standard MOC, the programmer choses the primitive operations and the combinators in terms of which he conceptualizes computations.

    A programming language supporting that MOC (ie., with static and dynamic semantic domains corresponding to the MOC's entities and events) allows computations thus conceptualized to be expressed/specified in program code[>].

    Compare this to system models (or models of the world), and to (partial) structural meta-models of object-oriented programming languages with memory-object semantics (C++) or with implicit reference semantics (Java, and similarly Smalltalk, and Eiffel without expanded objects).

    See a comparison of Applicative model and Update model for streams of data or timed events.

    1. Impersonal Request Models:
      provider:              system
      request mesg (undir.): op-name + parameters
      Execution is the (possibly multithreaded but basically sequential) issuing and honoring of impersonal "service requests" ("commmands"). `Impersonal' here means that they are not directed to a particular service provider, that actions/services are not demanded/requested from an identifyable computational entity (cf. linguistics: the unpersonal `it' in the statement "it rains"). The service provider is an invisible unnameable ubiquitous infrastructure, the `execution environment', `system' or `computer'.

      Imperative Update Models are the main (only?) example:
      primitive op: update
      The characteristic primitive service is the (destructive) update of a basic variable (box, pigeon-hole) which gives it a new basic value. (Of course there must also be other primitive services for transforming one basic value to another, like arithmetic and logic operations.) Consequently, compution in the imperative MOC is characterized by an incremental modification of state.

      Programming a system based on incremental update (by ``assignment'') «forces us to carefully consider the relative orders of the assignments.» Hence they are typically written as imperative code, but functional update code is also possible.

      1. In the (simple) Procedural MOC, the programmer can extend the language's built-in set of commands/services by user-defined commands f. These are obtained from a compound command C by way of procedural abstraction.
        Mapping their applications (procedure calls) into the update model would require the addition of some mechanism (typically the stack) to remember the local state each time a procedure is called: «Der Prozeduraufruf ist ein komplexerer Mechanismus als die Fallunterscheidung oder die Schleifenbildung, da es erforderlich ist, daß Informationen über den Zustand des Programs zum Zeitpunkt des Aufrufs und die Arbeitsweise der aufgerufenen Prozedur gespeichert werden» [Louden, 12].
        -> Procedures taking parameters and returning results are better explained in the applicative procedural model. Here incremental modification is explained as side-effects of applications of operations to operands.
      2. An imperative-update model in which the system components use shared global variables for communication has a -> repository architecture.

    2. Applicative Models are the main (only) examples:
      provider (single service): operation
      primitive op:              application
      request mesg (directed):   parameters
      Here the characteristic processing units are operations. The characteristic primitive action is the application, the flow of an operand to an operation (input action). An application is (successfully) terminated (after intermittant further applications) by the outflow of a result (output action). In other words, each processing unit implements one service, the service is requested by sending the necessary parameters to the processing unit.

      1. The Applicative Procedural MOC
        additional provider:     store
        request mesg to storage: new value OR 'read'
        combine operations and storages (shared variables, repositories) as processing-units / service-providers. An operation, besides computing a result, can read and update storages. Update of a storage is also called a
        side-effect. (The ability to update state improves modularity where random numbers are used.)
        E.g. Lisp/Scheme.
      2. The Generic Operations MOC generalizes the applicative procedural MOC with the notion dynamic binding of operations f to methods fi, their implementations, (shared with the object-oriented MOC). A request names a (generic) operation f and actual parameters. The parameter in the request determine which method fi to be executed for honoring the request for f
        -> cf. 2-D Data Abstraction
        Examples: CLOS, Dylan[?].

    3. Interacting-Components MOCs, i.e., MOCs with an interacting-components architecture[^], are characterized by a "signal-response" type of interaction: Computation proceeds by virtual computing units interacting with each other. Different styles of interaction and computing units lead to differents models of the computation.
      1. Message-passing Models, Client/Server Models or Object Models [MCOM, Quib 99-104] are closely connected with the object abstraction:

        «In all other languages we've considered [Fortran, Algol60, Lisp, APL, Cobol, Pascal], a program consists of passive data-objects on the one hand and the executable program that manipulates these passive objects on the other. Object-oriented programs replace this bipartite structure with a homogeneous one: they consist (partially in Simula, exclusively in Smalltalk) of a set of data systems [i.e. objects, c.f. p. 43], each of which is capable of operating on itself.» [PLing, 249]


    Semantic Relation: Computer Programming or Code/Execution Paradigms

    The second aspect of paradigms concerns the relationship between computation (carried out by computers) and program code, ie. some text in a programming language by which the computer is programmed (controlled), IOW, a program which the computer executes. The program code specifies or models a computation in the MOC[<]. There are three understandings on which aspect of computation programs (should) focus, and which are (should be) implicit. Correspondingly, there are three ways of how the program processor[^] is viewed to interpret what the program code is saying, i.e., how it executes the program code (specification of computation).
    focus on: code/exec.
    paradigm
    MOC
    pure applicative applicative storage update other
    1. sequence of computation steps: algorithmic monadic style procedural imperative ?
    2. how outputs relate with inputs: declarative pure functional impure functional ? ?
    3. response to stimuli: rule-based ? ? state-rules event-rules
    1. Algorithmic Code focuses on, and thus specifies explicitly, the sequence (thread) of computation steps (the control flow), and not so much on how values depend on each other [3KBM].
      [+] This is the emphasis needed in buisness applications [3KBM].
      Note that there may be several threads of sequential execution at once (multi-threaded program). It is essential for algorithmic languages to have control constructs by which the flow of control can be manipulated (c.f. structured control constructs).
      «An intuitive model of the execution of a program is to think of it in terms of a machine state consisting of a control part representing the instructions to be executed and a data part consisting of the structure being manipulated by the instructions of the program. This picture is augmented by some idea of the point of control indicating the instruction currently being executed. The computation then is a sequence of transitions in which the data is altered and the point of control moves through the instructions of the program. The semantics of a programming language is then described by saying how it is converted into instructions and what transitions are engendered by instructions» [p 14 in Gunter: Formal Semantics of Programming Languages]
      1. Imperative Code specifies a thread of assignments in the update model. «The imperative paradigm is marked by a fundamental use of commands such as assignment and flow control structures. The effects of the sequential list of commands that make up the imperative program combine to produce the desired computational effect» [G 245, >].
        «Eine Programmiersprache, die durch ... sequentielle Ausführung von Instruktionen, durch die Verwendung von Variablen, die Speicherwerte darstellen, und durch die Verwendung von Zuweisungen zum Ändern des Wertes von Variablen -- nennt man eine imperative Sprache, da ihr wichtigstes Merkmal eine Folge von Anweisungen ist, welche Kommandos oder Befehle darstellen» [Louden, 14].
        E.g. JBC, assembly code, three-address code, IMP, ...
      2. Procedural Code (imperative-applicative code) specifies a thread of applications in the applicative procedural model. «A program execution is regared as a (partially ordered) sequence of procedure calls manipulating data structures» [OOP?]. The threaded applications (not the ordinary applications nested inside of them -- cf. functional update code) do not return a result, but instead use update (on global variables or on out-parameters) to pass values. Imperative code can be subsumed by regarding assignment as a special built-in operation with update of the left-hand parameter. Then it becomes right to say «The procedural paradigm combines the imperative programming facilities described above with an abstraction mechanism to build procedures and functions. This mechanism allows the creation of generic commands» [G 245, <>].
      3. Structured Code «A program is structured if the flow of control through the program is evident from the syntactic structure of the program text. ... In this section "evident" is defined as single-entry/single-exit ...» [Sethi 63] «With single-entry/single-exit constructs, the behavior of a statement S can be characterized purely by conditions at the entry and exit to the statement. Such conditions are called preconditions and postconditions, respectively» [Sethi 80].
      4. Monadic Style Code (pure algorithmic code) is a way of specifying within a pure applicative model (in a pure functional language with support for monads) a thread of computation steps, i.e., of applications, since these are the only computation steps in a pure applicative model.
        Monadic style is explored in the context of the Haskell language. See on-line articles in the "Using Monads" section of the Haskell bookshelf.
      For returning from procedure calls the Language Independent Procedure Call standard [LIPC] (at ISO's "Committee Draft" stage) distinguishes call by value returned on termination (out parameter), and call by value returned when available. The latter «allows the return to take place as soon as it is [available] (i.e. while execution of the call is still in progress), or at any time thereafter - before, at, or even after termination of the call, since for LIPC the value is still "available". Indeed, it is not even precluded that such a value be returned more than once! [this particular method is included for logical completeness]» [LIPC] Brian Meek: What is a Procedure Call?

    2. Declarative Code specifies how outputs depend on inputs (it has a dataflow model in the background). The order of steps follows implicitly from this dependency [3KBM].
      A computation step (e.g., an applications) can only be made when other steps have made available the values which are inputs to this step -- since the data dependency between inputs and outputs form a partially ordered set, declarative code specifies only a partial order of computation steps (e.g., the computation steps implementing a function application f(x)) [3KBM]. [When [3KBM] says this, is he only talking of eager declarative code?]
      [+] Declarative code (data dependency specification) is good for manufacturing applications [3KBM].
      Declarative code is based on the concepts of function, relation, and logic as developed in mathematics [Louden, 14f].
      1. Relational Code:
        1. Logic Code, or constraint-based code: «A program is regarded as a set of equations,» or (first order) predicate logic assertions, «describing relations between input and output» [OOP?]. «The characteristic attributes of the logical paradigm include computation with relations, the existence of an underlying search mechanism, an incrematal rule-based program structure, and the logical variable» [G <].
        2. Relational Databases expresses relations as tables with (key) attributes, queries using operations projection, join etc.
        3. Relational Programs. «Relational programming is a generalization of functional programming that includes aspects of logic programming.» Introduced 1981 by MacLennan:
          - entire relations are manipulated as data
          - program definitions are represented as relations
          - relational operators (themselves relations) for manipulating data and programs
          MacLennan's language RPL distinguishes extensional relations (data structures) from intensional relations (computable functions).
          [Dave Cattrall, Colin Runciman:
          Widening the Representation Bottleneck: A Functional Implementation of Relational Programming; 1993]
      2. Applicative/Functional Code (functional programming): «A program is regarded as a mathematical function, describing a relation between input and output» [OOP?]. Program execution is the evaluation of nested function calls (with or without function definitions) where the order of sub-expression evaluation is not indicated in the code: «[W]ithin the contraints that a function can only be applied once the arguments are available, and must be applied before the results are used, the execution of functions can be performed in any sequence» [Leda, p 13].
        The language definition usually fixes the order of evaluation to one of the following evaluation strategies:

        1. Pure Functional Code evaluates without side-effects. It can be executed in the pure functional model, but also in a ``substitution model,'' (c.f. SICP) since it has the property of referential transparency.
          In a ``substitution model'' execution is modeled as rewriting the program term. C.f. the rewriting system style of defining a language's semantics.
        2. Functional Update Code evaluates with side-effects (applicative procedural model): update of variables, input/output.
          E.g. Lisp/Scheme.

    3. Rule-based Code: Focus on reaction to stimuli means specifying which steps to take when a stimulus occurs (it has a state-machine-with-I/O model in the background). The sequence of steps is determined by the interplay of stimuli from the environment and between the computational units [3KBM].
      The stimulus can originate from the environment of the specified computational unit, e.g., module, object, etc., or from within the computational unit itself. Consequently, the program is a collection/system of rules of the form if condition then action. Rule-based code does not explicitly specify the sequence of computation steps. [3KBM]
      [+] This is good for real-time applications, and reactive applications [3KBM].
      [-] (What [DevSWforUI, 166f] says about `production systems' applies to rule-based systems in general:) «A ... problem associated with the use of production models is lack of explicit transfer of control. Programmers are taught to think in terms of sequential algorithms, whereas the data-driven nature of production models require a heavily parallel method of thinking. This problem can be overcome with training, and if production rule systems prove to be suitable useful, programmers will be taught earlier to think in terms of parallel solutions to problems.»

      1. In an update model, rules are triggered by certain states (state-rules, or ``production systems''[DevSWforUI]): «Rules whose condition part is satisfied by the current state of the system are fired. When a rule is fired, the action part is executed.'' It «does not specify (a sequence/set of) all actions to do, but specifies only changes to the state. These changes trigger further actions not specified by the state's changer.» «Since the rules rely only on the current state of the system, there is no inherent sequencing in the rules. ...» [DevSWforUI, 166f]
        [-] «Since control is not explicitly transferred ... the system must monitor a large data space in order to decide which rule to fire ...» [DevSWforUI, 166f]
      2. In an event/multi-agent model, the rules are triggered if a broadcasted «event» matches the condition (event-rules). The reactions are then called `responses' to those events.

    Software Decomposition Paradigms

    For this kind of paradigms see also [WIOOP].
    «A language is said to support a style of programming [aka paradigm] if it provides facilities that makes[!] it convenient (reasonably easy, safe, and efficient) to use that style. A language does not support a technique if it takes exceptional effort or exceptional skill to write such programs; it merely enables the technique to be used. For example, you can write structured programs in Fortran, write type-secure programs in C, and use data abstraction in Modula-2, but it is unnecessarily hard to do because these languages do not support those techniques.
    Support for a paradigm comes not only in the obvious form of language facilities that allow direct use of the paradigm, but also in the more subtle form of compile-time and/or run-time checks agains unintended deviation from the paradigm. ... Extra-linguistic facilities such as standard libraries and programming environments can also provide significant support for paradigms.» (continued here) [WIOOP]
    E.g. «... C only enables the decomposition of a program into modules, while Modula-2 supports that technique.» [WIOOP, 4].
    1. Applicative Decomposition results in functional/applicative code (with or without side-effects) without function definitions: «Each expression in this model can be broken up into components that are either operators or operands; the operators are applied to the operands. Pure Lisp is an example of a language based on this paradigm» [G 247, <>].

    2. (Structured) Algorithmic Decomposition focuses on the control flow, resulting in algorithmic code: «The focus is on the design of the processing, the algorithm needed to perform the desired computation» [WIOOP]. ``«algorithmic decomposition: The process of breaking a system into parts, each of which represents some small step in a larger process. The application of structured design methods leads to an algorithmic decomposition, whose focus is upon the flow of control within a system» [Booch, 1991, p 512]'' [Quib, glossary: Funktionale Dekomposition].
      1. Algorithmic+Applicative Decomposition: combines algorithmic decomposition (of either flavour) in the large (e.g. statement level) with applicative decomposition (of either flavour) on the subordinate level (expressions).
        Nesting of procedure calls of course raises the applicative/functional code question of evaluation strategies for parameter expressions. See also [LIPC].
      What the primitive building blocks are, depends on the whether the code is supposed to be imperative (assignment), procedural (calls with side-effects), or monadic style (calls without side-effects).
      Features (sequential): The essential structuring elements are the three nestable structured control constructs for goto-less programming (other control constructs): sequence block, loop block, and case block: «Ein Vorteil strukturierter Kontrollstrukturen liegt darin, daß sie innerhalb anderer Kontrollstrukturen geschachtelt werden können, normalerweise in jeder erforderlichen Tiefe ...» [Louden, 9f]. (Talking about a language for algorithmic decomposition in the imperative paradigm:) «Eine Programmiersprache ist Turing-vollständig, wenn sie ganzzahlige Variablen und Arithmetik besitzt und Anweisungen sequentiell ausführt, einschließlich Zuweisung, Fallunterscheidungen (if) und Schleifen (while).» [Louden, 13].
      Features (multi-threaded): Additional control constructs: block for parallel execution of each sub-block in it, and parallel loop doing all iterations at once [Louden, 631f], and parallel case doing all applicable cases as once:
        parbegin
           S1;
           S2;
           ...
           Sn;
        parend;
      
       
        for i := 1 to n
        doparallel
           ...
        parend;
      
       
        parif a==0      then C1;
           [] a<=9      then C2;
           [] a>=9      then C3;
           [] iseven(a) then C4;
        parend;
      

      [-] «[T]he problem with the imperative paradigm is that it is not particularly close to the way in which human beings ... go about solving problems. Thus, formulating a problem in an imperative style many [sic] be a difficult task. Furthermore, the difficulty of this task increases dramatically as the complexity of the problem increases» [Leda, 10].
      «Pascal [is a] ... language that demands that every problem domain be modeled in terms of control structures that shuttle control flow this way and that among a collection of statements. Although any algorithm can be made to conform to this "von Neumann" model of the world, it can take considerable effort to do so for many different problem domains» [G 235].

    3. Structured Decomposition: «[F]unctions are used to create order in a maze of algorithms» [WIOOP], in the extreme by a rigorous top-down design/stepwise refinement of the top-most ``system function,'' leading to a structured program. A language supporting it needs function/procedure calls, and definitions based on other functions/procedures (c.f. procedural abstraction).
      «The importance of this decomposition strategy is not simply that one is dividing the program into parts. After all, we could take any large program and divide it into parts -- the first ten lines, the next ten lines, the next ten lines, and so on. Rather, it is crucial that each procedure [or function] accomplishes an identifiable task that can be used as a module in defining other procedures» [SICP]
      1. Functional Decomposition adds function definitions to applicative decomposition: Functional programs consist of function definitions and nested (function call) sub-expressions. See functional programming languages as examples.
        A functional decomposition can be found with
        Feature set: «Eine Programmiersprache ist Turing-vollständig, wenn sie ganzzahlige Werte, Funktionenen auf diese Werten und einen Mechanismus zur Definition neuer Funktionen unter Verwendung vorhandener Funktionen, Fallunterscheidung und Rekursion besitzt» [Louden, 15].
        1. Lambda-Free Decomposition: «The lambda-free paradigm is a restriction of the applicative model to the use of two types of functional mechanisms. One type is used for applying a function to its argument, the other is used for creating and naming functional forms. Backus's FP [J Backus: Can programming be liberated from the von Neumann style? A functional style and its algebra of programs; Communications of the ACM 21: 613-640, 1978] is an example of a language reflecting this approach to programming» [G 247].
        2. Functional decomposition with assignment improves modularity where random numbers are used. E.g. Lisp/Scheme.
        More:
      2. Procedural Decomposition adds procedure definitions to algorithmic+applicative decomposition [or definitions and non-nested calls to mere algorithmic decomposition?]. Structured languages offer them on top of structured control constructs.
        Most common is the combination with the imperative flavour of algorithmic (+applicative) decomposition: «The procedural paradigm combines the imperative programming facilities ... with an abstraction mechanism to build procedures and functions. This mechanism allows the creation of generic commands» [G 245].
      [-] «Die funktionale Dekomposition ging von dem fragwürdigen Konzept der ``Systemfunktion'' aus, die es galt, in der Wirthschen Top-down-Manier schrittweise zu verfeinern ... Dadurch wurden die Systemanforderungen zu einem sehr frühen Zeitpunkt des Systementwicklung in einer einzigen Funktion eingefroren. ... Eine starre Systemfunktion und das von ihr abgeleitete sequentielle Phasenmodell widersprechen aber dem evolutionären Charakter der Software-Entwicklung: Die Systemfunktion ist keineswegs eine Konstante, die im ersten Anlauf ermittelt werden können; die Kundenanforderungen sind in aller Regel vage und wechelhaft. Die Software-Entwicklung ist ein kommunikativer Prozeß zwischen mehreren Beteiligten, so daß Rückkopplung zwingend erforderlich ist» [Quib, 108].

    4. Decomposition around Hidden Data «Over the years, the emphasis in the design of programs has shifted away from the design of procedures towards the organization of data» [WIOOP]. There are several paradigms for decomposing systems into units in which some data is hidden from the rest of the system.
      1. Data Hiding (c.f. Object Abstraction) ``This paradigm is also known as the "data hiding principle"'' [WIOOP]: «[P]artition the program so that data is hidden in modules,» [WIOOP]; each module offers to the outside procedures, and variables.
        Supported by the module construct in the language [WIOOP].
      2. Data [Type] Abstraction (see also below): «Programming with modules leads to the centralization of all data of a type under the control of a type manager module» [WIOOP].
        Modules are not enough as a language support: «A type created through a module mechanism is in most important aspects different from a built-in type and enjoys support inferior to the support provided for built-in types. ... In other words, the module concept that supports the data hiding paradigm enables [data abstraction], but does not support it» [WIOOP, 5].
      3. Object-Oriented Decomposition (see also object abstractions): «Rather than writing procedures that manipulate data structures, operations and data are viewed as an organic whole, a unit that provides a service ... used by other portions of a software system. This view can be succinctly summed by a twist on a well-known quotation: "Ask not what you can do to your data structures, but ask what your data structures can do for you."» [Leda, p 12].
        In object-oriented design: «object-oriented decomposition: The process of breaking a system into parts, each of which represents some class or object from the problem domain. The application of object-oriented design methods leads to an object-oriented decomposition, in which we view the world as a collection of objects that cooperate with one another to achieve some desired functionality» [Booch, 1991, p 516, quoted from [Quib: glossary: funktionale Dekomposition]].
        In the program this designed decomposition is then expressed in terms of class definitions which comprise method definitions, and which are related in an inheritance (subclass/subtype) hierarchy.
        Minimal feature set: «A minimal list of features that should be supported in any object-oriented programming language includes:
        • Objects, consisting of both state and operations.
        • Classes, to generate objects (though delegation would be a reasonable alternative).
        • Mesage sending, as a way of specifying computation.
        • Instance variables, representing state.
        • Subclasses, to support reuse of the instance variables and methods of an existing class in definining a new class.
        • Subtypes, depending only of object interfaces, to provide a mechanism for programmers to use and object of one type in a context which expects one of a different but related type.
        • Keywords, self and super, representing the resevier of a message and its superclass, respectively.» [K Bruce et.al.: PolyTOIL: A type-safe polymorphic object-oriented language; extended abstract in ECOOP'95]

        On the object-oriented paradigm in general:


        My links on object-oriented software development
        On object-oriented terms and concepts: Objects: Concepts and Terms
        On objects, instances, values, entities etc:
        • Objects are data abstractions, and have a method suite.
        • Objects in ORM are either entities (non-lexical objects) or values (lexical objects). Each entity is required to be identified by a well defined reference scheme. «For example, employees might be identified by employee numbers or social security numbers, and countries by ISO country codes or country names. ... For example, you are an instance of the entity type Person. Entities might be referenced in different ways, and typically change their state over time. Glossing over some subtle points, values are constants (e.g. character strings and numbers) that basically denote themselves, so do not require a reference scheme to be declared» [UML Data Models from an ORM Perspective: Part One].
        • »UML classifies instances into objects and data values. UML objects basically correspond to ORM entities, but are assumed to be identified by oids. UML data values basically correspond to ORM values: they are constants (e.g. character strings or numbers) and hence require no oids to establish their identity. Entity types in UML are called classes, and value types are called data types» [UML Data Models from an ORM Perspective: Part One]

        On ``what is a class''?
        • See also Class below.
        • Jacobson, et.al.: Object-Oriented Software Engineering; 1994. (Underlining added):
          «A class represents a template for several objects and describes how these objects are structured internally. Objects of the same class have the same definition both for their operations and for their information structures.» [OOSE, 50]
          «In object-oriented languages, each object is described by a class. This class is both a module for source code and a type for the class instances.» [OOSE, 87]
        • A J H Simons: Let's agree on the meaning of class; Sheffield, 1996.
          The use of the term ``class'' varyies in the following dimensions:
          1. Intention (class definition) vs. Extension (set of instances).
          2. Type (abstract type) vs. Implementation (concrete type).
          3. Monomorphic vs Polymormic (including/excluding subclasses/subclass-instances).
        • A J H Simons: Exploring Object-Oriented Type Systems (slides); OOPSLA'94.

        On types and classes, subtypes and inheritance:

    Analysis Requirements & Principles Paradigms Abstractions Domains Features foundational safety flexible typing Syntactics Defining PLs Language List
    Ulf Schünemann 120698, 281199