CSE503: Software Engineering
Lecture 2 (January 6, 1999)

David Notkin

Question from an interested student:

So, something that has been bugging me recently is the need for specification of implementation in the specification of an ADT (or some such).

Take for an example a list/vector like data structure that supports indexing and insertion/deletion of arbitrary elements. So the question is, did does the structure have O(1) inserts/deletions and O(n) indexing, or O(n) insertions/deletions and O(1) inserts. Is it implemented over a linked list or an array? When I use a data structure out of the box, this is something I really want to know.

Examining two classes in the Java Hierarchy, java.util.Vector and java.util.Stack. It appears that the Stack (a subclass of Vector) uses the same implementation as Vector. I would also assume, although it is not specified (but it should be!!) that the Vector class is implemented over an array. This means that the insertion operations are costly and the indexing operations are not. Now, the Stack object is implemented as a subclass of Vector, so I would assume it has the same implementation. This means that doing N push operations on an initially empty stack costs me a runtime of order N log N, assuming that the Vector is implemented to double its size when ever needs more space than its capacity. However, in my opinion, any structure claiming to be a "stack" implemented on a system that supports dynamic allocation should have a runtime of order N for N push operations.

So, the only thing I know about this is that it doesn't seem like the typical way of specifying ADTs is good enough. Is an ADT being slower than is necessary a failure that people care about? Or is that something pushed under the carpet that the implementers don't tell their supervisors? Why is it acceptable to leave this sort of stuff out of specification?

Notkin’s Top 10 Observations

  1. We make a huge mistake by assuming similarity among software systems
    1. Ex: Does (and should) the reliability of a nuclear power plant shutdown system tell us much about the reliability of an educational game program?
    2. Ex: Does (and should) the design of a sorting algorithm tell us much about the design of an event-based GUI?
    3. So, assume differences until proven otherwise
  2. Intellectual tools still dominate mechanical tools in importance
    1. How you think is more important than the notations, tools, etc. that you use
      1. Ex: Information hiding is a key design principle
        1. Interface mechanisms can enforce information hiding decisions but cannot help one make the decisions
      2. Ex: The notion of design patterns is more important than languages that let you encode them
  3. Analogies to other engineering disciplines are attractive but generally fall apart quickly
    1. One key reason is because of the incredible rate of change in hardware and software technology
    2. Another is that software seems to be constrained by few physical laws
    3. But I’ll make them anyway, I’m sure (and you will, too)
    4. This is a variation on #1
  4. It is often too easy to estimate the benefits of a "better" approach to engineering software without assessing its costs
    1. "If only everyone only built software my way, it'd be great" is a common misrepresentation
      1. Ex: The formal methods community is just starting to understand this
    2. But at the same time, estimating the costs and the benefits is extremely hard, leaving us without a good way to figure out what to do
  5. The properties that programming languages can ensure are distant from the properties we require software systems to have
    1. Programming languages can help a lot, but they can't solve the "software engineering" problem
      1. Ex: Contravariant type checking (such as in ML) has significant benefits, but regardless, it doesn’t eliminate all errors in ML programs
      2. And covariant typing, with its flaws, may be useful in some situations
  6. The total software lifecycle cost will always be 100%
    1. Software development and maintenance will always cost too much
    2. Software managers will always bitch and moan
    3. Software engineering researchers will always have jobs
  7. Software engineering draws on mathematics, cognitive psychology, management, etc., but it is engineering and not mathematics, nor cognitive psychology, nor management (nor etc.)
    1. If somebody is talking about software without ever mentioning "software", run away
  8. Tradeoffs are at the heart of software engineering, but we're not very good at it
    1. Getting something for nothing is great, but it isn't usually possible
    2. We almost always choose in favor of hard criteria (e.g., performance) over soft criteria (e.g., extensibility)
    3. This makes sense, both practically and theoretically
    4. Brooks’ Golden Rule doesn’t really work
    5. But the situation leaves us up a creek to a large degree
  9. It's always good to (re-)read anything written by Brooks, Jackson, and Parnas
    1. Don’t fall into Mark Twain’s trap: "A classic is something everyone wants to have read, but nobody wants to read."
  10. Software engineering researchers should have a bit of the practitioner in them, and software engineering practitioners should have a bit of the researcher in them

A very basic overview of software engineering

Bar code scanners 10-50KLOC
4-speed transmissions 20KLOC
GNU Emacs 120KLOC
ATC ground system 130KLOC

GCC 280KLOC
Teller machine 600KLOC
Call router 2.1MLOC
B-2 Stealth bomber 3.5MLOC
Seawolf submarine combat 3.6MLOC
Space shuttle 26MLOC+1MLOC/flight
NT5.0 60MLOC

Code Size Discipline

103 Mathematics

104 Science

105 Engineering

106 Social Science

107 Politics

108 ??