From: "Robert I. Eachus" <rieachus@comcast.net>
Subject: Re: Reprise: 'in out' parameters for functions
Date: Fri, 16 Apr 2004 01:40:01 -0400
Date: 2004-04-16T01:40:01-04:00 [thread overview]
Message-ID: <VvadnXNuIcYs7OLdRVn-hg@comcast.com> (raw)
In-Reply-To: <5ad0dd8a.0404151752.4f598e1a@posting.google.com>
Wojtek Narczynski wrote:
> I had in mind implementing it without the need to resort to
> abstraction inversion, which I understand as -for example-
> implementing semaphores over protected objects, which are implemented
> over semaphores.
Protected objects _may_ be implemented using semaphores, or mutexes, or
counters, or any viable atomic action. But when you are programming in
Ada, you have to take the tasking model, complex as it seems, as the
fundamental primitive for concurrency. Protected objects were added to
Ada 9X to eliminate some of the baggage that most implementations of Ada
tasking carried. And to some extent they did just that. But if I need
fast semaphores, I use a semaphore abstraction, then I try various
implementations of the abstraction to find one which has the performance
I need. If implementing a semaphore portably as a protected object
works? Done.
> Yes, I should probably have dropped protected type in favor of raw
> semaphores.
Protected objects are a very useful model for a lot of jobs that require
management of concurrency. But it is a characteristic of protected
objects that they manage _their_own_ concurrency, and nothing else. As
long as that model fits what you are doing, great protected objects have
great advantages over other techniques, such as semaphores.
But there are two important points. First you _must_ as part of your
analysis of the problem domain identify the objects that need to be
managed. For lists and trees, two of the examples you mentioned, what
usually needs to be managed is the list, or the tree:
protected type List is
procedure Append(E: in Element);
procedure Prepend(E: in Element);
...
function Is_Empty return Boolean;
function Length return Natural;
private
...
end List;
Should you expect to find a ready made implementation that meets your
needs? Possibly. But you almost certainly won't find it by looking for
libraries of protected objects. The usual in Ada is to provide a
generic package abstraction where the protected object is hidden from
the user's sight. This allows it to "reuse" the interface of a List
that doesn't need protection from concurrent access. In fact, one of
the changes in Ada 95 was intended to make it easier to 'hide' such a
protected type in the body of a (generic) package.
To go back to the example that sparked the discussion, it is not that
difficult to create a protected type which protects an array of
counters. It then seems natural to have both a set of atomic operations
on a single counter and on a set of counters:
type Index is (<>);
generic package Counters is
type Set is array (Index) of Boolean;
type Count_Array is (Index range <>) of Integer;
protected type Counters is
procedure Reset(I: Index);
procedure Reset(S: Set);
procedure Reset; -- Zero all counters.
function Count(I: Index) return Integer;
function Count(S: Set) return Count_Array;
function Count return Count_Array;
--return a snapshot of all counts
private
...
end Counters;
Now you may think that this is an abstraction inversion, but I don't.
That is really a comment on thinking Ada. Even with Ada 83, it was
_hard_ to correctly identify the 'right' objects to make the rest of the
project easy, and Ada 95 has made those choices much harder. But the
way it has done that is by making the object calculus much more powerful.
I used to have a fully worked out example that demonstrated the issue.
It was a simulation of a barber shop, with multiple chairs and barbers,
customers who decided to return later if there were too many other
customers waiting, and so on. But none of that was the point of the
example. There was a simple elegant object-oriented solution. The
insight you needed to find it though, was that the key objects were the
haircuts!
You could also probably come up with just as clean a model if you made
the customers the key objects, but somehow _trying_ to do that leads you
astray. If a parent comes into the barber shop with a child, who is the
customer? Much easier to get it right, if you are thinking that a
father comes into the barber shop to get _haircuts_ for both himself and
his son, or only his son, or whatever.
There are lots of ways to identify the potential objects in a program.
Grady Booch's method of describing the problem space and underlining all
the nouns is probably as good as any. But that is where the hard work
begins. As in the barber shop example, there is some minimal set of
objects that need to be modelled, or perhaps a better way to say that is
that there is a minimal set of expensive objects that does the job.
What makes objects expensive? It can be storage space, allocation and
deallocation, active state, or some combination of the above. But you
often don't know what cost function for the project will be at that
stage of the analysis. You have to try strawmen, see which project
constraints bind hardest, then start looking for opportunties to trade
one resource for another. Sometimes, as in the barber shop example,
there will be one elegant model which minimizes the cost in all
dimensions. Other times, the engineering tradeoffs need to be decided
before you can actually start coding.
--
Robert I. Eachus
"The terrorist enemy holds no territory, defends no population, is
unconstrained by rules of warfare, and respects no law of morality. Such
an enemy cannot be deterred, contained, appeased or negotiated with. It
can only be destroyed--and that, ladies and gentlemen, is the business
at hand." -- Dick Cheney
next prev parent reply other threads:[~2004-04-16 5:40 UTC|newest]
Thread overview: 90+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <u4qrv5hwr.fsf@acm.org>
2004-04-08 17:19 ` Reprise: 'in out' parameters for functions Alexander E. Kopilovich
[not found] ` <bRecOT0TxF@VB1162.spb.edu>
2004-04-08 23:46 ` Stephen Leake
2004-04-09 9:23 ` Florian Weimer
2004-04-09 10:04 ` Dmitry A. Kazakov
2004-04-09 11:23 ` Martin Krischik
2004-04-09 12:44 ` Dmitry A. Kazakov
2004-04-09 22:48 ` Randy Brukardt
2004-04-14 14:40 ` Robert I. Eachus
2004-04-14 21:20 ` Randy Brukardt
2004-04-09 22:47 ` Florian Weimer
2004-04-10 10:49 ` Dmitry A. Kazakov
2004-04-10 11:11 ` Florian Weimer
2004-04-10 13:26 ` Dmitry A. Kazakov
2004-04-10 20:50 ` Georg Bauhaus
2004-04-11 10:31 ` Dmitry A. Kazakov
2004-04-09 11:27 ` Stephen Leake
2004-04-09 22:46 ` Randy Brukardt
2004-04-09 13:12 ` Wojtek Narczynski
2004-04-09 15:48 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Jacob Sparre Andersen
2004-04-10 13:07 ` Wojtek Narczynski
2004-04-10 13:52 ` Jacob Sparre Andersen
2004-04-11 2:45 ` Hyman Rosen
2004-04-11 10:14 ` Expressing physical units Jacob Sparre Andersen
2004-04-11 16:05 ` Hyman Rosen
2004-04-12 6:58 ` Expressing physical units (Was: Reprise: 'in out' parameters for functions) Russ
2004-04-12 10:29 ` Dmitry A. Kazakov
2004-04-13 6:52 ` Russ
2004-04-13 10:55 ` Dmitry A. Kazakov
2004-04-14 4:50 ` Hyman Rosen
2004-04-14 8:49 ` Dmitry A. Kazakov
2004-04-14 16:49 ` Hyman Rosen
2004-04-15 10:37 ` Dmitry A. Kazakov
2004-04-14 7:10 ` Russ
2004-04-14 8:53 ` tmoran
2004-04-14 9:01 ` Vinzent 'Gadget' Hoefler
2004-04-14 9:21 ` Dmitry A. Kazakov
2004-04-13 9:53 ` Wojtek Narczynski
2004-04-15 21:27 ` Expressing physical units Jacob Sparre Andersen
2004-04-16 11:40 ` Dmitry A. Kazakov
2004-04-09 16:17 ` Reprise: 'in out' parameters for functions Georg Bauhaus
2004-04-10 2:28 ` Wojtek Narczynski
2004-04-10 9:46 ` Georg Bauhaus
2004-04-10 10:49 ` Dmitry A. Kazakov
2004-04-10 15:35 ` Wojtek Narczynski
2004-04-10 21:01 ` Georg Bauhaus
2004-04-10 21:16 ` Georg Bauhaus
2004-04-11 13:20 ` exception parameters Stephen Leake
2004-04-12 10:29 ` Dmitry A. Kazakov
2004-04-13 0:58 ` Stephen Leake
2004-04-13 1:30 ` Randy Brukardt
2004-04-13 8:04 ` Jean-Pierre Rosen
2004-04-11 10:31 ` Reprise: 'in out' parameters for functions Dmitry A. Kazakov
2004-04-12 22:02 ` Randy Brukardt
2004-04-13 10:56 ` Dmitry A. Kazakov
2004-04-14 21:12 ` Randy Brukardt
2004-04-15 10:37 ` Dmitry A. Kazakov
2004-04-13 9:30 ` Wojtek Narczynski
2004-04-13 12:00 ` Dmitry A. Kazakov
2004-04-13 22:41 ` Wojtek Narczynski
2004-04-14 8:49 ` Dmitry A. Kazakov
2004-04-14 15:03 ` Wojtek Narczynski
2004-04-15 10:37 ` Dmitry A. Kazakov
2004-04-16 0:29 ` Wojtek Narczynski
2004-04-16 11:36 ` Dmitry A. Kazakov
2004-04-16 19:25 ` Wojtek Narczynski
2004-04-14 15:57 ` Robert I. Eachus
2004-04-15 8:04 ` Dmitry A. Kazakov
2004-04-10 12:32 ` Wojtek Narczynski
2004-04-14 15:46 ` Robert I. Eachus
2004-04-16 1:52 ` Wojtek Narczynski
2004-04-16 5:40 ` Robert I. Eachus [this message]
2004-04-16 11:38 ` Wojtek Narczynski
2004-04-16 16:30 ` Robert I. Eachus
2004-04-16 18:38 ` Randy Brukardt
2004-04-16 22:15 ` Wojtek Narczynski
2004-04-17 1:20 ` Robert I. Eachus
2004-04-17 11:42 ` Wojtek Narczynski
2004-04-17 14:14 ` Robert I. Eachus
2004-04-16 19:28 ` Wojtek Narczynski
2004-04-09 17:09 ` Pascal Obry
2004-04-10 2:37 ` Wojtek Narczynski
[not found] <u8yh75y33.fsf@acm.org>
2004-04-07 23:54 ` Alexander E. Kopilovich
[not found] ` <WLZI9T09aE@VB1162.spb.edu>
2004-04-08 2:21 ` Stephen Leake
2004-04-07 20:31 Stephen Leake
2004-04-08 18:42 ` Georg Bauhaus
2004-04-08 20:32 ` Randy Brukardt
2005-01-12 15:15 ` okellogg
2005-01-12 20:14 ` Randy Brukardt
2004-04-08 23:48 ` Stephen Leake
2004-04-13 14:45 ` Robert I. Eachus
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox