comp.lang.ada
 help / color / mirror / Atom feed
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



  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