From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,34257fd17abeba14 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!wns13feed!worldnet.att.net!attbi_s22.POSTED!53ab2750!not-for-mail From: "Jeffrey R. Carter" Organization: jrcarter at acm dot org User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: [SPARK] Code safety and information hiding References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Message-ID: <%%QFg.913090$084.629274@attbi_s22> NNTP-Posting-Host: 12.201.97.176 X-Complaints-To: abuse@mchsi.com X-Trace: attbi_s22 1156045947 12.201.97.176 (Sun, 20 Aug 2006 03:52:27 GMT) NNTP-Posting-Date: Sun, 20 Aug 2006 03:52:27 GMT Date: Sun, 20 Aug 2006 03:52:27 GMT Xref: g2news2.google.com comp.lang.ada:6274 Date: 2006-08-20T03:52:27+00:00 List-Id: 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