Content deleted Content added
change paradigms template to navbox (see Template talk:Programming paradigms#too long) |
No edit summary |
||
Line 123:
The specification of a generic package:
<syntaxhighlight lang="
generic
Max_Size : Natural; -- a generic formal value
Line 159:
Using an instance of a generic package:
<syntaxhighlight lang="
type Document_Type is record
Contents : Ada.Strings.Unbounded.Unbounded_String;
Line 177:
The language syntax allows precise specification of constraints on generic formal parameters. For example, it is possible to specify that a generic formal type will only accept a modular type as the actual. It is also possible to express constraints ''between'' generic formal parameters; for example:
<syntaxhighlight lang="
generic
type Index_Type is (<>); -- must be a discrete type
Line 204:
There are many kinds of templates, the most common being function templates and class templates. A ''function template'' is a pattern for creating ordinary functions based upon the parameterizing types supplied when instantiated. For example, the C++ Standard Template Library contains the function template <code>max(x, y)</code> that creates functions that return either ''x'' or ''y,'' whichever is larger. <code>max()</code> could be defined like this:
<syntaxhighlight lang="
template<typename T>
T max(T x, T y) {
Line 213:
''Specializations'' of this function template, instantiations with specific types, can be called just like an ordinary function:
<syntaxhighlight lang="
std::cout << max(3, 7); // Outputs 7.
</syntaxhighlight>
Line 219:
The compiler examines the arguments used to call <code>max</code> and determines that this is a call to <code>max(int, int)</code>. It then instantiates a version of the function where the parameterizing type <code>T</code> is <code>int</code>, making the equivalent of the following function:
<syntaxhighlight lang="
int max(int x, int y) {
return x < y ? y : x;
Line 241:
Some uses of templates, such as the <code>max()</code> function, were previously filled by function-like [[preprocessor]] [[Macro (computer science)|macros]] (a legacy of the [[C (programming language)|C]] language). For example, here is a possible implementation of such macro:
<syntaxhighlight lang="
#define max(a,b) ((a) < (b) ? (b) : (a))
</syntaxhighlight>
Line 274:
For example, an input [[Range (computer programming)#Range as an alternative to iterator|range]] is defined as any type that satisfies the checks performed by <code>isInputRange</code>, which is defined as follows:
<syntaxhighlight lang="
template isInputRange(R)
{
Line 290:
A function that accepts only input ranges can then use the above template in a template constraint:
<syntaxhighlight lang="
auto fun(Range)(Range range)
if (isInputRange!Range)
Line 314:
For example, given a function that takes a string containing an HTML template and returns equivalent D source code, it is possible to use it in the following way:
<syntaxhighlight lang="
// Import the contents of example.htt as a string manifest constant.
enum htmlTemplate = import("example.htt");
Line 331:
Generic classes are declared with their class name and a list of one or more ''formal generic parameters''. In the following code, class <code lang=Eiffel>LIST</code> has one formal generic parameter <code lang=Eiffel>G</code>
<syntaxhighlight lang="
class
LIST [G]
Line 347:
The formal generic parameters are placeholders for arbitrary class names that will be supplied when a declaration of the generic class is made, as shown in the two ''generic derivations'' below, where <code lang=Eiffel>ACCOUNT</code> and <code lang=Eiffel>DEPOSIT</code> are other class names. <code lang=Eiffel>ACCOUNT</code> and <code lang=Eiffel>DEPOSIT</code> are considered ''actual generic parameters'' as they provide real class names to substitute for <code lang=Eiffel>G</code> in actual use.
<syntaxhighlight lang="
list_of_accounts: LIST [ACCOUNT]
-- Account list
Line 361:
For the list class shown above, an actual generic parameter substituting for <code lang=Eiffel>G</code> can be any other available class. To constrain the set of classes from which valid actual generic parameters can be chosen, a ''generic constraint'' can be specified. In the declaration of class <code lang=Eiffel>SORTED_LIST</code> below, the generic constraint dictates that any valid actual generic parameter will be a class that inherits from class <code lang=Eiffel>COMPARABLE</code>. The generic constraint ensures that elements of a <code lang=Eiffel>SORTED_LIST</code> can in fact be sorted.
<syntaxhighlight lang="
class
SORTED_LIST [G -> COMPARABLE]
Line 376:
.NET allows six varieties of generic type constraints using the <code>where</code> keyword including restricting generic types to be value types, to be classes, to have constructors, and to implement interfaces.<ref>[https://msdn2.microsoft.com/en-us/library/d5x73970.aspx Constraints on Type Parameters (C# Programming Guide)]</ref> Below is an example with an interface constraint:
<syntaxhighlight lang="
using System;
Line 405:
A notable behavior of static members in a generic .NET class is static member instantiation per run-time type (see example below).
<syntaxhighlight lang="
// A generic class
public class GenTest<T>
{
// A static variable - will be created for each type on reflection
static CountedInstances OnePerType = new CountedInstances();
// a data member
private T
// simple constructor
public GenTest(T
{
}
}
// a class
public class CountedInstances
{
Line 436:
}
</syntaxhighlight>
Line 447:
[[Delphi (software)|Delphi's]] [[Object Pascal]] dialect acquired generics in the Delphi 2007 release, initially only with the (now discontinued) .NET compiler before being added to the native code in the Delphi 2009 release. The semantics and capabilities of Delphi generics are largely modelled on those had by generics in .NET 2.0, though the implementation is by necessity quite different. Here's a more or less direct translation of the first C# example shown above:
<syntaxhighlight lang="
program Sample;
Line 496:
Delphi and Free Pascal example:
<syntaxhighlight lang="
// Delphi style
unit A;
Line 596:
The [[type class]] mechanism of [[Haskell]] supports generic programming. Six of the predefined type classes in Haskell (including <code>Eq</code>, the types that can be compared for equality, and <code>Show</code>, the types whose values can be rendered as strings) have the special property of supporting ''derived instances.'' This means that a programmer defining a new type can state that this type is to be an instance of one of these special type classes, without providing implementations of the class methods as is usually necessary when declaring class instances. All the necessary methods will be "derived" – that is, constructed automatically – based on the structure of the type. For example, the following declaration of a type of [[binary tree]]s states that it is to be an instance of the classes <code>Eq</code> and <code>Show</code>:
<syntaxhighlight lang="
data BinTree a = Leaf a | Node (BinTree a) a (BinTree a)
deriving (Eq, Show)
Line 609:
The flatten function in PolyP is here provided as an example:
<syntaxhighlight lang="
flatten :: Regular d => d a -> [a]
flatten = cata fl
Line 637:
As an example, the equality function in Generic Haskell:<ref>[https://www.cs.uu.nl/research/projects/generic-haskell/compiler/diamond/GHUsersGuide.pdf The Generic Haskell User's Guide]</ref>
<syntaxhighlight lang="
type Eq {[ * ]} t1 t2 = t1 -> t2 -> Bool
type Eq {[ k -> l ]} t1 t2 = forall u1 u2. Eq {[ k ]} u1 u2 -> Eq {[ l ]} (t1 u1) (t2 u2)
|