Constrained genericity: Difference between revisions

Content added Content deleted
(Removed assertion that this language features applies only to statically typed languages. (see J implementation for counter example.))
(→‎{{header|Ada}}: I think this solves the issue)
Line 6: Line 6:


=={{header|Ada}}==
=={{header|Ada}}==

{{incorrect|Ada|This doesn't create a generic type FoodBox, but a non-generic type in which all objects derived from Food can be stored (the example code demonstrates it: Instead of a foodbox only for bananas and another only for tomatoes, one can put bananas and tomatoes into the same food box).}}
Ada allows various constraints to be specified in parameters of a generics. A formal type constrained to be derived from certain base is one of them:
Ada allows various constraints to be specified in parameters of generics. A formal type constrained to be derived from certain base is one of them:
<lang ada>with Ada.Containers.Indefinite_Vectors;
<lang ada>with Ada.Containers.Indefinite_Vectors;


Line 14: Line 14:
procedure Eat (Object : in out Food) is abstract;
procedure Eat (Object : in out Food) is abstract;


end Nutrition;
package Food_Boxes is

with Ada.Containers;
with Nutrition;

generic
type New_Food is new Nutrition.Food;
package Food_Boxes is

package Food_Vectors is
new Ada.Containers.Indefinite_Vectors
new Ada.Containers.Indefinite_Vectors
( Index_Type => Positive,
( Index_Type => Positive,
Element_Type => Food'Class
Element_Type => New_Food
);
);

subtype Food_Box is Food_Boxes.Vector;
subtype Food_Box is Food_Vectors.Vector;
end Nutrition;</lang>

The package Nutrition defines an interface of an eatable object, that is, the procedure Eat. Then a container package is instantiated with the elements to be of the class Food. I.e. the elements can be only the members of the class Food. Example of use:
end Food_Boxes;
</lang>
The package Nutrition defines an interface of an eatable object, that is, the procedure Eat. Then a generic container package is defined with the elements to be of some type derived from Food. Example of use:
<lang ada>type Banana is new Food with null record;
<lang ada>type Banana is new Food with null record;
overriding procedure Eat (Object : in out Banana) is null;
overriding procedure Eat (Object : in out Banana) is null;
package Banana_Box is new Food_Boxes (Banana);


type Tomato is new Food with null record;
type Tomato is new Food with null record;
overriding procedure Eat (Object : in out Tomato) is null;</lang>
overriding procedure Eat (Object : in out Tomato) is null;
package Tomato_Box is new Tomato_Boxes (Tomato);
We have declared Banana and Tomato as a Food.
-- We have declared Banana and Tomato as a Food.
<lang ada> Lunch_Box : Food_Box;
</lang>
begin
The Tomato_Box can only contain tomatoes; the Banana_Box can only contain bananas. You can only create boxes of eatable objects.
Lunch_Box.Append (Banana'(null record));
Lunch_Box.Append (Banana'(null record));
Lunch_Box.Append (Tomato'(null record));</lang>
The lunch box contains two banana and one tomato.


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==