From: "Jeffrey R. Carter" <spam.not.jrcarter@acm.not.spam.org>
Subject: Re: [SPARK] Code safety and information hiding
Date: Sun, 20 Aug 2006 03:52:27 GMT
Date: 2006-08-20T03:52:27+00:00 [thread overview]
Message-ID: <%%QFg.913090$084.629274@attbi_s22> (raw)
In-Reply-To: <upsex12ed.fsf@stephe-leake.org>
Stephen Leake wrote:
>
> I think I'll choose to take offense at this statement (it's 5:26 AM,
> and I can't sleep because I've got a bit of the flu, so I claim the
> right :).
I have a bad cold, and did when I wrote the statement to which you're
responding, so I claim the right to argue back. Let's spray our addled
perceptions into c.l.a, where someone will reference them as definitive
in the future.
> I have an application called Goddard Dynamic Simulator (GDS); it is
> used to test flight software and hardware for NASA Goddard (yes, I am
> a rocket scientist). It has 90,000 lines of code, mostly Ada, some C
> and VHDL.
I've never been sure what a "rocket scientist" is. Is it someone who
deals with the theory of anaerobic propulsion systems? Or is it a more
general science dealing with launch systems overall?
In any case, being a scientist is probably not a qualification for
designing actual systems. Scientists deal with theory; engineers with
creating systems. Physicists are not necessarily competent to design
bridges; civil engineers are.
> However, there are some global variables. I thought long and hard
> about each one, and decided they are the best solution to the
> problem.
Some is probably better than lots. With "some" they might be well
documented. As I've said, I've seen large, safety-critical systems
designed around thousands of undocumented global variables. I think it
would be faster and easier to redesign and reimplement these systems
than to understand them well enough to safely make changes to a small
part of them.
I've often had similar thoughts about systems in which simple boolean
options exist which may be changed at any time. If it's a sequential
system, Boolean variables seem sufficient. For a concurrent system,
making them atomic should be enough, though I would prefer a protected
object. On the other hand, I don't want to seem to give permission for
modifiers of the system to create global variables that are more complex
or have more restricted situations when they may be accessed.
> This design has evolved thru several iterations of similar systems.
> They all have a global symbol table.
So, as a modifier of the system, without reading and understanding all
parts of the system that may access this variable, it's OK for me to
write to this variable whenever it's convenient?
> type Distribute_Mode_Type is (Master_Mode, Remote_Mode, Single_Mode);
>
> Distribute_Mode : Distribute_Mode_Type := Single_Mode;
Again, it must be reasonable and meaningful for me to change the SW to
write this variable whenever it suits me.
If that's not the case, then I claim this should not be a variable.
Instead of being able to write
X.Distribute_Mode := X.Master_Mode;
I should have to call something like
function Request_Distribute_Mode_Change
(New_Mode : Distribute_Mode_Type)
return Boolean;
-- Request mode change to New_Mode.
-- Returns True if the mode change is legal; False otherwise.
All the details of when a mode change may occur should be encapsulated
with the current mode value.
On the 3rd hand, systems generally are either distributed or not, and
that doesn't change during execution. In that case, this is essentially
a constant. If the actual mode is determined at run time during start
up, then probably the value should be encapsulated with the logic that
determines it, and the resulting value be made available to the rest of
the system through a function.
In this latter case, there may also be a race condition. What if one
part of the system reads this and gets the default value before its
actual value is determined? It's probably better to control that locally
than otherwise.
> Ignore_Hardware_Errors : Boolean := False;
> -- Set True for unit tests when hardware is not present or should
> -- be ignored.
Shouldn't that be "Boolean_Type"?
This is documented, and shows that it isn't a variable. Clearly this
should have the same value for an entire execution; I've never seen SW
that switches between unit test and other modes during execution. I
suspect your SW would be clearer if this were a constant.
> I claim to be competent to design SW; I have 20 years of experience,
> and at least 10 monetary awards for outstanding performance, together
> with high praise from my (internal) customers, to prove that. My
> system has a few global variables because they are the right solution
> to the problem.
Perhaps. Who modifies the system? Add 1 undocumented global variable to
a system, and you generally increase the coupling and decrease the
cohesion. You understand the system, but after you're hit by a truck,
how easy is it for someone who doesn't have any experience with the
system to figure out how it works?
> You have not said why getter/setter would be better for these
> variables. I agree with Robert; they are just more verbose.
I don't think they're better. I said that if global variables were not
available, those who would try to base their designs around them might
not think of using such operations to mimic them.
> Hmm. You could try to impose control over what parts of the system
> are "allowed" to write the variables, as opposed to reading them. But
> that would require an elaborate system of IDs for various parts of
> the system (which does not otherwise exist); definitely not worth it.
You might simply document who may write and who may read such variables.
That would be a big improvement in the global-centric systems I've seen.
Of course, that goes against the basic Ada philosophy that packages
should not be concerned with who their clients are. That's something
that's not always achievable in large, real SW systems. There are
sometimes operations that are documented as "used only by X and Y to
achieve Z". Such things should generally be private to some subsystem.
In general, values should be encapsulated with the logic that generates
or modifies them, and systems that are designed that way have better
coupling and cohesion than systems that aren't. Systems designed around
global variables are an extreme example of the latter. If your SW
determines a value in one place and stores it in another, that's an
indication that you may need to rethink your design. If the value is
determined in multiple places, that's almost always a red flag.
Now, I've worked on systems with physical redundancy, so that one
processor is the currently active one, and the others shadow it and are
prepared to take over if it fails. I've worked on such systems where the
determination of which is the active processor is made by another part
of the system, so it is necessary to distribute that value to the
processors. In that case, the SW pretends that it determines the value;
for example, there's a module that encapsulates the value and provides
access to it to other parts of the SW. There isn't a procedure Set for
the value; rather, the module has an operation that receives and
processes the message that changes the value.
> I'll make a counter claim; people who claim global variables are
> _always_ bad should not be designing large complex systems; the
> systems will be more complex than necessary, which is definitely a
> Bad Thing.
I have over 30 yrs of professional SW development experience, and I
still find myself doing things I know I shouldn't. Hopefully I catch
them most of the time in the important cases. But I've seen people with
decades of experience who are not competent to design any meaningful SW.
They're among that large proportion of developers who will never be more
than coders. Customers are happy with anything that works and they can
afford; I've seen customer satisfaction with very poorly designed SW.
There may be cases where global variables are the correct design
approach, but I have yet to see one.
> While it is true that all SW people are not equal, I don't see what
> that has to do with the issue of global variables, nor do I see what
> problem recognizing that might be a solution to.
Once you recognize that, you don't allow the coders to design SW. That
gets rid of most poor design, including designs with large numbers of
undocumented global variables.
As I said above, I have many designs that are not as good as they could
be, and some of them are freely available for anyone to look at. My
primary problem is with designs where the global variable is the
determining feature, with large numbers of them, and the fact that in
over 30 yrs I've never seen a case where global variables were the best
approach. GDS is probably not in that category. I'm not saying the GDS
SW is poorly designed (I've seen enough of your work to suspect it
probably isn't), but I suspect that the design could be improved and
that the improvement would eliminate the global variables. Whether the
improvement in design quality would be worth the effort to achieve it
now, I can't say. At the time of initial design, it almost certainly was.
--
Jeff Carter
"In the frozen land of Nador they were forced to
eat Robin's minstrels, and there was much rejoicing."
Monty Python & the Holy Grail
70
next prev parent reply other threads:[~2006-08-20 3:52 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-16 7:56 [SPARK] Code safety and information hiding Maciej Sobczak
2006-08-16 8:53 ` roderick.chapman
2006-08-16 11:18 ` Stuart
2006-08-16 13:23 ` Maciej Sobczak
2006-08-16 19:49 ` [SPARK] " Jeffrey R. Carter
2006-08-17 7:01 ` Maciej Sobczak
2006-08-17 18:08 ` Jeffrey R. Carter
2006-08-17 20:00 ` Björn Persson
2006-08-18 1:22 ` Jeffrey R. Carter
2006-08-18 19:39 ` Björn Persson
2006-08-19 5:35 ` Jeffrey R. Carter
2006-08-19 12:47 ` Björn Persson
2006-08-20 3:58 ` Jeffrey R. Carter
2006-08-20 11:35 ` Björn Persson
2006-08-18 23:02 ` Robert A Duff
2006-08-19 5:40 ` Jeffrey R. Carter
2006-08-19 9:49 ` Stephen Leake
2006-08-20 3:52 ` Jeffrey R. Carter [this message]
2006-08-20 19:06 ` Stephen Leake
2006-08-21 1:07 ` Jeffrey R. Carter
2006-08-21 7:25 ` Maciej Sobczak
2006-08-21 19:31 ` Jeffrey R. Carter
2006-08-21 19:58 ` Dmitry A. Kazakov
2006-08-21 21:06 ` Björn Persson
2006-08-22 7:16 ` Maciej Sobczak
2006-08-22 9:45 ` Björn Persson
2006-08-22 12:42 ` Maciej Sobczak
2006-08-22 7:27 ` Dmitry A. Kazakov
2006-08-21 11:30 ` Colin Paul Gloster
2006-08-22 10:51 ` Stephen Leake
2006-08-23 9:44 ` Peter Amey
2006-08-23 22:37 ` Jeffrey R. Carter
2006-08-24 10:55 ` Peter Amey
2006-08-24 23:33 ` Jeffrey R. Carter
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox