The mobile computing landscape is characterized by extreme heterogeneity. According to Facebook, the mobile version of their application is accessed from more than 2,500 varieties of mobile devices. Modern smartphones and tablets differ in terms of their respective hardware setups (e.g., screens, sensors, processors, memories, batteries, etc.), platforms (e.g., Android, iOS), versions, etc. Furthermore, mobile devices access the Web via mobile networks with dissimilar characteristics such as latency, bandwidth, and packet loss rates (e.g., 3G, 4G, Wi-Fi, etc.). It is the confluence of these differences that causes the heterogeneity challenge in mobile computing.
Addressing the heterogeneity challenge entails engineering mobile applications that can be used seamlessly on any device. As is commonly the case, addressing a challenge of this magnitude requires satisfying several constraints, only a subset of which can be satisfied at the same time. Specifically, the engineering process is subject to the following constraints: (1) maximize utility: provide the required functionality in as user-friendly fashion as possible; this is commonly achieved by supporting a native look-and-feel on every platform and properly leveraging a given device’s hardware capacities (e.g., screen resolution, touch interface, sensors, etc.); (2) minimize energy consumption: as the energy demands of mobile applications continue to outstrip the battery capacities of modern devices, mobile applications should be engineered with energy efficiency in mind; (3) minimize software development and maintenance costs: software development is costly and software maintenance is even more so.
The software maintenance and evolution constraint is particularly hard to satisfy in mobile computing. Mobile applications designed yesterday will have to run on mobile devices to be designed tomorrow. Mobile devices are evolving rapidly, with each new device featuring new hardware capabilities. Mobile software must keep up with the device evolution to provide quality user experience while keeping the energy consumption in check. Perfective maintenance, which codifies a set of activities aimed at optimizing applications for different objectives, is particularly hard hit by the heterogeneity challenge.
When planning their next mobile application, enterprises have no choice but to carefully select which two of the three constraints (utility, energy efficiency, development costs) they want to satisfy and plan their software development processes accordingly.
I keep finding more parallels between software maintenance and academic maintenance. Back in my days as a software developer, I vividly remember that the more senior and experienced developers were, the more their jobs were concerned with maintenance. In fact, the head of our programming team was devoting almost all of his time to fixing bugs. He was the most senior developer, who was most intimately familiar with our main product. He always had the largest number of bug reports in his work queue. These were pretty nasty bugs–showstoppers–which stood on the way of shipping the product to the customer. Despite performing an utterly important service for the company (i.e., keeping the product afloat), I remember my team lead being one of the most bitter people I’ve ever encountered. Fixing mostly other people’s mess must not be that fulfilling, even though the activity is vital for the very survival of the product and company. Not wanting to be eventually put in a position like that was one of the primary reasons why I decided to go back to school to get my Ph.D. and seek a career in research rather than in industry.
I am noticing that a faculty’s seniority level is almost directly proportional to the amount of academic maintenance they perform. The amount of service I perform has increased significantly since I got tenure. The faculty with administrative responsibilities mostly focus on academic maintenance rather than research. Department head is the ultimate example of a faculty focusing solely on maintaining the research enterprise of the department. I wonder, however, if focusing on academic maintenance too much can make faculty bitter, similarly to how it tends to work in software development. Too much non-research commitments is indeed stated as a key reason by those who have left academia.
It seems that maintenance, while essential, makes people engaged in it unhappy. There are notable exceptions, however. One of my former bosses claimed that he enjoyed fixing bugs more than he did writing original code. I am sure there are faculty who find departmental service as fulfilling as their research activities. Perhaps some of the techniques used to facilitate software maintenance can be applied to academic maintenance. Appropriate architecture, thoughtful design, solid implementation–all are known to streamline the maintenance process. A well-structured academic department with well-engineered work processes indeed reduces and simplifies the maintenance of the research enterprise as well. I wonder what other software maintenance state of the art can be applied here.
One of the common software myths is “once the software is delivered, most of the work is behind us.” In fact, nothing can be further from the truth, as it is estimated that between 60 and 80% of all software engineering effort and cost is expended on software maintenance, the process of modifying software after its initial release.
Whenever I interview people for faculty positions, I always ask them why they want to get a job in academia rather than in a research lab. Most of the interviewees have thoughtful answers that range from the ability define your own research agenda to developing long term mentoring relationships. However, once in a while I get an answer that goes something as follows: “I have done internships in research labs and saw how much time researchers spend on maintaining research software rather than on actual research; I’d rather not do that.” I am usually proud of my restraint when I don’t counter this answer with: “You think there is no maintenance in academia–what do you think I am doing right now talking to you rather than working on my research?!”
This answer indicates to me a fundamental misunderstanding of how the academic research enterprise operates. In fact, I find that similarly to software maintenance, academic maintenance takes between 60 and 80% of the total time and effort of an academic researcher. Teaching, grant preparation, committee work, manuscript reviewing, recommendation letter writing–all are essential activities without which the research enterprise cannot function. However, these maintenance activities combined commonly consume more time than direct research activities, including reading and writing research papers, meeting with your graduate students, and crafting research prototypes, even in a research university. That’s the basic equation of the academic research enterprise, and anyone who thinks that academic researchers live the posh existence of spending the majority of their time on research rather than on research maintenance are sadly mistaken.
Recently, I had the pleasure to attend a Distinguished Lecture given by Dr. Barbara Liskov of MIT, the 2008 ACM A.M. Turing Award winner. The lecture, entitled “The Power of Abstraction,” gave a fascinating historical perspective on how the modern software abstractions have emerged and why the mainstream programming languages look the way they do.
I was particularly intrigued by the observation Dr. Liskov made about the relative time a computer program is written vs. read. Early in the development of programming languages, language designers optimized their designs to make programs easy to write. However, Dr. Liskov has observed that the amount of time spent on reading the source code of a computer program tends to be much bigger than the amount of time it takes to write it. In other words, during the lifetime of a computer program, if t(w) is the time spent writing the program, and t(r) is the time spent reading it, then
t(r) > t(w). This observation has fundamentally transformed the optimization criteria for programming language design, and nowadays programming languages are optimized to make programs easy to read.
It has occurred to me that the t(r) > t(w) inequality is not true for all computer programs. To define t(w) more precisely, let it be the metric that includes the time it takes to write a program and to subsequently modify it as part of various maintenance tasks. However, only useful programs are read and modified continuously.
As a specific example, consider programs written as assignments in CS classes. I don’t think such programs are read more than they are written. Once a student program does what it is assigned to do, the student may never execute the program again. (The program is likely to be executed one more time during the grading process.) Similarly, professional developers write plenty of code that never makes it into production. This code is discarded and never read again. For that kinds of programs, their t(r) < t(w).
To better quality the t(r) > t(w) inequality, let us introduce another metric–t(e), the total time a computer program is executed. The relationship between t(r) and t(w) cannot be accurately assessed without taking t(e) into account.
To support this claim quantitatively, let me offer the following observation. For a program to be read more than it is written, the total time that a program is executed should be at least an order of magnitude larger than it has taken to write it. That is, t(r) > t(w) => t(w) * 10 < t(e).
I am not sure whether “order of magnitude” is the right quantification for this observation, but it is obvious that only useful programs are executed. A computer program’s practical utility directly affects how often it is executed. Furthermore, the more the program is executed, the more likely it is that the users will identify the need to change the program by fixing bugs, adding new features, and modifying existing features. In other words, using a program engenders the need to maintain it. To maintain a program, the programmer first must read and understand its source code. Therefore, there is a direct dependency between the total time the program is executed (i.e., used), read, and written.
In summary, only useful programs are read more than they are written, and the total amount of time spent on executing a program directly affects how often the program’s source code is read and written. I am not sure though whether this observation has any bearing on programming language design and software abstraction.