home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.ada
- Path: sparky!uunet!stanford.edu!eos!aio!dnsurber
- From: dnsurber@lescsse.jsc.nasa.gov (Douglas N. Surber)
- Subject: Re: Controlling Type Definition - Is it useful/necessary?
- Message-ID: <dnsurber.716479211@node_26400>
- Sender: news@aio.jsc.nasa.gov (USENET News System)
- Organization: Lockheed Engineering and Sciences
- References: <1992Sep10.162550.5675@saifr00.cfsat.honeywell.com>
- Distribution: comp.ada
- Date: 14 Sep 92 14:00:11 GMT
- Lines: 104
-
-
- In order to discuss how to properly control type definitions, you must
- consider what purpose types serve. Obviously they are used to define
- storage. All that is required to accomplish that is to say "this thing
- takes up this many bits". Second, they allow you to specify certain
- types of built in functionality, such as indexing or floating point
- multiply. This is pretty well covered by integers, floats, chars,
- pointers, arrays and records. Not much sophistication required. Finally
- they are used to tell the compiler and the maintainer something about
- the program. Does the value of one object relate (more or less) directly
- to the value of another object _with_ _in_ _the_ _logical_ _space_ _of_
- _this_ _program_. If so they should have the same type, if not, not.
- This is where the full power of Ada's type system is needed.
-
- Like everything else, type definitions can be described to exist along a
- continuum between two extremes--those types specified by the interface
- to a package and those and those that exist solely to describe/support
- the specific implementation of the computation the package performs.
- The types of objects that directly relate to the interface, such as the
- types of parameters, storage of intermediate results, etc should be
- tightly controlled, as you described. Clearly the value of these objects
- are closely related. But in a package of any complexity there may be
- other objects which, while influencing the result, are not as closely
- related to the result. The types of these object should be chosen to
- convey as much information about the computation as possible.
- Arbitrarily restricting the programmer's ability to define new types of
- this kind will reduce the quality of the code. It takes away one of
- Ada's biggest strengths.
-
- In the first paragraph I said that types are used to tell the compiler
- about the program. I feel I ought to clarify that statement. Testing of
- programs is *HARD*. Compilation is easy. The compiler can verify
- certain correctness properties of a program using the information in the
- types. Each correctness property of a program that is expressed in the
- types is one that you don't have to worry about in testing. (Sure you
- want to test for it anyway, but that's just reasonable paranoia.) If I
- define a new type "Foo_Array_Index" and use it as the index type for an
- array, then I _know_ that I haven't mistakenly used "Bar_Array_Index" to
- access "Foo_Array". This eliminates a whole class of errors. This can
- be taken to extreemes--you can define a new type for everything. Of
- course this doesn't tell the compiler anything since every time two
- objects are "combined" you have to do type casting. Ultimately this is
- a judgement call. The extreemes are obvious, but stuff gets muddy in
- the middle.
-
- Guidelines for creating new types are certainly in order. But in my
- opinion there are no simple syntatic rules. This is one of those skills
- that distinguishes good programmers from poor ones--the ability to write a
- program that is not only correct and efficient but readable, testable,
- and robust in the face of changes. Good use of the type system improves
- those properties.
-
- I am presently working with a group to improve the speed of a rather
- large package. The profiler tells us that 10-12% of the cycles are spent
- TRUPping (Trim Right, UPper case) strings. The interface has a number of
- parameters of type "String", and the internals of the package require
- that those string parameters be TRUPped. The implementation TRUPs just
- about every use of every string, so of course most of those strings have
- already been TRUPped multiple times. Obviously the thing to do is to
- just TRUP things once and then forget about it. But this is a large
- package with several people working on it and unknown future generation
- having to maintain it. Our solution is to derive a new type,
- "Trupped_String", from an existing type "Pascal_String", and write a
- procedure, "Trup_String (arg : in String) return Trupped_String", that
- trims and upper cases its argument. Then we convert args at the
- interface and don't worry much after that. Because this is a new type,
- the compiler can find certain kinds of errors for us, and for future
- maintainers. Additionally, maintainers will be constantly reminded that
- these strings need to be TRUPped.
-
- As far as specific guidelines go, I can think of the following:
-
- Use the interface types unless there are good reasons not to.
- There often are good reasons not to, but be sure you have thought
- about them before creating a new type.
-
- Don't create a new type from thin air if you can reasonablly derive
- it from an existing type. This will help with precision problems.
-
- If you are type casting two types back and forth all over the place,
- consider making them the same type. However, if there is a clear
- conceptual transformation that occurs with the type casting, consider
- writing a function that captures that transformation and using it
- instead of the bare type coersion.
-
- If two objects are never "combined" (transitively) then they should
- be of different types. If they aren't the same then don't say they
- are the same by making them the same type.
-
- This last is especially important when it comes to array indices. I
- think every array should have its own distinct index type so there is no
- problem with getting indices mixed up.
-
- This has all been about creating new types. Subtypes are less of a
- problem. I use them every where I can to specify range constraints.
- This is a help with testing, but since you can mix and match subtypes to
- your hearts desire, they don't give you much help at compile time.
-
- This has gone on rather longer than I intended, I hope it helps.
- Sorry I had to post it, but I don't have email access. :(
-
- Douglas Surber
- Lockheed
- Houston, TX
-