The Need For A Cognitive Viewpoint on Software Component Understanding

Larry Latour

University of Maine
Department of Computer Science
222 Neville Hall
Orono, Maine, 04473
Tel: 207-581-3523
Fax: 207-581-4977
Email: larry@gandalf.umcs.maine.edu
URL: http://www.umcs.maine.edu/~larry/latour/latour.html

Abstract

While we as researchers spend a great deal of time trying to understand the products and processes of our field, it might be worthwhile to step back a bit and ask ourselves whether or not the majority of software engineers out there are "getting it". Reasons why this might not be so are not necessarily due to our lack of success at describing software artifacts. Rather, they might be due to the inability of software engineers to see past particular solutions to particular problems, i.e., they might be due to software engineers having restricted, or functionally fixed views of problem solutions. I suggest a variety of examples where functional fixedness plays a role, and point to work that we are doing to help break us of this "bad habit".

Workshop Goals : To share my ideas about a cognitive perspective on reuse, and to integrate these ideas into an overall model of both reuse process and product creation.

Working Groups : Reuse Education, Human Factors, Reuse Understanding.

1 Background

For a while now I've been interested in the understanding problem in reuse [8,9]. From this perspective, I've noticed an interesting pattern in our workshop papers and in the greater community. Researchers in the reuse field seem to spend a great deal of time describing the products of our discipline, somewhat less time describing the processes we use to derive these products, and very little time on how the software engineer comes to understand these artifacts. We don't formally acknowledge (but often gossip) that software engineers have a generally poor understanding of all of those wonderful software artifacts out there - artifacts that just "drip" with generality.

Such a restricted view could be caused by a number of factors:

* The domains in which the artifacts are to be used might not be well understood. These domains include the architecture of the overall application (process control, organizational management, graphic design, etc.) the architecture of the connection infrastructure (OLE, CORBA, OpenDoc, etc.), the architectures of the support domains (interface management, storage management, network management, etc.), and the architecture of the development tools.

* The education and training of many software engineers is poor. Many software engineers come from poor university and industry backgrounds, taught from textbooks with cookbook recipes rather than with a firm grounding in the basic principles and insights of computer science. Also, many otherwise good software engineers have simply not kept up with the lightening quick technology advances of the past few years. One recent software engineering manager told me that his company provided 40 hours of training per year (he was proud of that) for each of his software engineers, that a number of his software engineers have been on the job for 10 or more years (which might actually work against him), and that some (but not all) of his software engineers have had the motivation to keep up with the industry in their "off-time".

* There is a wide disparity in the inherent ability of our software engineers. I recently had a conversation with a software engineering manager who lamented that she could get more out of person A in one week than she could get out of person B in a year.

* The good software engineers are suffering from "information glut". It is often less the question of how much money can be spent on a reuse effort than how much mental energy is required to understand all of the meta-information we as researchers are pumping into the marketplace.

My colleague Liesbeth Dusink and I have discussed this problem in the literature, both independently and jointly [2,3,4,7]. Certainly a good number of the problems stated above are beyond our control. But also a good number of these same problems are what are causing the goals of reuse to be only partially achieved. Are these technical or non-technical problems? It depends on your point of view. If you're writing a paper on reuse management issues, you tend to ignore the technical issues and concentrate instead on convincing the management. If you're writing a technical paper, your concerns are typically with the technical insights gained in solving a knotty problem. I tend to see each side as an artificial distillation of a greater problem, a problem which is concerned not only with management and technical issues, but also with the human software engineer's ability to understand and integrate these issues.

2 Position

We realize that there is a great deal of literature on how to make software generic. This literature includes extensive work on domain analysis, domain specific software architectures, component libraries, etc. But what all of this work seems to have in common is that it looks at genericity from the perspective of the software artifacts. The cognitive perspective of the software engineer tends to be ignored. Specifically, we worry a great deal about behaviorally rigid components that are designed in an overly restrictive manner. We even spend a great deal of time modeling the genericity of components in order to avoid such rigidity. But what of the poor software engineer's ability to understand and assimilate what we've come up with?

Our position: we need to find ways to help the software engineer avoid developing functionally fixed views of software artifacts that are unfortunately so often cultivated in software engineering environments. Functional fixedness refers to the way in which knowledge is learned for the solution of a specific problem. Such fixedness limits the range of perceptual organizations capable of being developed by the problem solver with respect to the learned knowledge, and as a result interferes with problem solving capacity with respect to the knowledge [1,12].

Although behavioral rigidity and functional fixedness do influence each other, they aren't synonymous with one other. A software engineer could have a functionally fixed view of a software artifact that might or might not be due to the restrictiveness of the artifact itself. It might also be due to the limited view of the artifact presented to the software engineer, the limited education of the software engineer, or simply the limited reasoning ability of the software engineer. For example, users of Unix see it from a wide range of perspectives. New users might find it to be confusing and hard to use. Expert users might find it empowering because of the compositional properties of its components. Users familiar with the design of communication protocols might find such protocols to be easy to cobble together using pipes. Others might view pipes as simply a way to string together simple filters (such as cat and more ). Still others might not have the slightest clue as to what either a pipe or a communication protocol is.

There is literature on this cognitive notion of functional fixedness [16], but it is not focused on software engineering artifacts. What we have been doing is to try to operationalize functional fixedness in the software engineering domain.

2.1 Forms of Functional Fixedness

Functional fixedness seems to be a property of the human condition, and as such is not limited to any one type of artifact or perspective of it. This gives us the license to look at what functional fixedness means with respect to all manner of software artifact. We are looking for a set of guiding principles that spans these artifacts. Here are a few examples:

2.1.1 User Interface Functional Fixedness

User Interface functional fixedness rears it's ugly head both in the engineering of an interface and in the human use (or misuse) of that interface. The previous example of Unix is interesting in this regard since it is not clear whether it is a human interface or an embedded interface. That is, is it a language that we use with a keyboard to communicate our informal scenerios to the machine, or is it a language we use to more formally compose scripts of complex operations?

But let's take a look at a different sort of interface. The wide variety of graphic art tools available on the desktop give us an interesting set of interfaces to analyze. Consider Adobe Photoshop. It provides a growing collection of tools allowing the graphic artist to use some fairly complicated digital image manipulation techniques. Recently I attended a Photoshop seminar run by a photographer for photographers. I found it fascinating that although I had what I felt was a good knowledge of what each individual operation could do within Photoshop, I was not really aware of why such functionality had been provided, nor did I have a good feel for how to compose these operations into ever more complex scenarios.

Consider the following scenario taken from the Adobe Photoshop manual, entitled Adding Color to a Grayscale Image [15]:

The term Duotone mode applies generically to monotones, duotones, tritones, and quadtones. Creating a Duotone involves three steps:

* Specify the type of duotone

* Specify the ink color to use (by creating or using a default duotone curve)

* Adjust the duotone curve to determine how ink is distributed across the image.

But what are the criteria for specifying the type of a duotone? What are the criteria for choosing ink color? How do you determine how ink is distributed across the page? Delving a bit more deeply into these operations uncovers a dizzying collection of dialog and sub-dialog boxes depicting duotone graphs, color wheels, and sliders for adjusting complex parameter values. Interestingly enough, despite my obvious confusion as to why these operations were used, I was still the one that people tended to go to for questions regarding how to perform an operation.

We've also looked at a number of other examples of this user interface functional fixedness, including:

* The functionally fixed view that K-12 learners develop by looking at student modeling environments from the perspective of a particular problem. For example, if a tool for modeling emergent phenomena is used to model an ecological system of rabbits eating grass, many students believe that this is what the modeling tool was designed for - modeling rabbits eating grass. In a related project, I am exploring student learning in a language/environment/modeling tool called Starlogo [10].

* The functionally fixed view that PC users have of the OLE (Object Linking and Embedding) environment. If all a user sees of OLE is it's use in embedding graphical applications inside text documents, then the user thinks that this was what OLE was designed for. They might not realize that it's an integrated architecture for building systems of interoperable subsystems.

* The functionally fixed view users have of Spreadsheets. Most users don't tap the expressive and analytical power of today's spreadsheet environments. They view them as a way to generate budgets and balance sheets.

These are only a few of the examples we've looked/explored/thought about. Readers can most likely think of many more examples of their own where functional fixedness plays a role in cognitive understanding.

2.1.2 Architectural Functional Fixedness

Often a software engineer's limited view of options available in architectural design leads to subsequent problems in the implementation. As a faculty member in a computer science department, I'm fortunate to witness firsthand the learning process of our students. This issue of architectural design is something that most students don't begin to appreciate until fairly late in their studies (if at all).

As an example, many students begin with a single thread of control model as their single perspective, seeing procedure calls as the only way to make connections between components. They literally can't conceive of communication in any other way. Their introduction to multi-process operating systems and networks begins to break down this functional fixedness, introducing the concepts of asynchronous and synchronous process communication. They begin to realize at this point that there are many architectural points of view on a single system. These might include a functional view defining an architecture in terms of the major functional components, a modular view defining the major units of encapsulation, and a process view, defining the major units of parallelism (along with synchronization and timing concerns).

One might excuse the above progression as simply part of the learning process, but limited architectural perspective can occur in any environment in which software engineers are dedicated to constructing their systems in a standard way, using a standard set of protocols. To a Unix hack everything looks like filters and pipes. To an object oriented software engineer, everything looks like objects, methods, and messages. Other software engineers may view the world in terms of clients and servers, and still others in terms of events, event loops, and event handlers. A number of interesting papers explore these architectural concerns, including [5,13,14].

2.1.3 Component Functional Fixedness

Libraries are littered with components whose functionality has never been fully and consistently exploited. Although part of this is due to the poor design and documentation of the components, part is also due to the functionally fixed view users have of these components. Consider the range of COTS (Common Off The Shelf) software available to software developers - programming languages and environments, database tools, interface development tools, graphics packages, numerical analysis packages. What all of these have in common is that they are often improperly used, in many cases due to the limited perspective a software engineer has of them.

2.1.4 Algorithmic Functional Fixedness

We have looked at a number of textbook algorithms from the cognitive perspective of functional fixedness. Textbook examples tend to be the first algorithms computer science students see, and these examples suffer simply because they are only that: examples. To demonstrate this, we looked at a quicksort algorithm in [4]. We noted that a typical quicksort algorithm presented in a text is full of design decisions that don't relate directly to the concept of a quicksort algorithm. For example, most quicksort algorithms (except those in lisp texts) sort data in place, most use a binary partition algorithm, and most impose a sequential ordering on which half of the partition is sorted first. Programmers develop a functionally fixed view through the study of such behaviorally rigid forms, and this view is reinforced through repeated application. Nothing can break the programmer of such views if there is no apparent need to generalize the algorithm.

2.2 Ways of Overcoming Functional Fixedness

Liesbeth Dusink and I have looked at a number of issues relating specifically to software understanding and the functional fixedness problem. For example, the literature discusses the need to make artifacts generic. We've translated this goal into the following cognitive concerns:

How does a software engineer know how to recognize properties of a component that make it less generic than it could and should be? This is not always as easy as the rhetoric sounds. For example, what does it mean to generalize a component to work in a multi-process context, when that component has always been viewed within the context of a single thread of control. In this case the specific choice of synchronization used in the single thread of control example is the null choice. How does one generalize from nothing?

How can a software engineer be educated to "be aware"? That is, how is a software engineer trained to value assumptions, consider all viable alternatives, and analyze the implications of making a component generic with respect to the surrounding architecture?

How hard is it for a software engineer to assimilate and then manipulate a collection of interrelated generic components for the purpose of building a system? In many cases these components might be designed within different contexts, in which case there might be an architectural mismatch leading to all sorts of problems [5].

In order to combat functional fixedness, we've suggested the exercise of uncommitting design decisions from functionally fixed designs in such a way that (1) their essence is kept, and (2) a component architecture unfolds. The notion of "essence" is a crucial one in that we want to capture an abstract design in such a way that we can leverage the analyses that accompany it in the literature. We've discussed how the uncommit process is done with the support of: reasoning by analogy, stating implications, challenging assumptions, and (of course) previous experience/ knowledge about the domain and other domains and about general software engineering principles. This method of working seems to aid the software engineer in ``seeing'' a solution for a problem class instead of for a problem, thus helping to avoid functional fixedness in the design process.

We have developed a number of examples illustrating the uncommit process, and are planning experiments to further illustrate it's effectiveness when used explicitly in the design process [4]. These examples range from a spreadsheet interface design exercise to the use of uncommitting design decision in the factoring of monolithic program libraries into architectural frameworks.

3 Comparison

There seems to be a number of groups working on the program understanding problem, although it is very hard to get away from the "product-centric syndrome". Most of the groups I've looked at talk about the understanding problem, but ultimately they use the generated products for illustration. This has to some extent also been our problem. I can recall giving a talk on the assumptions and implications of uncommitting design decisions in both a quicksort algorithm and in a collection of Grady Booch's data structure components, only to be left with the same products on the board as when I focused on the products themselves and not on the human understanding issues.

The psychology of programming interest group, a UK based group, is looking at a number of problems related to programmer learning. John Hartman , of the Ohio State University Laboratory for Artificial Intelligence Research, is looking at a number of cognitive science issues in [6]. Alex Quilici of the University of Hawaii at Monoa, is doing work on program understanding, essentially a reverse engineering problem [11]. The reverse engineering field is looking at this concept of program understanding, but the concern here again is less from the cognitive perspective as it is from the "data mining" perspective.

References

[1] H.G. Birch and H.S. Rabinowitz. The Negative Effect of Previous Experience on Productive Thinking. In Wason and Johnson-Laird , chapter 3.

[2] E.M. Dusink. Reuse is not done in a Vacuum. WISR'92, 5th Ann. Workshop on Software Reuse , Palo Alto California, October 26-29 1992.

[3] E.M. Dusink. The Reuse Process Refined. Technical Report, Faculty of Mathematics and Informatics, TU Delft, The Netherlands, 1994.

[4] E.M. Dusink, and L. Latour. Controlling Functional Fixedness: the Essence of Successful Reuse. Jour. on Knowledge Based Systems - Models and Techniques for Reuse of Designs , Spr 1995.

[5] D. Garlen, R. Allen, and J. Ockerbloom. Architectural Mismatch: Why Reuse Is So Hard. pps. 17-26, IEEE Software , November, 1995.

[6] J. Hartman and B. Chandrasekaran. Functional Representation of Executable Software Architectures. Technical Report, Laboratory For Artificial Intelligence Research, The Ohio State University, December 1, 1995.

[7] L. Latour, and E.M. Dusink. Controlling Functional Fixedness: The Essence of Successful Reuse. WISR'95: 7th Annual Workshop on Software Reuse , St. Charles, IL., August, 1995.

[8] L. Latour, and E. Johnson. Seer: A Graphical Retrieval System for Reusable Ada Software Modules. Proceedings of the 3rd Int'l IEEE Conference on Ada Applications and Environments , Manchester, NH., 1988.

[9] L. Latour. Experiments in Hypermedia Support for the "Understanding for Reuse" Problem. WISR'93: 6th Annual Workshop on Software Reuse , Owego, NY, November, 1993.

[10] L. Latour. Maine Starlogo Communities: http://www.asap.um.maine.edu/starlogo. ,Sept, 1996.

[11] A. Quilici and D. Chin. A Cooperative Program Understanding Environment. Proceedings of the 9th Annual Knowledge-Based Software Engineering Conference . IEEE Press. Monterey, CA, pp. 125-132, September 1994.

[12] P. Saugstadt and K. Raaheim. Problem-Solving, Past Experience and Availability of Functions. In Wason and Johnson-Laird , chapter 5.

[13] M. Shaw. Comparing Architectural Design Styles. pps. 27-41, IEEE Software , November, 1995.

[14] M. Shaw, R. DeLine, D. V. Klein, T. L. Ross, D. M. Young, and G. Zelesnik. Abstractions for Software Architecture and Tools to Support Them. pps. 314-335, IEEE Transactions on Software Engineering , Vol. 21, No. 4, April, 1995.

[15] Tutorial: Adobe Photoshop. Adobe Systems Incorporated, 1993.

[16] P.C. Wason and P.N. Johnson-Laird, editors. Thinking and Reasoning, Selected Readings. Penguin Modern Psychology . Penguin Books, 1968.

Biography

Larry Latour is an Associate Professor of Computer Science at the University of Maine, having received his PhD degree in Computer Science from Stevens Institute of Technology in 1985. His work was in the development of a model theoretic approach to concurrency control, and he has since looked at how algebraic specifications of abstract objects can enhance concurrency control in object databases. At the same time he developed his software engineering interests at the Ft. Monmouth Center for Software Engineering. He was introduced to reuse in 1986 at the Syracuse University Annual Software Engineering Workshop in Minnowbrook, NY, where he and a small group of Tools and Environments working group members began what is currently the National WISR workshop series on software reuse. In conjunction with this workshop he manages the WISR repository at Maine. Along with his reuse interests, Larry is exploring interdisciplinary teaching techniques and K-12 learning environments, all of which focus on the understanding problem.