HOME

TheInfoList



OR:

In
type theory In mathematics, logic, and computer science, a type theory is the formal presentation of a specific type system, and in general type theory is the academic study of type systems. Some type theories serve as alternatives to set theory as a foundat ...
, an intersection type can be allocated to values that can be assigned both the type \sigma and the type \tau. This value can be given the intersection type \sigma \cap \tau in an intersection type system. Generally, if the ranges of values of two types overlap, then a value belonging to the ''intersection'' of the two ranges can be assigned the ''intersection type'' of these two types. Such a value can be safely passed as argument to functions expecting ''either'' of the two types. For example, in
Java Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's List ...
the class implements both the and the interfaces. Therefore, an object of type can be safely passed to functions expecting an argument of type and to functions expecting an argument of type . Intersection types are
composite data type In computer science, a composite data type or compound data type is any data type which can be constructed in a program using the programming language's primitive data types and other composite types. It is sometimes called a structure or aggrega ...
s. Similar to
product type In programming languages and type theory, a product of ''types'' is another, compounded, type in a structure. The "operands" of the product are types, and the structure of a product type is determined by the fixed order of the operands in the prod ...
s, they are used to assign several types to an object. However, product types are assigned to
tuple In mathematics, a tuple is a finite ordered list (sequence) of elements. An -tuple is a sequence (or ordered list) of elements, where is a non-negative integer. There is only one 0-tuple, referred to as ''the empty tuple''. An -tuple is defi ...
s, so that each tuple element is assigned a particular product type component. In comparison, underlying objects of intersection types are not necessarily composite. A restricted form of intersection types are
refinement type In type theory, a refinement type is a type endowed with a predicate which is assumed to hold for any element of the refined type. Refinement types can express preconditions when used as function arguments or postconditions when used as return typ ...
s. Intersection types are useful for describing overloaded functions. For example, if is the type of function taking a number as an argument and returning a number, and is the type of function taking a string as an argument and returning a string, then the intersection of these two types can be used to describe (overloaded) functions that do one or the other, based on what type of input they are given. Contemporary programming languages, including
Ceylon Sri Lanka (, ; si, ශ්‍රී ලංකා, Śrī Laṅkā, translit-std=ISO (); ta, இலங்கை, Ilaṅkai, translit-std=ISO ()), formerly known as Ceylon and officially the Democratic Socialist Republic of Sri Lanka, is an ...
, Flow,
Java Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's List ...
, Scala,
TypeScript TypeScript is a free and open source programming language A programming language is a system of notation for writing computer programs. Most programming languages are text-based formal languages, but they may also be graphical. They are ...
, and
Whiley Whiley is the surname of: * Manning Whiley (1915–1975), British actor * Richard Whiley (born 1935), English cricketer * Jo Whiley (born 1965), English DJ * Matthew Whiley (born 1980), English cricketer * Jordanne Whiley (born 1992), British wheel ...
(see comparison of languages with intersection types), use intersection types to combine interface specifications and to express
ad hoc polymorphism In programming languages, ad hoc polymorphismC. StracheyFundamental concepts in programming languages Lecture notes for International Summer School in Computer Programming, Copenhagen, August 1967 is a kind of polymorphism in which polymorphic fu ...
. Complementing
parametric polymorphism In programming languages and type theory, parametric polymorphism allows a single piece of code to be given a "generic" type, using variables in place of actual types, and then instantiated with particular types as needed. Parametrically polymorph ...
, intersection types may be used to avoid class hierarchy pollution from
cross-cutting concern In aspect-oriented software development, cross-cutting concerns are aspects of a program that affect several modules, without the possibility of being encapsulated in any of them. These concerns often cannot be cleanly decomposed from the rest o ...
s and reduce
boilerplate code In computer programming, boilerplate code, or simply boilerplate, are sections of code that are repeated in multiple places with little to no variation. When using languages that are considered ''verbose'', the programmer must write a lot of boile ...
, as shown in the TypeScript example below. The type theoretic study of intersection types is referred to as the intersection type discipline. Remarkably, program termination can be precisely characterized using intersection types.


TypeScript example

TypeScript TypeScript is a free and open source programming language A programming language is a system of notation for writing computer programs. Most programming languages are text-based formal languages, but they may also be graphical. They are ...
supports intersection types, improving expressiveness of the type system and reducing potential class hierarchy size, demonstrated as follows. The following program code defines the classes , , and that each have a method returning an object of either type , , or . Additionally, the functions and require arguments of type and , respectively. class Egg class Milk //produces eggs class Chicken //produces milk class Cow //produces a random number class RandomNumberGenerator //requires an egg function eatEgg(egg: Egg) //requires milk function drinkMilk(milk: Milk) The following program code defines the ad hoc polymorphic function that invokes the member function of the given object . The function has ''two'' type annotations, namely and , connected via the intersection type constructor . Specifically, when applied to an argument of type returns an object of type type , and when applied to an argument of type returns an object of type type . Ideally, should not be applicable to any object having (possibly by chance) a method. //given a chicken, produces an egg; given a cow, produces milk let animalToFood: ((_: Chicken) => Egg) & ((_: Cow) => Milk) = function (animal: any) ; Finally, the following program code demonstrates
type safe In computer science, type safety and type soundness are the extent to which a programming language discourages or prevents type errors. Type safety is sometimes alternatively considered to be a property of facilities of a computer language; that is ...
use of the above definitions. var chicken = new Chicken(); var cow = new Cow(); var randomNumberGenerator = new RandomNumberGenerator(); console.log(chicken.produce()); //Egg console.log(cow.produce()); //Milk console.log(randomNumberGenerator.produce()); //0.2626353555444987 console.log(animalToFood(chicken)); //Egg console.log(animalToFood(cow)); //Milk //console.log(animalToFood(randomNumberGenerator)); //ERROR: Argument of type 'RandomNumberGenerator' is not assignable to parameter of type 'Cow' console.log(eatEgg(animalToFood(chicken))); //I ate an egg. //console.log(eatEgg(animalToFood(cow))); //ERROR: Argument of type 'Milk' is not assignable to parameter of type 'Egg' console.log(drinkMilk(animalToFood(cow))); //I drank some milk. //console.log(drinkMilk(animalToFood(chicken))); //ERROR: Argument of type 'Egg' is not assignable to parameter of type 'Milk' The above program code has the following properties: * Lines 1–3 create objects , , and of their respective type. * Lines 5–7 print for the previously created objects the respective results (provided as comments) when invoking . * Line 9 (resp. 10) demonstrates type safe use of the method applied to (resp. ). * Line 11, if uncommented, would result in a type error at compile time. Although the ''implementation'' of could invoke the method of , the ''type annotation'' of disallows it. This is in accordance with the intended meaning of . * Line 13 (resp. 15) demonstrates that applying to (resp. ) results in an object of type (resp. ). * Line 14 (resp. 16) demonstrates that applying to (resp. ) does not result in an object of type (resp. ). Therefore, if uncommented, line 14 (resp. 16) would result in a type error at compile time.


Comparison to inheritance

The above minimalist example can be realized using
inheritance Inheritance is the practice of receiving private property, Title (property), titles, debts, entitlements, Privilege (law), privileges, rights, and Law of obligations, obligations upon the death of an individual. The rules of inheritance differ ...
, for instance by deriving the classes and from a base class . However, in a larger setting, this could be disadvantageous. Introducing new classes into a class hierarchy is not necessarily justified for
cross-cutting concern In aspect-oriented software development, cross-cutting concerns are aspects of a program that affect several modules, without the possibility of being encapsulated in any of them. These concerns often cannot be cleanly decomposed from the rest o ...
s, or maybe outright impossible, for example when using an external library. Imaginably, the above example could be extended with the following classes: * a class that does not have a method; * a class that has a method returning ; * a class that has a method, which can be used only once, returning . This may require additional classes (or interfaces) specifying whether a produce method is available, whether the produce method returns food, and whether the produce method can be used repeatedly. Overall, this may pollute the class hierarchy.


Comparison to duck typing

The above minimalist example already shows that
duck typing Duck typing in computer programming is an application of the duck test—"If it walks like a duck and it quacks like a duck, then it must be a duck"—to determine whether an object can be used for a particular purpose. With nominative t ...
is less suited to realize the given scenario. While the class contains a method, the object should not be a valid argument for . The above example can be realized using duck typing, for instance by introducing a new field to the classes and signifying that objects of corresponding type are valid arguments for . However, this would not only increase the size of the respective classes (especially with the introduction of more methods similar to ), but is also a non-local approach with respect to .


Comparison to function overloading

The above example can be realized using
function overloading In some programming languages, function overloading or method overloading is the ability to create multiple functions of the same name with different implementations. Calls to an overloaded function will run a specific implementation of that f ...
, for instance by implementing two methods and . In TypeScript, such a solution is almost identical to the provided example. Other programming languages, such as
Java Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's List ...
, require distinct implementations of the overloaded method. This may lead to either
code duplication In computer programming, duplicate code is a sequence of source code that occurs more than once, either within a program or across different programs owned or maintained by the same entity. Duplicate code is generally considered undesirable for a n ...
or
boilerplate code In computer programming, boilerplate code, or simply boilerplate, are sections of code that are repeated in multiple places with little to no variation. When using languages that are considered ''verbose'', the programmer must write a lot of boile ...
.


Comparison to the visitor pattern

The above example can be realized using the
visitor pattern In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to ...
. It would require each animal class to implement an method accepting an object implementing the interface (adding non-local
boilerplate code In computer programming, boilerplate code, or simply boilerplate, are sections of code that are repeated in multiple places with little to no variation. When using languages that are considered ''verbose'', the programmer must write a lot of boile ...
). The function would be realized as the method of an implementation of . Unfortunately, the connection between the input type ( or ) and the result type ( or ) would be difficult to represent.


Limitations

On the one hand, intersection types ''can'' be used to locally annotate different types to a function without introducing new classes (or interfaces) to the class hierarchy. On the other hand, this approach ''requires'' all possible argument types and result types to be specified explicitly. If the behavior of a function can be specified precisely by either a unified interface,
parametric polymorphism In programming languages and type theory, parametric polymorphism allows a single piece of code to be given a "generic" type, using variables in place of actual types, and then instantiated with particular types as needed. Parametrically polymorph ...
, or
duck typing Duck typing in computer programming is an application of the duck test—"If it walks like a duck and it quacks like a duck, then it must be a duck"—to determine whether an object can be used for a particular purpose. With nominative t ...
, then the verbose nature of intersection types is unfavorable. Therefore, intersection types should be considered complementary to existing specification methods.


Dependent intersection type

A dependent intersection type, denoted (x : \sigma) \cap \tau, is a
dependent type In computer science and logic, a dependent type is a type whose definition depends on a value. It is an overlapping feature of type theory and type systems. In intuitionistic type theory, dependent types are used to encode logic's quantifiers lik ...
in which the type \tau may depend on the term variable x. In particular, if a term M has the dependent intersection type (x : \sigma) \cap \tau, then the term M has ''both'' the type \sigma and the type \tau := M/math>, where \tau := M/math> is the type which results from replacing all occurrences of the term variable x in \tau by the term M.


Scala example

Scala supports type declarations as object members. This allows a type of an object member to depend on the value of another member, which is called a ''path-dependent type''. For example, the following program text defines a Scala trait Witness, which can be used to implement the
singleton pattern In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to a singular instance. One of the well-known "Gang of Four" design patterns, which describe how to solve recurring problems ...
. trait Witness The above trait Witness declares the member T, which can be assigned a ''type'' as its value, and the member value, which can be assigned a value of type T. The following program text defines an object booleanWitness as instance of the above trait Witness . The object booleanWitness defines the type T as Boolean and the value value as true. For example, executing System.out.println(booleanWitness.value) prints true on the console. object booleanWitness extends Witness Let \langle \textsf : \sigma \rangle be the type (specifically, a
record type Record type is a family of typefaces designed to allow medieval manuscripts (specifically those from England) to be published as near-facsimiles of the originals. The typefaces include many special characters intended to replicate the various s ...
) of objects having the member \textsf of type \sigma. In the above example, the object booleanWitness can be assigned the dependent intersection type (x : \langle \textsf : \text \rangle) \cap \langle \textsf : x.\textsf \rangle. The reasoning is as follows. The object booleanWitness has the member T that is assigned the type Boolean as its value. Since Boolean is a type, the object booleanWitness has the type \langle \textsf : \text \rangle. Additionally, the object booleanWitness has the member value that is assigned the value true of type Boolean. Since the value of booleanWitness.T is Boolean, the object booleanWitness has the type \langle \textsf : \textsf \rangle. Overall, the object booleanWitness has the intersection type \langle \textsf : \text \rangle \cap \langle \textsf : \textsf \rangle. Therefore, presenting self-reference as dependency, the object booleanWitness has the dependent intersection type (x : \langle \textsf : \text \rangle) \cap \langle \textsf : x.\textsf \rangle. Alternatively, the above minimalistic example can be described using ''dependent record types''. In comparison to dependent intersection types, dependent record types constitute a strictly more specialized type theoretic concept.


Intersection of a type family

An intersection of a type family, denoted \bigcap_ \tau, is a
dependent type In computer science and logic, a dependent type is a type whose definition depends on a value. It is an overlapping feature of type theory and type systems. In intuitionistic type theory, dependent types are used to encode logic's quantifiers lik ...
in which the type \tau may depend on the term variable x. In particular, if a term M has the type \bigcap_ \tau, then for ''each'' term N of type \sigma, the term M has the type \tau := N/math>. This notion is also called ''implicit Pi type'', observing that the argument N is not kept at term level.


Comparison of languages with intersection types


References

{{Data types Type theory Type systems Data types Composite data types Polymorphism (computer science) TypeScript