Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Generic programming
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
====Generics in Ada==== {{unreferenced|section|date=January 2024}} [[Ada (programming language)|Ada]] has had generics since it was first designed in 1977β1980. The [[standard library]] uses generics to provide many services. Ada 2005 adds a comprehensive generic container library to the standard library, which was inspired by C++'s [[Standard Template Library]]. A ''generic unit'' is a package or a subprogram that takes one or more ''generic formal parameters''.<ref>{{Cite web |title=Generic Units |url=https://www.adaic.org/resources/add_content/standards/05rm/html/RM-12.html |access-date=2024-04-25 |website=www.adaic.org}}</ref> A ''generic formal parameter'' is a value, a variable, a constant, a type, a subprogram, or even an instance of another, designated, generic unit. For generic formal types, the syntax distinguishes between discrete, floating-point, fixed-point, access (pointer) types, etc. Some formal parameters can have default values. To ''instantiate'' a generic unit, the programmer passes ''actual'' parameters for each formal. The generic instance then behaves just like any other unit. It is possible to instantiate generic units at [[Run time (program lifecycle phase)|run-time]], for example inside a loop. =====Example===== The specification of a generic package: <syntaxhighlight lang="ada"> generic Max_Size : Natural; -- a generic formal value type Element_Type is private; -- a generic formal type; accepts any nonlimited type package Stacks is type Size_Type is range 0 .. Max_Size; type Stack is limited private; procedure Create (S : out Stack; Initial_Size : in Size_Type := Max_Size); procedure Push (Into : in out Stack; Element : in Element_Type); procedure Pop (From : in out Stack; Element : out Element_Type); Overflow : exception; Underflow : exception; private subtype Index_Type is Size_Type range 1 .. Max_Size; type Vector is array (Index_Type range <>) of Element_Type; type Stack (Allocated_Size : Size_Type := 0) is record Top : Index_Type; Storage : Vector (1 .. Allocated_Size); end record; end Stacks; </syntaxhighlight> Instantiating the generic package: <syntaxhighlight lang="ADA"> type Bookmark_Type is new Natural; -- records a location in the text document we are editing package Bookmark_Stacks is new Stacks (Max_Size => 20, Element_Type => Bookmark_Type); -- Allows the user to jump between recorded locations in a document </syntaxhighlight> Using an instance of a generic package: <syntaxhighlight lang="ada"> type Document_Type is record Contents : Ada.Strings.Unbounded.Unbounded_String; Bookmarks : Bookmark_Stacks.Stack; end record; procedure Edit (Document_Name : in String) is Document : Document_Type; begin -- Initialise the stack of bookmarks: Bookmark_Stacks.Create (S => Document.Bookmarks, Initial_Size => 10); -- Now, open the file Document_Name and read it in... end Edit; </syntaxhighlight> =====Advantages and limits===== 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="ada"> generic type Index_Type is (<>); -- must be a discrete type type Element_Type is private; -- can be any nonlimited type type Array_Type is array (Index_Type range <>) of Element_Type; </syntaxhighlight> In this example, Array_Type is constrained by both Index_Type and Element_Type. When instantiating the unit, the programmer must pass an actual array type that satisfies these constraints. The disadvantage of this fine-grained control is a complicated syntax, but, because all generic formal parameters are completely defined in the specification, the [[compiler]] can instantiate generics without looking at the body of the generic. Unlike C++, Ada does not allow specialised generic instances, and requires that all generics be instantiated explicitly. These rules have several consequences: * the compiler can implement ''shared generics'': the object code for a generic unit can be shared between all instances (unless the programmer requests inlining of subprograms, of course). As further consequences: ** there is no possibility of code bloat (code bloat is common in C++ and requires special care, as explained below). ** it is possible to instantiate generics at run-time, and at compile time, since no new object code is required for a new instance. ** actual objects corresponding to a generic formal object are always considered to be non-static inside the generic; see [[wikibooks:Ada Programming/Generics#Generic formal objects|Generic formal objects]] in the Wikibook for details and consequences. * all instances of a generic being exactly the same, it is easier to review and understand programs written by others; there are no "special cases" to take into account. * all instantiations being explicit, there are no hidden instantiations that might make it difficult to understand the program. * Ada does not permit arbitrary computation at compile time, because operations on generic arguments are performed at runtime.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)