comp.lang.ada
 help / color / mirror / Atom feed
From: "John G. Volan" <johnvolan@sprintmail.com>
Subject: Re: circular unit dependency
Date: 1997/06/03
Date: 1997-06-03T00:00:00+00:00	[thread overview]
Message-ID: <3393D0E1.AC9@sprintmail.com> (raw)
In-Reply-To: mheaney-ya023680000206972122410001@news.ni.net


Matthew Heaney wrote:
> 
> Oh, yes, I realize the CORBA's IDL allows mutual dependency of modules, but
> this a really dumb thing to do.
> 
> But we're comparing apples and oranges.  In IDL, an module is a type.  That
> IDL "modules" are allowed to be mutually dependent means that "types" are
> allowed to by mutually dependent.  So be it.  To have mutually dependent
> types in Ada, just put them together in the same package, as you yourself
> stated.

Nope. I admitted that there was a certain subset of mutually dependent
types that are very highly coupled and so belong in the same package
with each other, primarily because they must share implementation
details. But I also defended the fact that this subset did not
constitute the entire set of mutually-dependent types.  There are a
great many cases where the types are very loosely coupled and fall into
a client/supplier pattern.  It is unwise to co-encapsulate in this kind
of situation, because of the transitivity effect and because the types
are not intended to share implementation details--they present
abstractions to each other. If you can't see that, well, you can't see
that, too bad.

> The guys that wrote the Ada IDL binding made a common mistake: they mapped
> an IDL module (type) to an Ada package.  This was a poor choice, and
> suffers exactly from the problem you describe: how do you have mutual
> dependencies now, across package boundaries?  This is an IDL-to-Ada mapping
> problem, not a problem with Ada the language.  The authors of the mapping
> made a mistake.   What they should have done was to map an IDL type to an
> Ada type.

They did that. :-) But they also recognized that an IDL _interface_
(catch that: _interface_, not _type_) is an _abstraction_ that
_encapsulates_ distributed object services.  This concept _includes_ the
notion of modularity, as well as the notion of data abstraction.

It was not a poor choice, it was a necessary one. The problem is with
Ada, and it either needs a workaround or a fix.

> But no, they didn't do that, and seemed to have C++ on-the-brain when they
> wrote the mapping document.  

Oh come on.  Ada is the only language I know of that is unable to fully
modularize object classes in the most general case. If you're trying to
make your point by belittling C++, you're going to have to take on
Eiffel, Smalltalk, CLOS, Java, and in short the whole wide OO world...

> If the developers of that binding were
> thinking in Ada,  

What is this "thinking in Ada" thing?  Sounds like religious bigotry to
me, nothing to do with the design principles of Ada.  (I'm one of the
biggest Ada advocates around, but I'm not so blinded by zeal that I
can't see the warts, the places where something  was missed that could
have fit naturally into Ada's design principles.)

> using its "a module is not a type" paradigm,

Of course a module is not a type. That's one of the great things about
Ada: The fact that types and packages are orthogonal constructs.  Which
means they can be composed in a variety of ways.  Including a pattern in
which each type is separately encapsulated.  Which is one of many
legitimate design choices.  A _design choice_, which is justified for a
certain set of domains under a certain set of design criteria.  There is
no "one true Ada way."

There are kinds of modules that go beyond object classes. Ada packages
(and especially child hierarchies) are great for that.  But it is a
legitimate option to choose to have object-classes act as base-level
units of modularity.

> then they
> should have realized any binding must detect mutual dependencies across
> types, ...

That's silly. You take something that should be a simple,
straightforward mapping, something that should be easy to build a
mapping-compiler for, and instead superimpose this extra complexity,
requiring the mapping-compiler to do this unnecessary extra analysis and
make an arbitrary distinction between one kind of client and another. 
I'm glad the IDL-to-Ada mapping folks didn't listen to you; the solution
they chose made the job of constructing an IDL-to-Ada compiler _much_
simpler and more orthogonal that they feared it would be.

> ... and properly colocate the mutually dependent types together.

Make that: Improperly colocate (because the types don't need access to
each other's implementation details).  And make that improperly colocate
_many_ types together -- _all_ your types, in the worst case.  How many
times do I have to describe the transitivity effect before the light
dawns?

> Because they failed to do that, they had to solve the mutual dependency
> problem that they themselves created, and so came up with a klunky scheme
> whereby each type designates the other through a pointer to a common
> ancestor.  So we've reduced Ada to the typeless paradigm proffered by
> Smalltalk and Objective-C.

You really don't know what you're talking about.  My generic forwarding
scheme preserves type safety, because it establishes a one-to-one
correspondence between a class and a reference type responsible for
designating that class. It is nothing at all like Smalltalk and
Objective-C.  It is very much like the way Ada does access types:
They're all treated as distinct types by the compiler, but they share a
common underlying implementation.

The common ancestor pointer you criticize is just a hidden
implementation detail -- one possible implementation scheme for those
abstract reference types, but not the only one.  That particular
implementation choice was a convenient one for the IDL-to-Ada folks,
because -- get this -- _they_ _already_ _had_ _a_ _common_ _ancestor_
_type_ _anyway_, for reasons that had nothing to do with mutual
dependency: These are all CORBA distributed object classes, after all.
They're supposed to share common mechanisms and resources that make them
distributed object classes.  Inheriting from a root type that
establishes those resources is a very smart design.

> They also used the horrible convention of naming types "Object," in a
> misguided attempt to "fix" Ada by pretending that a package is a type.
> Well, I have news for you, in Ada a package is not a type, so you better
> get used to it.  

This is supposed to be news to _me_?  Are you kidding me?

> If you don't like that, then you're definately using the
> wrong language, and it does not good for you ... to pine for the language to
> be some other way...

Does this statement have anything to do with engineering, or is it just
religiously based?

> (nor for the maintenance
> programmer unlucky enough to inherit your code)

I feel sorry for the maintenance programmer who's faced with a package
containing a dozen object classes, who has to puzzle out the fact that
each one is only directly collaborating with 2-4 others, and not _all_
the others. Who also has to somehow magically realize that, despite
their being in the same package, they all carefully refrain from
touching each other's private declarations -- and if he doesn't realize
that and starts ignoring the abstractions, poof goes the original
design.  This, because all of the abstraction boundaries that should
have been there, weren't, because of this co-encapsulation dogma.

This dogma is so ironic, because one of the design principles behind Ada
was that different abstractions would be encapsulated into different
packages, and the collaborations between the abstractions would be
obvious, because you'd see them in the "with" clauses.  All of that is
lost when you co-encapsulate.

> To try to separate mutually dependent types across
> package boundaries will only obfuscate the code, as evidenced by the
> pointer-to-common-ancestor technique, which wouldn't have been necessary
> had they done the mapping properly.

How can the pointer-to-common-ancestor obfuscate, when it is hidden
inside an abstraction, and the abstraction presents exactly the proper
concept: A reference type that designates one and only one object-class.

I find it far more obfuscatory to take a object-oriented analysis and
design model that has nice, clean abstraction boundaries and then
dissolve those abstractions into package soup!
 
> Would allowing dependencies across package boundaries be better?  Sure!
> I'm all for it.  But that's a far different thing from saying that Ada has
> some kind of "with'ing problem" (which it does not).

Make up your mind: How can you be all for something that you claim is
totally unnecessary?

> Somehow I manage to
> program every day in Ada, thank you very much, in spite of Ada's
> "difficiencies."

I guess you meant "deficiencies". (Hey, if you're going to nit-pick over
word usage...)

Perhaps you just haven't worked on the kinds of problems where this
issue arises.  There are a lot of ways to skirt the issue (see section 3
of my FAQ for a few).  But there are just some domains where this
pattern is the most straightforward one, the one that preserves the most
abstractions.

------------------------------------------------------------------------
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-03  0:00 UTC|newest]

Thread overview: 40+ 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       ` Ada95 packages, C++ namespaces, & circular dependencies John G. Volan
1997-06-07  0:00       ` Ada95=>Ada0Y Process? [was: circular unit dependency] 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   ` Matthew Heaney
     [not found]     ` <33932F31.4399@sprintmail.com>
1997-06-02  0:00       ` Matthew Heaney
1997-06-03  0:00         ` John G. Volan [this message]
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
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
  -- strict thread matches above, loose matches on Subject: below --
1998-05-26  0:00 Brendan Reville
2003-05-23  9:20 Mirko Aigner
2003-05-23 11:37 ` Jeffrey Creem
2003-05-23 12:12   ` David C. Hoos
2003-05-23 18:08 ` Stephen Leake
2003-05-24 22:12   ` Robert I. Eachus
2003-05-26  8:05   ` Mirko Aigner
2005-01-04 18:31 R
2005-01-04 23:45 ` Randy Brukardt
2005-01-05  8:35   ` Martin Krischik
2005-01-05  8:55     ` Duncan Sands
2005-01-05  0:26 ` Stephen Leake
replies disabled

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