============================
Referencing Other Packages
============================

----------------
 "with" Clause
----------------

* When package :ada:`User` needs access to package :ada:`Designer`, it uses a :ada:`with` clause

   - Specify the library units that :ada:`User` depends upon
   - The "context" in which the unit is compiled
   - :ada:`User`'s code gets **visibility** over :ada:`Designer`'s specification


**Syntax**

.. container:: source_include 100_packages/syntax.bnf :start-after:with_clause_begin :end-before:with_clause_end :code:bnf

**Example**

.. code:: Ada

   with Designer; -- dependency
   procedure User is

----------------------------
Referencing Exported Items
----------------------------

* Achieved via "dot notation"
* Package Specification

  .. code:: Ada

     package Float_Stack is
       procedure Push (X : in Float);
       procedure Pop (X : out Float);
     end Float_Stack;

* Package Reference

  .. code:: Ada

     with Float_Stack;
     procedure Test is
        X : Float;
     begin
        Float_Stack.Pop (X);
        Float_Stack.Push (12.0);
        ...

----------------------
"with" Clause Syntax
----------------------

* A library unit is a package or subprogram that is not nested within another unit

   - Typically in its own file(s)

     - e.g. for package :ada:`Test`, GNAT defaults to expect the spec in :filename:`test.ads` and body in :filename:`test.adb`)

* Only library units may appear in a :ada:`with` statement

   * Can be a package or a standalone subprogram

* Due to the :ada:`with` syntax, library units cannot be overloaded

   - If overloading allowed, which `P` would :ada:`with P;` refer to?

----------------
What To Import
----------------

* Need only name direct dependencies

   - Those actually referenced in the corresponding unit

* Will not cause compilation of referenced units

   - Unlike "include directives" of some languages

.. code:: Ada

   package A is
     type Something is ...
   end A;

   with A;
   package B is
     type Something is record
       Component : A.Something;
     end record;
   end B;

   with B; -- no "with" of A
   procedure Foo is
     X : B.Something;
   begin
     X.Component := ...

