comp.lang.ada
 help / color / mirror / Atom feed
From: "John G. Volan" <johnvolan@sprintmail.com>
Subject: Ada95 packages, C++ namespaces, & circular dependencies
Date: 1997/06/04
Date: 1997-06-04T00:00:00+00:00	[thread overview]
Message-ID: <33964782.1DEC@sprintmail.com> (raw)
In-Reply-To: 33937420.4458@sprintmail.com


David Weller wrote:
> 
> John,
> here's an interesting thought.  WIth the advent of namespaces in C++,
> which generally mimic packages (the "old" non-child type a la Ada83),
                                  ^^^^^^^^^^^^^^^^^^^^^^^^
                                  See [***] NOTE: below

> what is the result of mutual dependencies on classes in separate
> namespaces?  I wonder if that has an effect in C++?  I don't know if
> you've pondered that one or not.

-----

I'm cross-posting this to comp.lang.c++, because it's pertinent, and
because I would like to get some confirmation on my understanding of
C++.  For those of you on comp.lang.c++, here's the background on this
thread: I've written up an FAQ concerning an apparent "hole" in the
design of Ada95 known as the "with-ing" problem, which has to do with
circular dependencies between packages. You can find this FAQ at the
following URL:

    http://bluemarble.net/~jvolan/WithingProblem/FAQ.html

You might want to peruse this before reading further.  In particular,
section [5.4] compares proposed Ada0Y solutions for this problem with
the current situation in C++

    http://bluemarble.net/~jvolan/WithingProblem/FAQ.html#cplusplus
    
Please do not use this thread as an excuse for Ada-bashing. In comparing
Ada95 with C++, I've tried to be fair to both languages. Please extend
the same courtesy.

-----    

Here's my response to David Weller:

It's only been in the past couple days that I've managed to find the URL
for the online C++ draft standard working paper

    http://www.maths.warwick.ac.uk/c++/pub/wp/html/cd2/

and read the straight dope on namespaces. From what I can glean from the
verbiage there, it doesn't look like namespaces introduce any new
problems for C++ with regard to separate encapsulation/mutual
dependency.

In fact, to me they seem most reminiscent of Norman Cohen's "package
parts" idea for Ada0Y. It appears that you can scatter as many sections
of the same namespace as you want through any given C++ compilation. 
So, for instance, you could have the following (but see the [**]
DISCLAIMER below).

  // let this be all in one file, or perhaps all in
  // one output from the C++ preprocessor:

  namespace Doctors {  // initial definition of namespace
    class Doctor;      // forward class declaration
  }

  namespace Patients { // initial definition of namespace
    class Patient;     // forward class declaration
  }
  ...

  namespace Doctors {  // extension providing "interface"
    class Doctor {     // full class declaration
      ...
    public:
      ...
      void treatPatient (Patients::Patient& patient);
      void billPatient  (Patients::Patient& patient);
      ...
    };
  }

  namespace Patients { // extension providing "interface"
    class Patient {    // full class declaration
      ...
    public:
      ...
      void visitDoctor (Doctors::Doctor& doctor);
      void payDoctor   (Doctors::Doctor& doctor);
      ...
    };
  }
  ...
  //----- See [*] NOTE: below. -----

  namespace Doctors {  // extension providing "implementation"

    // definitions of Doctor member functions:

    void Doctor::billPatient (Patients::Patient& patient) {
      ...
      Doctor& doctor = *this;
      patient.payDoctor (doctor);
    }
    ...
  }

  namespace Patients { // extension providing "implementation"

    // definitions of Patient member functions:

    void Patient::visitDoctor (Doctors::Doctor& doctor) {
      ...
      Patient& patient = *this;
      doctor.treatPatient (patient);
    }
    ...
  }

This arrangement seems a lot like my "package abstracts" proposal (see
section [5.1] of my FAQ, at URL:

    http://bluemarble.net/~jvolan/WithingProblem/FAQ.html#abstracts 

It also appears that namespace sections can be sliced up and scattered
through as many source files as you wish.  Remember that C++ still does
not define any notion of "semantic dependency" between "compilation
units" comparable to Ada's "with" clauses (at least, as near as I can
tell).  All it provides is a mechanism for preprocessor textual
inclusion between source files.  It's up to the programmer to make sure
that the source files that are #included into a given compilation get
assembled into some kind of meaningful order within the preprocessor,
before being fed into the compiler proper. And it's still up to the
programmer to specify what object files go into a link, and to ensure 
that those object files are semantically consistent with each other--or
at least they are all based on the same versions of the same #included
source files (usually with assistance from some tool outside the
language, e.g. "make").

But this allows a C++ programmer to do something like the following:

  ////////////////////////////////////////////////////////////
  // Doctors_forward.h
  ////////////////////////////////////////////////////////////
  #ifndef _DOCTORS_FORWARD_H
  #define _DOCTORS_FORWARD_H
  namespace Doctors {      // initial definition of namespace
    class Doctor;          // forward class declaration
  }
  #endif  _DOCTORS_FORWARD_H

  ////////////////////////////////////////////////////////////
  // Doctors.h
  ////////////////////////////////////////////////////////////
  #ifndef _DOCTORS_H
  #define _DOCTORS_H
  #include "Doctors_forward.h"
  #include "Patients_forward.h"
  ...                      // other *_forward.h inclusions
  namespace Doctors {      // extension providing "interface"
    class Doctor {         // full class declaration
      ...
    public:
      ...
      void treatPatient (Patients::Patient& patient);
      void billPatient  (Patients::Patient& patient);
      ...
    };
  }
  #endif  _DOCTORS_H

  ////////////////////////////////////////////////////////////
  // Doctors.cc
  ////////////////////////////////////////////////////////////
  #include "Doctors.h"
  #include "Patients.h"
  ...                  // other *.h inclusions
  namespace Doctors {  // extension providing "implementation"

    // definitions of Doctor member functions:

    void Doctor::billPatient (Patients::Patient& patient) {
      ...
      Doctor& doctor = *this;
      patient.payDoctor (doctor);
    }
    ...
  }

The source files for the sections of the Patients namespace would be
similar.

[*] NOTE: The sequence of #include directives in the Doctors.cc file

  #include "Doctors.h"
  #include "Patients.h"

when textually expanded in the C++ preprocessor, would generate the
interleaving of Doctors and Patients namespace sections I showed above,
up to the "See [*] NOTE:" comment.  The sequence of #includes that might
appear in the Patients.cc file

  #include "Patients.h"
  #include "Doctors.h"

would generate a similar interleaving, but with the corresponding
Doctors and Patients sections interchanged.  Both interleavings should
compile successfully. It just goes to show you: It really doesn't matter
whether the chicken comes first, or the egg! :-)

[**] DISCLAIMER:  The Doctors/Patients namespace example above is a bit
contrived.  I'm not sure you'd want to bother wrapping e.g. a "Doctor"
class inside a "Doctors" namespace, since the class itself, being a kind
of module as well as a type, already provides a level of scope analogous
to a "Doctors" package containing a "Doctor_Type". A more realistic
scenario might be to use a namespace for a subsystem, with various
classes nested inside it (but possibly scattered over many source
files).  For instance, you might have a "Providers" subsystem
implemented as a namespace, with "Doctor" as one of the classes inside
it; likewise, a "Consumers" subsystem as a namespace, with "Patient" as
one of the classes inside it.)

[***] NOTE: David, I think you may be underestimating what namespaces
can do. Because you are allowed to extend a namespace as many times as
you like within a given compilation, and because the C++ preprocessor
can stitch together a compilation from any arbitrary set of source file
inclusions, it looks like namespaces will in fact be able to mimic the
functionality of Ada95 child hierarchies after all.

------------------------------------------------------------------------
Internet.Usenet.Put_Signature 
  (Name       => "John G. Volan",
   Employer   => "Texas Instruments Advanced C3I Systems, San Jose, CA",
   Work_Email => "johnv@ti.com",
   Home_Email => "johnvolan@sprintmail.com",
   Slogan     => "Ada95: World's *FIRST* International-Standard OOPL",
   Disclaimer => "My employer never defined these opinions, so using" & 
                 "them would be totally erroneous ... or is that"     &
                 "just nondeterministic behavior now? :-) ");
------------------------------------------------------------------------




  reply	other threads:[~1997-06-04  0:00 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-05-24  0:00 circular unit dependency jdlopez
1997-05-24  0:00 ` Michael F Brenner
1997-05-25  0:00 ` Jon S Anthony
1997-05-26  0:00   ` John G. Volan
1997-05-26  0:00     ` Fergus Henderson
1997-05-27  0:00     ` Jon S Anthony
1997-06-02  0:00     ` Ada95=>Ada0Y Process? [was: circular unit dependency] John G. Volan
1997-06-04  0:00       ` John G. Volan [this message]
1997-06-07  0:00       ` Robert Dewar
1997-06-07  0:00         ` John G. Volan
1997-06-08  0:00           ` Robert Dewar
1997-06-08  0:00             ` John G. Volan
1997-06-07  0:00         ` John G. Volan
1997-05-28  0:00 ` circular unit dependency John G. Volan
1997-06-01  0:00   ` John G. Volan
1997-05-31  0:00 ` Kevin Cline
1997-05-31  0:00   ` John G. Volan
1997-06-01  0:00     ` Kevin Cline
1997-06-01  0:00       ` John G. Volan
1997-06-02  0:00     ` John G. Volan
1997-05-31  0:00   ` Matthew Heaney
     [not found]     ` <33932F31.4399@sprintmail.com>
1997-06-02  0:00       ` Matthew Heaney
1997-06-03  0:00         ` John G. Volan
1997-06-05  0:00           ` Matthew Heaney
1997-06-05  0:00             ` John G. Volan
1997-06-06  0:00             ` Stephen Schmid
1997-06-03  0:00         ` W. Wesley Groleau (Wes)
1997-06-03  0:00           ` John G. Volan
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox