G.2. Generics: Private VS Box - JulTob/Ada GitHub Wiki

Using private in Generic Type Definitions

When you define a generic type parameter as private, you are specifying that the type must support default initialization and assignment (:=). This is a minimal requirement, ensuring that you can create and assign values of the type but without knowing any other details about its internal structure or supported operations.

generic
   type Item is private;
   procedure Process_Items(A, B: Item);

Allows for writing and reading on the variable.

  • Encapsulation
    • Using private ensures that the internals of Item are hidden from the generic unit. This enforces encapsulation, which is a core aspect of safe and maintainable Ada programming.
  • Operations Allowed
    • You can assign to and from variables of type Item, and you can pass them to and from procedures and functions.
  • Use Case
    • Suitable when the generic procedure or package needs to manipulate data of the generic type but does not need to perform type-specific operations like comparison or arithmetic.

Using <> (Box Notation)

The box notation <> is used when you want to specify that the actual type or operation must be provided at the point of instantiation but do not wish to impose other constraints on it at the point of generic definition. This is particularly useful for operations like comparison, hashing, or ordering, which may not be universally applicable to all possible types.

generic
   type Element is private;
   with function "=" (Left, Right : Element) return Boolean is <>;
   package Container is
      -- Package operations that depend on "=" function for Element
      end Container;
  • Operation Requirement
    • The = function must be supplied when the generic is instantiated. This function is not defined in the generic but is expected to be available so that the package or procedure can use it.
  • Flexibility
    • The actual implementation of the = function can be tailored to the specific needs of the type used to instantiate the generic. This allows the generic to be used with a wide variety of types, as long as they provide this operation.
  • Use Case
    • Ideal for data structures or algorithms that require specific operations (like sorting, searching, etc.) but are otherwise generic in how they manage elements.

Summary

Private

  • Use private when your generic needs to work with any type, but only needs to perform basic operations like assignment. It's like saying, "I don’t care what this is, as long as I can copy it."

<> (Box Notation)

  • Use the box notation when your generic needs to perform specific operations that are not universally applicable. It's like saying, "You must tell me how to perform this specific operation when you use this template."