Fact-checked by Grok 2 weeks ago

Bounded quantification

Bounded quantification is a construct in that enables universal or existential quantifiers over type variables restricted by subtyping bounds, allowing polymorphic functions to be defined over a constrained set of related types in programming languages. This mechanism integrates with , providing a foundation for while ensuring through explicit constraints on the quantified types. Introduced in the late as part of efforts to model object-oriented features in typed lambda calculi, bounded quantification addresses limitations in earlier systems like by incorporating subtype bounds, such as in the form ∀t ⊆ τ. t → t, which types functions applicable to any subtype of τ. A significant extension, known as F-bounded quantification, generalizes this by allowing the bound to depend recursively on the type variable itself, as in ∀t ⊆ F. σ, where F is a type expression involving t. This innovation, proposed by , , , Olthoff, and Mitchell in 1989, resolves challenges with recursive types, such as typing binary methods (e.g., equality or comparison functions) that require the input and output types to match the same recursive structure. In practice, bounded quantification underpins features in modern programming languages, including Java's bounded type parameters (e.g., <T extends Comparable> for self-comparable types) and Scala's support for F-bounded polymorphism in definitions. These applications facilitate expressive type-safe for object hierarchies, inheritance, and generic algorithms like sorting over partially ordered types. Theoretically, systems incorporating bounded quantification, such as F< and its F-bounded variant, exhibit properties like subject reduction and type preservation under reduction, though remains undecidable in general. Ongoing research explores decidable fragments, such as subclassing-bounded quantification, to improve practical implementability in compilers and type checkers.

Background in Type Theory

Universal and Existential Quantification

In , universal quantification, denoted as \forall T. \tau, enables the definition of polymorphic functions that can operate uniformly over any type T, without depending on the specific properties of that type. This construct allows a to be abstracted over a type variable T, resulting in a type that is applicable to arbitrary instantiations of T. The introduction of universal quantification occurs through , where a \Lambda T. e is formed, assuming T is a fresh type variable not appearing in the context. The typing rule for introduction is: if \Gamma, T \vdash e : \tau, then \Gamma \vdash \Lambda T. e : \forall T. \tau, where \Gamma is the typing context and \tau may contain T freely. Elimination, or type application, instantiates the quantified type with a specific type S: if \Gamma \vdash e : \forall T. \tau and \Gamma \vdash S (type), then \Gamma \vdash e[S] : \tau[S/T]. This mechanism ensures while providing flexibility for . Existential quantification, denoted as \exists T. \tau, abstracts over an unknown type T, allowing the encapsulation of a concrete type and its associated value while hiding the type's identity from the client. This is particularly useful for modeling data abstraction, where the implementation type is existentially quantified to prevent direct access. Introduction via packing constructs a package \mathsf{pack}\, T,\, v as \exists T. \tau, where v : \tau[T/U] for some fixed U in \tau, certifying that the value satisfies the existential specification. The typing rule is: if \Gamma \vdash T (type) and \Gamma \vdash v : \tau[T/U], then \Gamma \vdash \mathsf{pack}\, T,\, v : \exists U. \tau. Elimination through unpacking, often via a let-binding or case expression, extracts the hidden type and value into a scope where the type remains opaque: if \Gamma \vdash e : \exists T. \tau and \Gamma, x : \tau, T \vdash body : \sigma (with T fresh), then \Gamma \vdash \mathsf{let}\, (\mathsf{pack}\, x : \tau) = e\,\mathsf{in}\, body : \sigma. This duality to universal quantification supports modular designs by separating interfaces from implementations. Universal quantification in System F serves as the foundation for parametric polymorphism, enabling type-generic functions in practical programming languages. These concepts were introduced in Jean-Yves Girard's System F in 1972, establishing a basis for higher-order typed lambda calculi that influenced subsequent developments in type theory.

Parametric Polymorphism

Parametric polymorphism enables the development of code that operates uniformly across a variety of types, treating the type parameter as an abstract entity without relying on type-specific operations or knowledge of the concrete type. This form of polymorphism, also known as genericity, allows functions and data structures to be defined generically, where the behavior remains consistent regardless of the instantiated type, ensuring that the code does not discriminate based on the particular type provided. In programming languages such as , manifests through polymorphic functions, such as the function that applies a given to each of without regard to the list's type, and through functors, which are parametric modules that generate structure instances based on input signatures. Similarly, in , unbounded type classes support by allowing instances where no additional constraints are imposed, enabling generic definitions like the function of type that works for any type without requiring type-specific methods. These mechanisms facilitate the creation of reusable components that abstract over types, as seen in ML's where functors parameterize structures over type variables. The primary benefits of include enhanced by preventing type errors at through uniform treatment of types, greater by hiding implementation details behind interfaces, and significant , as a single definition suffices for multiple type instantiations without duplication. However, it has limitations in scenarios requiring type hierarchies or constraints, such as when operations like comparison must be available on the parameterized type, as pure cannot enforce such requirements without additional mechanisms. This approach draws from in , where polymorphic functions embody types of the form that quantify over all possible types.

Core Concepts of Bounded Quantification

Bounded Type Variables

Bounded type variables introduce constraints on type parameters in polymorphic types, restricting them to a of possible types defined by a relation. This mechanism extends , the unbounded precursor where type variables range over all types, by allowing programmers to specify that a type T must be a subtype of a given type U. The syntax for bounded is typically expressed as \forall (T <: U). \tau, where T is the bounded type variable, U is the upper bound, and \tau is the type body that may depend on T. This notation originates from early explorations in type theory aimed at supporting inheritance and in object-oriented contexts. The typing rules for bounded quantification ensure type safety by enforcing the subtype constraint during type application. Specifically, to apply a polymorphic term of type \forall (T <: U). \tau to an actual type T', the judgment requires T' <: U, after which the resulting type is \tau[T / T'] (substituting T' for T in \tau). This rule prevents invalid instantiations, such as applying a function expecting subtypes of a base class to an unrelated type, thereby maintaining the integrity of subtyping hierarchies. Bounded type variables play a crucial role in enabling operations on type parameters that rely on shared interfaces or behaviors among subtypes. For instance, a generic function can invoke methods defined in the upper bound U, assuming all possible T implement those methods, such as accessing a common field in record types representing objects. This allows uniform processing of hierarchical types, like drawing operations on shapes where T ranges over subtypes of a base "Shape" type. In formal semantics, bounded quantification is modeled within typed lambda calculi such as F^<\! :, an extension of System F that incorporates subtyping. The operational semantics preserve subtyping relations under quantification: if a term is well-typed under a bounded quantifier, reductions maintain the subtype constraints, ensuring subject reduction and progress properties hold. This preservation guarantees that type applications remain valid throughout evaluation, supporting decidable type checking in restricted fragments.

Subtyping Constraints

In bounded quantification, subtyping rules for universally quantified types, such as \forall X \leq B. T, ensure type safety by relating instances where the bound is widened and the body respects the substitution. Specifically, if B_1 \leq B_2 and T_1[B_2 / X] \leq T_2[B_2 / X], then \forall X \leq B_1. T_1 \leq \forall X \leq B_2. T_2, reflecting covariance in the bound and careful substitution in the body to maintain polymorphism under subtyping. For existential quantifiers, dual rules apply using union types, preserving contravariance in negative positions like function arguments. These rules exhibit covariance in the upper bound for universal quantification, allowing a narrower bound to subtype a wider one, while the body must adjust covariantly under the looser bound. However, contravariance arises in contexts like method parameters within the quantified body, ensuring the holds across polymorphic invocations. A key challenge in these subtyping rules is their potential undecidability, particularly when bounds involve , as the subtype relation may require solving infinite expansions that do not terminate. For instance, checking \forall \alpha \leq \alpha. \top \leq \forall \alpha \leq \top. \top propagates recursive constraints that can loop indefinitely without additional restrictions. In type inference, constraint propagation handles these rules by lifting types to minimal forms that satisfy bounds, such as computing the smallest type \tau \upharpoonright \alpha free of certain variables to resolve local subtyping obligations. This technique, applied in systems restricting bounds to class names, ensures decidable checks by separating subclassing from general subtyping and iteratively refining assumptions. The theoretical foundation integrates these rules with Mitchell-Wright-style subtyping in polymorphic lambda calculi, using coercion semantics to interpret subtypes as type-directed coercions that preserve operational behavior in calculi like F^<. Bounded type variables syntactically enable this integration by restricting quantification to subtype lattices.

F-Bounded Quantification

Motivation and Origins

F-bounded quantification emerged in the late 1980s as an extension to standard in type theory, specifically to address challenges in modeling recursive subtyping within object-oriented programming paradigms. Introduced by Peter Canning, William Cook, Walt Hill, John Mitchell, and Walter Olthoff in their 1989 paper, it built upon earlier work on , such as that by Luca Cardelli and Peter Wegner, which allowed polymorphic functions to operate uniformly over subtypes but struggled with self-referential types common in object-oriented designs. This innovation was motivated by the need to type functions that work polymorphically over families of types involving inheritance hierarchies, where standard bounds like T \leq U proved insufficient for recursive constraints. The core motivation stemmed from the failure of conventional bounded approaches to handle self-referential type definitions, such as implementing a comparable interface where the type parameter must extend itself, exemplified by \text{Comparable}<T \text{ extends Comparable}<T>>. In such cases, simple bounded quantification leads to inconsistencies or overly restrictive , preventing the expression of methods like or ordering that operate on instances of the same type family. F-bounded quantification resolves this by permitting bounds of the form T \leq F<T>, where F is a or , enabling recursive while preserving and polymorphism. This approach was particularly vital for encoding object-oriented features like and in statically typed languages. Over time, F-bounded quantification has profoundly shaped type systems for encoding complex inheritance patterns and binary methods, serving as a cornerstone for features in modern object-oriented languages and proving essential for maintaining type soundness in the presence of recursion. Bounded type variables, as a simpler precursor, provided the initial framework for subtype polymorphism but lacked the recursive power of F-bounds.

Formal Syntax and Semantics

In the typed lambda calculus, F-bounded quantification extends the syntax of System F to include bounded universal types where the bound may recursively depend on the quantified type variable. The syntax for types includes type variables \alpha, the top type \top, function types A \to B, and bounded universal types \forall \alpha \leq A. B, where A (the bound) may contain free occurrences of \alpha, effectively taking the form \forall \alpha \leq F[\alpha]. \tau with F a type constructor and \tau the body. Terms extend System F with type abstractions \Lambda \alpha \leq A. a and type applications a \{A'\}, alongside standard variables x, abstractions \lambda x : A. a, and applications a(a). The typing rules enforce a self-subtyping condition to handle the recursive nature of F-bounds. For type abstraction, if \Gamma, \alpha \leq A, \Delta \vdash a : B with \alpha not free in the value environment \Delta, then \Gamma, \Delta \vdash \Lambda \alpha \leq A. a : \forall \alpha \leq A. B, where the assumption \alpha \leq A (with A = F[\alpha]) implies the self-condition \alpha \leq F[\alpha]. For type application, if \Gamma, \Delta \vdash a : \forall \alpha \leq A. B and \Gamma \vdash A' \leq A[\alpha \leftarrow A'], then \Gamma, \Delta \vdash a \{A'\} : B[\alpha \leftarrow A'], ensuring instantiation preserves the bound via substitution and the self-subtyping A' \leq F[A']. Subsumption allows weakening types via subtyping: if \Gamma, \Delta \vdash a : A and \Gamma \vdash A \leq B, then \Gamma, \Delta \vdash a : B. Standard rules for functions and variables complete the system, with well-formedness requiring environments \Gamma (for types) to satisfy \Gamma \vdash \diamond and bounds to be subtypes under assumptions. The operational semantics consists of \beta- and \eta-reductions for terms and types: (\lambda x : A. b)(a) \to b[x \leftarrow a], (\Lambda \alpha \leq A. b)\{A'\} \to b[\alpha \leftarrow A'], and corresponding \eta-rules like \lambda x : A. b(x) \to b if x unbound. These ensure subject reduction—if \Gamma, \Delta \vdash a : A then for any reduct a' \to a, \Gamma, \Delta \vdash a' : A' with \Gamma \vdash A' \leq A—and progress, preventing stuck configurations in closed well-typed terms despite recursion. Denotationally, the system is modeled using partial equivalence relations (PERs) over a universal domain \omega, where types denote PERs and terms denote elements thereof; for instance, \llbracket \forall \alpha \leq A. B \rrbracket^\gamma = \bigcap \{ \llbracket B \rrbracket^{\gamma[\alpha \mapsto p]} \mid p \subseteq \llbracket A \rrbracket^\gamma \}, capturing the intersection over realizers satisfying the self-referential bound. This validates typing and supports recursive types via fixed points in the subtype lattice. F-bounded quantification arises as a conservative extension of System F_{\leq}, the second-order calculus with subtyping and non-recursive bounds \forall \alpha \leq B. \tau (where B lacks \alpha). Allowing recursive dependence in bounds preserves the expressiveness of F_{\leq} for parametric polymorphism while adding support for self-referential subtyping, proven via normal-form derivations that introduce no new inconsistencies. Subtyping constraints address recursion by enforcing fixed-point inclusions like T \leq F[T] in the subtype relation.

Theoretical Properties

Expressiveness and Limitations

Bounded quantification significantly enhances the expressiveness of type systems by integrating constraints with polymorphism, allowing for more precise modeling of type hierarchies in object-oriented contexts. In particular, it enables the encoding of recursive types through self-referential bounds, such as in the form \forall t \leq F. \sigma, where F is a type-level that captures structural . This construct characterizes types with recursive akin to \mathsf{Rec}\, t. F, facilitating the typing of operations that preserve subtype information, like geometric transformations on recursive data structures such as points or shapes. A key strength lies in supporting binary methods, which operate on pairs of objects from the same type while respecting . For instance, an equals method can be typed as \forall t \leq \mathsf{Comparable}. t \times t \to \mathsf{[boolean](/page/Boolean)}, ensuring that subtypes like or can implement equality without violating across hierarchies. Similarly, bounded quantification accommodates mixin-based by enforcing compatible "shapes" in recursive type definitions, such as separating material types (e.g., classes) from abstract shapes (e.g., interfaces like Comparable), thereby modeling composable behaviors without unbounded . F-bounded quantification further bolsters self-referential expressiveness in these scenarios. Despite these capabilities, bounded quantification has notable limitations in expressiveness. It typically adheres to prenex (rank-1) polymorphism, where quantifiers appear only at the outermost level of types, preventing the direct encoding of higher-rank types that nest quantifiers arbitrarily—such as functions accepting polymorphic continuations—without extensions like impredicative . Moreover, it falls short of full dependent types, which permit types to depend on term-level values (e.g., length-indexed lists), requiring separate mechanisms for value-dependent refinements beyond mere subtype bounds. In comparison to unbounded System F, which offers impredicative polymorphism across all types without subtyping, bounded variants like F_{<: introduce subtype constraints to support hierarchical polymorphism but narrow the scope of instantiation to bounded domains, trading some generality for improved integration with inheritance and object-oriented features. Theoretical analyses confirm that these extensions are conservative, meaning they preserve core properties of the underlying system—such as type safety and consistency—without introducing inconsistencies in basic formulations.

Decidability Issues

Bounded quantification, particularly when combined with subtyping in calculi like F≤, leads to undecidability of the subtyping relation due to the ability to encode recursive constraints that simulate Turing-complete computations. In F≤, which extends with bounded universal quantification and subtyping, the subtyping problem becomes undecidable because bounded types allow "re-bounding" behaviors that can express arbitrary recursive definitions, enabling reductions to the . This result builds on earlier work showing undecidability of subtyping for second-order types without bounds, based on for polymorphic types, as established by . To address this undecidability, researchers have identified decidable fragments of bounded quantification by imposing syntactic restrictions that limit recursive interactions. For instance, prohibiting recursive bounds—where the bound of a quantified type variable does not depend on that variable itself—ensures decidable subtyping by avoiding infinite descent in type comparisons. Similarly, stratified subtyping hierarchies, which organize types into levels where quantification only occurs within or across fixed strata without cyclic dependencies, yield decidable checking algorithms, often via automata-based methods or constraint simplification. These fragments maintain much of the expressiveness of bounded quantification for practical use while guaranteeing termination of type-checking procedures. Specific algorithms for handling F-bounded quantification in decidable settings leverage coinductive techniques to verify recursive constraints without enumerating infinite structures. In extensions like , Rémy and collaborators employ coinduction over coercion constraints to check satisfaction of F-bounds, treating recursive type equalities and subtyping as greatest fixed points that can be approximated finitely through step-indexed or environment-based proofs. This approach, formalized in systems like (System F with coercion constraints), supports bounded polymorphism while ensuring decidable type soundness for abstraction and instantiation rules, though full principal type inference remains challenging. These decidability results have significant practical implications for programming language design, where full bounded quantification is often approximated to achieve efficient type inference. Languages must balance expressiveness—such as supporting recursive generics—with computability, leading to trade-offs like restricting F-bounds to non-recursive forms (as in early Java generics) or using partial inference with user annotations (as in Scala). Such compromises enable decidable checking in real-world systems without sacrificing core benefits of bounded polymorphism, though they may require careful hierarchy management to avoid subtle undecidability pitfalls.

Applications in Programming Languages

Java Generics

Bounded quantification in Java generics was introduced with Java 5 (J2SE 5.0) in September 2004, marking a significant evolution in the language's support for type-safe parametric polymorphism. This feature drew heavily from the Generic Java (GJ) project, proposed by Gilad Bracha, Martin Odersky, David Stoutamire, and Philip Wadler in 1998, which outlined a translation-based approach to adding generics while preserving backward compatibility with existing Java bytecode. The GJ design emphasized bounded type parameters to constrain generic types, enabling safer and more expressive code without runtime overhead. In Java, upper bounds on type parameters are specified using the syntax <T extends U>, where T is the type variable and U is its upper bound, restricting T to U or any subtype thereof. This allows methods and classes to operate on a of types, such as ensuring elements in a collection implement a specific . For more flexible in method parameters and types, wildcards provide lower bounds via <? super T>, permitting arguments of type T or its supertypes, which is particularly useful for producer-consumer patterns like adding elements to a list without knowing the exact type. These constructs enforce compile-time checks for , preventing errors like inserting incompatible types into generic containers. F-bounded patterns in enable recursive self-referential bounds, as seen in the Comparable<T extends Comparable<T>> , which ensures that comparable objects can be compared to instances of their own subtype. This design realizes F-bounded polymorphism, allowing methods like compareTo to type-check against the declaring class's type parameter. F-bounded quantification provides the theoretical basis for such recursive bounds in generics. Java's generics rely on type erasure for implementation, where generic type information is stripped at compile-time, replacing type parameters with their bounds (or Object if unbounded) in the . Bounds are rigorously verified during compilation to ensure adherence to constraints, but type checks cannot leverage erased information, leading to the need for explicit casts in certain scenarios. , introduced in Java 5 and enhanced in later versions like Java 7 with diamond operators (<>) for constructor calls, automates much of the bound resolution, reducing verbosity while maintaining safety. This erasure model balances expressiveness with compatibility but imposes limitations, such as the inability to instantiate generic arrays or use instanceof with parameterized types.

Scala and Other Languages

In , bounded quantification is extended through F-bounded s, which use upper type bounds to reference the type parameter itself, enabling recursive constraints for self-referential polymorphism. For instance, a for ordered types can be defined as trait Ord[A <: Ord[A]] { def compare(that: A): Int }, allowing subtypes to maintain covariance while ensuring method return types align with the specific subclass. This approach supports higher-kinded types, where type constructors can be parameterized over other types, facilitating abstractions like functors or monads beyond simple value polymorphism. Additionally, introduces context bounds (or implicit bounds) as a shorthand for requiring implicit evidence of type class instances, such as def maximum[T: Ord](xs: List[T]): T, which expands to an implicit parameter using Ord[T]. This enhances expressiveness for ad-hoc polymorphism without explicit bound syntax. Other languages implement bounded quantification with variations emphasizing runtime support and constraints. In C#, the where clause enforces bounds on generic type parameters, as in class Comparer<T> where T : IComparable<T>, restricting T to types implementing the specified interface or inheriting from a base class, thereby ensuring access to required members at compile time. Ceylon took a different approach with reified generics (in its active development phase until archived in 2023), preserving full type information at runtime to avoid Java's type erasure pitfalls; this allowed bounded types like T of UpperBound to retain their constraints during execution, enabling reflective operations on generic arguments without loss of specificity.

Examples

Basic Bounded Quantification

Bounded quantification restricts type parameters in polymorphic constructs to subtypes (or supertypes) of a specified bound, enabling type systems to guarantee access to certain methods or properties without runtime checks or casts. This basic form combines parametric polymorphism with subtyping, allowing generic code to operate safely on a constrained set of types. A straightforward example is a generic Stack class parameterized by T where T must extend a Collection interface, permitting the stack to invoke Collection methods like size() on its elements. This design assumes a basic object-oriented setting with interfaces defining common behaviors.
pseudocode
[interface](/page/Interface) Collection {
  [int](/page/INT) size();
  // Other methods omitted for brevity
}

[class](/page/Class) Stack<T extends Collection> {
  [private](/page/Private) List<T> elements = new ArrayList<>();

  public void push(T item) {
    // Safe access to bound methods without casting
    if (item.[size](/page/Size)() > 0) {
      System.out.println("Pushing non-empty collection of [size](/page/Size) " + item.[size](/page/Size)());
    }
    elements.add(item);
  }

  public T pop() {
    if (!elements.isEmpty()) {
      return elements.remove(elements.[size](/page/Size)() - 1);
    }
    throw new EmptyStackException();
  }
}
The upper bound T extends Collection informs the type checker that any instantiation of Stack—such as Stack<List> or Stack<Set>—provides elements supporting Collection operations, ensuring type-safe calls like item.size() within push without explicit casts or potential ClassCastExceptions at runtime. This contrasts with unbounded parametric polymorphism, where T could be any type and method calls on T would require unsafe casts. Upper bounds (extends) suit producer patterns, where the generic type yields values readable as supertypes, while lower bounds (super) fit consumer patterns, where values from subtypes are accepted. The PECS principle—Producer Extends for reading, Consumer Super for writing—helps select bounds to preserve flexibility in method signatures. A frequent pitfall is bound mismatch: attempting Stack<String> fails since String does not extend Collection, preventing erroneous usage and enforcing the intended type constraints at .

F-Bounded Polymorphism Example

F-bounded polymorphism enables the implementation of type-safe binary methods in comparable containers, where operations like finding a minimum require arguments of the exact same subtype as the receiver. Consider a SortedList class parameterized over T extends Comparable<T>, allowing methods such as minimum to compare and return elements of type T without type casts or widening to a supertype. This recursive bound T <: Comparable<T> ensures that subtypes like Integer or custom classes can participate in operations that preserve the specific type, as introduced in the foundational work on F-bounded quantification for object-oriented programming. In Java, this can be exemplified as follows:
java
interface Comparable<T extends Comparable<T>> {
    boolean lessThan(T other);
}

class Integer implements Comparable<Integer> {
    private int value;
    public Integer(int value) { this.value = value; }
    public boolean lessThan(Integer other) {
        return this.value < other.value;
    }
}

class SortedList<T extends Comparable<T>> {
    private T element;
    public SortedList(T element) { this.element = element; }
    public T minimum(T other) {
        if (this.element.lessThan(other)) {
            return this.element;
        } else {
            return other;
        }
    }
}
Here, SortedList<Integer> instantiates correctly because Integer satisfies the bound Integer <: Comparable<Integer>, enabling minimum to return Integer precisely. In , F-bounded polymorphism often combines with self-types in to support operations like or that return the concrete subtype. For instance, a for cloneable entities can use a self-referential bound with a self-type annotation to enforce that implementations provide a method returning their own type:
scala
trait Cloneable[A <: Cloneable[A]] { self: A =>
  def clone: A
}

class MyClass extends Cloneable[MyClass] {
  override def clone: MyClass = new MyClass
}
This setup ensures MyClass.clone returns MyClass, not a supertype, leveraging the F-bound A <: Cloneable[A] alongside the self-type self: A => for precise typing within the trait. Type checking for such F-bounded instantiations proceeds recursively: for a type S to instantiate F<T> where T <: F<T>, the system verifies S <: F<S>, unfolding the bound as needed. In the SortedList<Integer> case, it checks Integer <: Comparable<Integer>, confirming Integer implements the interface with the correct parameter type; failure occurs if the bound does not hold, preventing unsafe polymorphism. This resolution supports recursive scenarios by ensuring subtype compatibility without infinite expansion, as formalized in the semantics of F-bounded quantification. In real-world applications, F-bounded polymorphism facilitates encoding patterns through , where an abstract builder class uses T extends Builder<T> to allow fluent methods like setValue to return the specific child builder type, enabling type-safe chaining in subclasses. Similarly, it supports machines via hierarchical , where state classes extend a bounded base to define transitions that return the exact next-state subtype, maintaining type precision across machine evolutions. These patterns extend basic bounded quantification by handling self-referential in practical object-oriented designs.

References

  1. [1]
    F-bounded polymorphism for object-oriented programming
    F-bounded polymorphism for object-oriented programming. Authors: Peter Canning ... Peter Canning, William Cook, Walt Hill, and Walter Olthoff. interfaces for ...
  2. [2]
    [PDF] F-Bounded Polymorphism for Object-Oriented Programming
    F-bounded quantification is a generalization of bounded quantification, introduced to provide a basis for typed polymorphic functions in object-oriented ...
  3. [3]
    Bounded Type Parameters - The Java™ Tutorials
    To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound.
  4. [4]
    Basic Theory of F-Bounded Quantification - ScienceDirect.com
    Abstract. System F-bounded is a second-order typed lambda calculus, where the basic features of object-oriented languages can be naturally modelled.
  5. [5]
    [PDF] Decidable Subclassing-Bounded Quantification - Microsoft
    Bounded quantification allows quantified types to specify subtyping bounds for the type variables they introduce. It has undecidable subtyping and type checking ...
  6. [6]
    [PDF] Girard's System F - People at MPI-SWS
    System F was introduced by Girard (1972) in the context of proof theory and by Reynolds (1974) in the context of programming languages. The concept of ...Missing: Jean- Yves
  7. [7]
    [PDF] Interpretation fonctionelle et elimination des coupures dans l ...
    Semantic Scholar extracted view of "Interpretation fonctionelle et elimination des coupures dans l'aritmetique d'ordre superieur" by J. Girard. ... System F to ...
  8. [8]
    [PDF] Lecture Notes on Parametric Polymorphism
    Sep 17, 2020 · Polymorphism refers to the possibility of an expression to have multiple types. In that sense, the simply-typed λ-calculus is polymorphic.
  9. [9]
    [PDF] Comprehensive Parametric Polymorphism: Categorical Models and ...
    1 Introduction. According to Strachey [26], a polymorphic program is parametric if it applies the same uniform algorithm at all instantiations of its type ...
  10. [10]
    [PDF] 1 Parametric polymorphism
    Examples include polymorphic functions in ML and Java generics. In this lecture we will consider parametric polymorphism in detail. Suppose we are working ...Missing: functors | Show results with:functors
  11. [11]
    [PDF] On The Type Structure of Standard ML
    Jan 10, 1992 · The basic entities of the Standard ML module system are structures, signatures and functors. ... Types, abstraction, and parametric polymorphism.
  12. [12]
    More polymorphism and type classes
    Feb 11, 2013 · Haskell's particular brand of polymorphism is known as parametric polymorphism. Essentially, this means that polymorphic functions must work ...
  13. [13]
    30 Parametric Polymorphism
    This kind of parameterization over types is called parametric polymorphism. Not to be confused with the “polymorphism” of objects, which we will discuss ...Missing: functors | Show results with:functors
  14. [14]
    [PDF] Subtypes vs. Where Clauses: Constraining Parametric Polymorphism
    To satisfy this need a programming language must provide a mechanism for parametric polymorphism, allowing for types as parameters to routines and types. We ...
  15. [15]
    [PDF] On Understanding Types, Data Abstraction, and Polymorphism
    ∀A⊆Type. Type | ∃A⊆Type. Type. Bounded Quantification. Universal ... Milner: A theory of type polymorphism in programming, Journal of Computer and.Missing: seminal | Show results with:seminal
  16. [16]
    [PDF] An implementation of F<: - Luca Cardelli
    In preparation for the typing algorithms, these are the same type rules expressed with de Bruijn indices. ... Bounded quantification is undecidable. Proc. 19th ...
  17. [17]
    [PDF] Typed Compilation of Inclusive Subtyping
    I present a type-preserving translation that eliminates sub- typing and bounded quantification without introducing any run-time costs.
  18. [18]
    [PDF] Basic theory of F-bounded quantification
    The key ingredient of F≤ is the bounded type abstraction (or bounded polymor- phism). It allows one to define a function which works for every type A′ that is a.
  19. [19]
    [PDF] Bounded Quantification is Undecidable - Page has been moved
    First proposed by Cardelli and Wegner, it has been widely studied as a core calcu- lus for type systems with subtyping. Curien and Ghelli proved the partial ...
  20. [20]
    Polymorphic type inference and abstract data types
    Polymorphic type inference and abstract data types · Type inference with polymorphic recursion · Type inference for unboxed types and first class mutability.
  21. [21]
    [PDF] Programming with Intersection Types and Bounded Polymorphism
    Dec 20, 1991 · This thesis unifies and extends prior work on intersection types and bounded quantification, previously studied only in isolation, by ...
  22. [22]
    [PDF] Getting F-Bounded Polymorphism into Shape
    F-bounded polymorphism is the ability to constrain a type vari- able by a type expressed in terms of the type variable itself [4].
  23. [23]
    [PDF] Complete and Easy Bidirectional Typechecking for Higher-Rank ...
    In this paper, we extend the proof-theoretic account of bidirec- tional typechecking to full higher-rank polymorphism (i.e., pred- icative System F), and ...<|control11|><|separator|>
  24. [24]
    [PDF] Advances in Programming Languages - Lecture 6: Dependent Types
    Oct 8, 2018 · Beyond System F with bounded and F-bounded quantification, F<:, F2 and Fω. ... Some other functional languages use dependent types to increase the ...
  25. [25]
    Bounded quantification is undecidable - ACM Digital Library
    As we shall see, this. “re-bounding” behavior is powerful enough to allow undecidable prob- lems to be encoded as subtyping statements. Cardelli and. Wegner's.
  26. [26]
    The Subtyping Problem for Second-Order Types Is Undecidable
    We prove that the subtyping problem induced by Mitchell's containment relation for second-order polymorphic types is undecidable.
  27. [27]
    [PDF] Hierarchies of decidable extensions of bounded quantification
    May 24, 2006 · Since F un has the largest type , the bounded quantification subsumes the unbounded one as a particular case: V a is simply expressed by V a < .
  28. [28]
    [PDF] System F with Coercion Constraints - Hal-Inria
    It has similarities with both F<: and Fη, but introduces yet another notion, instance bounded quantification—or unique lower bounds.Missing: methods | Show results with:methods
  29. [29]
    [PDF] From ML to MLF: Graphic Type Constraints with Efficient ... - Gallium
    To solve this problem, MLF enriches types with a new form of. (bounded) quantification: choose id receives the type ∀ (α ⩾ σid ) α → α. The variable α is ...
  30. [30]
    Making the future safe for the past: adding genericity to the Java ...
    We present GJ, a design that extends the Java programming language with generic types and methods. These are both explained and implemented by translation.Missing: project paper
  31. [31]
    Scala School - Advanced types
    F-bounded polymorphism. Often it's necessary to access a concrete subclass in a (generic) trait. For example, imagine you had some trait that is generic, but ...<|separator|>
  32. [32]
    Context Bounds
    A context bound is a shorthand for expressing the common pattern of a context parameter that depends on a type parameter.
  33. [33]
    where (generic type constraint) - C# reference - Microsoft Learn
    Jul 30, 2024 · The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, ...
  34. [34]
    The Ceylon Language - MIT
    In particular, generic type arguments are reified, eliminating many problems that result from type erasure in Java. There are no primitive types or arrays ...
  35. [35]
    Row and Bounded Polymorphism via Disjoint Polymorphism - DROPS
    Peter Canning, William Cook, Walter Hill, Walter Olthoff, and John C Mitchell. F-bounded polymorphism for object-oriented programming. ... POPL '01, pages ...
  36. [36]
    [PDF] Java Generics are Turing Complete - arXiv
    Nov 7, 2016 · Java generics are Turing complete because subtype checking is undecidable, and Java's type checker can recognize any recursive language.
  37. [37]
    Types and Programming Languages - MIT Press
    This text provides a comprehensive introduction both to type systems in computer science and to the basic theory of programming languages.
  38. [38]