Example Embedding Ohad Barzilay Blavatnik School of Computer Science Tel Aviv University
[email protected]
Using code examples in professional software development is like teenage sex. Those who say they do it all the time are probably lying. Although it is natural, those who do it feel guilty. Finally, once they start doing it, they are often not too concerned with safety, they discover that it is going to take a while to get really good at it, and they realize they will have to come up with a bunch of new ways of doing it before they really figure it all out.
Categories and Subject Descriptors D.2.13 [Software Engineering]: Reusable Software – Reuse models. D.2.3 [Software Engineering]: Coding Tools and Techniques. General Terms Management, Human Factors. Keywords reuse;
examples; example embedding; ecosystem;
1. Before We Start…
more complicated code. Some developers look for existing code snippets only for tasks they have already encountered, whereas other developers use examples only for tasks in unknown domains. When I tell academic researchers about my work, investigating how professional developers use code examples, they also say they can spare me the effort, and refer me to existing literature about code reuse and patterns – they claim it is all already out there. In fact, reuse and patterns both enjoy more credit in the academic world than in the industry. Programming languages offer constructs for code reuse such as functions, objects and inheritance mechanisms, but offer no support for reusing unpackaged code, and thus miss many reuse opportunities. Patterns suffer from another problem: they introduce an additional level of abstraction, which makes it difficult for a developer, seeking a specific solution for the specific programming task at hand, to find the pattern and tailor it to the specific context. When I tell my mother about my work, investigating how professional developers use code examples, she says nothing. My mother trusts my judgment and loves me no matter what I do.
When I tell software developers about my work, investigating how professional developers use code examples, they say they can spare me the effort and claim that developers use code examples all the time and for all purposes. So far in my studies, I have found that this is not the case – developers differ in the way they use examples [2]. Many developers are not attentive to the use of examples in multiple contexts and scales and/or do not use them effectively [3]. For instance, some developers use examples only in a certain programming language, but avoid using them in others. Some developers look for examples only for tasks that they consider to be simple, while others use examples only for
2. Introduction
Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, or republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. Onward! 2011, October 22–27, 2011, Portland, Oregon, USA. Copyright © 2011 ACM 978-1-4503-0941-7/11/10…$10.00.
For the first time, I realized it was not only me – it was not my fault. There was something missing in my training as a professional developer; in the training of us all. Books on agile software construction often describe software development as a craft and provide practices and
When I first read "Extreme Programming Explained" [4] I was so relieved. In his book, Beck describes his first attempt to write a Star Trek game as a kid: "So I sat confidently down to write my game. Nothing came. I had no idea how to write an application bigger than 20 lines. So I stepped away and I tried to write down the whole program on paper before typing it in. I got three lines written before I got stuck again. I needed to do something beyond programming. But I didn't know what else to do."
baby steps to follow and imitate. The book "Extreme Programming Explained", for example, introduced me to concepts such as refactoring, pair programming and continuous integration, activities that I had performed before, but because I had no name for them, I used them only sporadically and arbitrarily. The book "Test Driven Development by Example" [5] took me by the hand and, as its name implied, taught me, step by step, by way of example, how to use test-driven development in my own code. A new world revealed itself to me; a world in which development practices have names and, therefore, can be mastered. I was hungry for more. I wanted to learn more such practices so that I could incorporate them into my work. I looked for additional role models, more such star programmers whom I could observe and learn from. I had this crazy idea of watching professional software developers at work in order to discover new patterns, much like the 3D images that were popular in the 1980’s – if you would stare at them long enough, something would "pop out". Something must pop out. I wanted to find 'the next refactoring' – the thing everyone had been doing for years, but that once it was given a name, people started doing it right. So I began a field study1. I conducted observations for a month at the development sites of two major, wellknown worldwide software companies. Each day, I joined a different developer for a programming session that lasted 23 hours, for a total of 14 sessions. The choice of which programmer to observe with was made ad hoc, based on the programmers' availability and willingness, and the type of task they were engaged in (e.g. I preferred programming sessions over design meetings). During my observations I realized that example usage is a fundamental part of modern software development. Although it is widely used by many developers, its potential is far from being exploited, and I found that the practice should be carefully studied in order to be incorporated into professional software development settings. This realization led me to the concept of example embedding.
embedded software for a specific hardware, received from an offshore office. No one on the team knew how to work with this specific hardware and so the team assigned one team member, Dan, to learn how to perform its basic operations. Dan wrote a set of 10 short example programs, each demonstrating a different feature of the hardware, and sent them by email to the other team members. I joined Adam for a programming session in which he was trying to map to memory a new piece of hardware that was recently added to their existing large and complex machine. The code running on the machine was written in C. At the beginning of the session, Adam opened his email account and retrieved a message containing several code examples. He explained: "Dan sent several developers in the team some examples that deal with this... After I met with him and explained what I needed, he sent me some more examples". From that point on, Adam was very determined: he scanned over the example names, chose an example and opened it, saying "This is the 'Hello World' of base boards". Opening the code in which he wished to incorporate the new functionality side by side with the example code, he began to think out loud: "In this part, as opposed to the example, the reader is the base board and the writer is the daughter card that says 'I'm up'…". During the following 50 minutes, Adam was able to rewrite the example to his needs and to complete his programming task. During the observation itself, I did not perceive this to be innovative in any way; just a case of simple common sense. Common sense, however, is not that common. When I later reviewed the observation report of this session, I noticed three interesting things in retrospect: •
First, the work was directed. Adam did not waste time wondering; he was focused and determined. Although he did not know how to perform the task upfront, he knew exactly what would get him there: he opened his email targeted on finding the example closest to his specific task, and proceeded from there.
3. Using Examples in Software Construction
•
Second, the team used examples as a means for collective learning and sharing of knowledge among team members.
•
Third, the example usage itself is not atomic, but is rather a composition of several activities: browsing through the examples, choosing the most relevant one, copying the example code, and adapting it to a specific context. These various activities, and maybe others, serve as the building blocks of the example usage activity. They require different skills, their best practices should be better understood, and they could possibly be assisted by designated software tools.
The first time I encountered explicit example usage was during an observation session with an experienced developer, Adam, who was performing example-driven development (without calling it that). His team was working on
1
This study was done as part of my PhD research under the supervision of Professor Amiram Yehudai (Tel Aviv University) and Professor Orit Hazzan (Technion).
Example centric programming has also been observed by other researchers. Stylos and Myers [30] identified ex-
ample usage as one of the high-level activities involved in API learning while observing computer science graduate students performing three small programming projects in Java. Brandt et al. [9] conducted a laboratory study in which graduate students used Blueprint, a Web search interface that helps users locate example code. In their report they describe an example-centric behavior of Jenny, one of the participants in a controlled experiment. I was excited. Adam, in contrast to Jenny, was performing example-centric development ‘in the wild’. It was not done in laboratory settings, but as part of Adam’s real development task. The potential of methodological and effective example usage in professional software development became concrete. My mind started wandering to other activities and purposes in which example usage can be beneficial such as learning purposes, code comprehension, feature implementation, solving problems, and many more. Indeed, the literature describes many benefits of systematic and habitual example usage, for software companies as well as for individuals. These include raising levels of software reuse [18][19], increasing productivity [28], improving code quality [23], enforcing consistency in design [15][24] and coding standards [7], and establishing an effective knowledge transfer mechanism both inside and outside an organization [29]. What if we take it even further and consider not only example centric programming practices but an example centric software development paradigm? Gabel and Su [14] discuss the possibility of a “singularity” in software engineering’s future: a point of convergence at which all necessary software will have been produced. While they believe this question is of intrinsic academic interest, they also point out several practical applications and consequences, including automation of programming, development tool research and code reuse. Imagine what a programming course would be like after singularity has been reached. What if we reach a point at which not all possible software has been produced, but only 50%? What would be our strategy then?
“Used Cars, Good Used Cars. Cheap transportation, three trailers. '27 Ford, clean. Checked cars, guaranteed cars. Free radio. Car with 100 gallons of gas free. Come in and look. Used Cars. No overhead.” The Grapes of Wrath by John Steinbeck
Consider the following thought experiment: Imagine that you are in the middle of a huge junkyard full of cars and
car parts. Millions of cars and gazillions of parts. Some of them are old, some might be broken, but some of them might still be good, or have some decent parts in them. Imagine that you are a mechanic – how would you take advantage of the situation, assuming you are allowed to take whatever you like, free of charge? Now, imagine that this junkyard is actually the internet, the cars are applications, and the parts are code snippets. As a developer, how could you make use of that? Under what circumstances? What would be the benefits? What barriers exist? Who is in a better situation – the developer or the mechanic? Why? Most of the developers I met during my research did not use examples as systematically as did Adam. They were mindful of getting the job done, and if using examples was too cumbersome, too risky or not handy, they just managed to do without. My research subjects did not use examples as extensively as reported by recent example-centric and opportunistic development studies [8]. In some cases they were not attentive to using examples, in other cases they preferred to write the code themselves, or found themselves struggling against the inherent challenges that accompany example usage. When I discussed example usage issues with professional developers they raised different kinds of concerns: technical, organizational and social. Prima facie, the current state of example usage in software development is unfortunate. On the one hand, there is huge potential – piles and piles of existing code waiting to be reused; on the other hand, developers are not using it for several reasons, some of which are inherent, others accidental.
4. The Software Engineering Rumpelstiltskin In order to address the challenges involved with extensive example usage, we must first name this thing, this software activity. It is hard to address an issue if it has no name; simply talking about ‘using examples’ is not enough. A parallel can be found in the conceptualization of the term refactoring [13]. The distinction between refactoring and 'just rewriting' provided the software engineering vocabulary with new abstractions, and promoted the formulation of new techniques, practices and tools. Moreover, both refactoring and example usage are activities that developers perform both implicitly and inevitably. Doing them in a non-methodological manner can, however, introduce problems and bugs or prevent us from leveraging their full potential. To emphasize the importance of a name, let us review the refactoring case more carefully. Refactoring is defined [11] as a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior. Although refactoring code has
been performed informally for years, William Opdyke's 1993 PhD dissertation [27] is the first known resource that specifically examines refactoring. The mere identification of refactoring as an activity, as well as its naming and definition, promoted the following important processes: •
First, it laid the foundations for others to build a catalog of different examples of refactorings [13], some of which are also available online [12], prescribing their proper application and discussing their subtleties. Such catalogs also contributed to raising the level of abstraction in software design. The various refactorings serve as design building blocks and allow designers, for example, to speak about an ‘extract method’ without needing to explain it.
•
Second, it enabled the development of software tools that systematically apply various refactoring activities to existing code whilst ensuring their correctness2.
•
Third, it influenced the coding practices, the way in which programmers write code, using, for example, test-driven development techniques [5].
•
And fourth, it affected the software construction lifecycle by allowing the design phase to be incorporated into the coding phase, as manifested in the agile methodologies [6], and by legitimizing time allocation for activities that improve the code without adding functionality.
These advancements would not have been possible had the refactoring activity not been extracted from the various activities that constitute the coding phase. In retrospect, it is clear that refactoring is much more profound than a mere ‘technique’; refactoring is a fundamental software activity. It is a conceptualization of the key principle that software is not only written but also rewritten. In fact, code is only written once but may be rewritten many times. Refactoring is an inherent part of software construction that is manifested in various forms and scales, from renaming local variables to system-wide architectural changes. Moreover, refactoring does not only serve as an enabler for the above advancements; it is also enabled and legitimized by them. One of the clichés of software engineering states: "If it ain't broken – don't fix it!" which is exactly opposite in spirit to the rationale for refactoring. This contradiction is settled by what I call the software engineering ecosystem – the symbiotic relations between the various components involved in software construction – which together compensate for the pitfalls of a certain activity.
2
http://en.wikipedia.org/wiki/Code_refactoring#Automated_code_refactoring
Refactoring is supported by the ecosystem as follows: comprehensive refactoring catalogs describe a wide variety of possible refactoring activities, provide useful information on their systematic application, and highlight their subtleties. Automatic refactoring tools reduce the probability that the code change introduces a bug into the system. Agile practices, such as test-driven development, guide developers to refactor the code only after a new addition is introduced and tested, thus avoiding spending precious time on unnecessary cosmetic changes. A software process that promotes refactoring also promotes simple design to allow easier application of future refactorings as well as to save time, knowing that this time investment will save time in future stages during the system growth. Moreover, refactoring is weaved into the ecosystem, so that gaining the developers’ explicit attentiveness is no longer an issue; refactoring is inherent in the use of tools or in following the development process.
“So much has been done, exclaimed the soul of Frankenstein—more, far more, will I achieve; treading in the steps already marked, I will pioneer a new way, explore unknown powers, and unfold to the world the deepest mysteries of creation.” Frankenstein by Mary Shelley
5. The Example-Embedding Ecosystem Let us define example embedding as a methodological and disciplined use of existing code in a new context [1]. Using Guy Steele's definition3, an example is "some one thing, out of a set of things, which I put in front of you so that you can see how some part of that thing is in fact a part of each thing in the set." Once the term is in place, we can start talking about an ecosystem that promotes and facilitates extensive example usage. As in the case of refactoring, example embedding also goes beyond being a mere programming technique and should be manifested in software development tools and processes, as well as in training, best practices, and the organizational culture, as elaborated below.
3
http://video.google.com/videoplay?docid=-8860158196198824415
5.1
Attentiveness
The definition and characterization of example embedding raises awareness of code reuse. Although programming languages offer constructs for code reuse such as functions, objects, and inheritance mechanisms, code reuse should also be performed explicitly by the developer. Moreover, reuse should not be limited to the use of code as is, but rather, should be applied more freely, as long as the resulting unit is tested thoroughly. The difference between example embedding and conventional black-box reuse [20] is analogous to the difference between refactoring and thorough design. Specifically, just like refactoring liberated us from the need for an elaborate design phase, example embedding aims at liberating us from the belief that we can only reuse code as is. 5.2
Recipe Catalogs and Example Repositories
A recipe catalog is a detailed and comprehensive description of all known instances of a certain software activity. Gamma et al. [16] present a good example of a catalog of design patterns. Fowler [11] offers a comprehensive online catalog for refactoring. Like in cookbooks, where different dishes require different degrees of attention, so do software activities in recipe catalogs. Two major tasks are involved in building a recipe catalog: First, classification and categorization of the differences between the various instances of the software activity, and second, description of the recipes including a comprehensive discussion of each, highlighting its subtleties, best practices and common variants. The open source community, as well as numerous technical blogs and community web sites, put online a vast amount of free source code, ranging from mere snippets to full-blown products. This code embodies the software development community's domain knowledge. This knowledge takes the form of the internet on which it is found – it is distributed rather than hierarchical; it is chaotic, incomplete, and inconsistent. One might think of extracting these code snippets in a systematic way and putting them in a structured form, which would be searchable. Such repositories could rank the quality of these code snippets and document their context, which make them easier to browse and reuse. 5.3
Practices
Many developers perceive example usage as a searching task. They think a perfect code snippet exists, which is an exact match to what they need, and is just waiting to be found. This is not always the case. Example usage often requires browsing through multiple examples, comparing and assessing them, identifying corner cases, and possibly merging code from several sources.
To use examples effectively, one must first identify and sequence the building blocks of effective example usage. Some of these building blocks include browsing, commenting, learning, modifying, refactoring, running, testing, understanding, and writing. One of the arguments voiced by example usage opponents is that extensive example usage will compromise the quality of the code produced over time. They claim the practice will produce a Frankenstein code that will be difficult to understand and to maintain. The various abovementioned activities could, when put in place, assist the developer in addressing these concerns. Code inspection practices will provide the developer with tools to evaluate the quality of the code, refactoring of the code will assist in maintaining system integrity, and testing (even black box testing) will ensure that the code behaves as expected. Another argument against using existing code snippets is that it results in code duplication, which is considered to be bad. However, ignoring existing code and writing it all over again is no better than code duplication. Furthermore, once a relevant code snippet is found (i.e., the example) the developer can (and should!) refactor the code to remove undesired redundancy. In order to be commonly applied, the example embedding concept must be broken down into digestible practices that the developer can more easily embrace. Consider, for example, the following hypothetical rules of thumb: Any time you look for an example on the internet, you must find at least 3 variations of the required functionality; Any time you use a code that you have not written yourself, you must provide a reference to the original copy of that code (on the Web or in another project); Any time you write a piece of functionality by yourself, you must list (maybe as part of the code review process) all places you checked to see if this functionality has not already been implemented elsewhere, and so can be reused. 5.4
Development Process
The development process is an umbrella term encompassing the software lifecycle, the use of programming practices, the organizational culture, and more. Introducing examples into the development process must be addressed at the organizational level. The software organization should encourage and legitimize example usage, and maintain a strict policy about its caveats (e.g., licensing and protecting intellectual property). Examples can be considered at various stages of the development process and at various granularities, including coding, documentation, training, and testing. From a cultural perspective, considering code reuse as the fundamental activity challenges the classic image of the software developer, who is perceived by some as a scientist, an engineer or even an artist [22]. A creation process is
often considered nobler than a reformation process; in the same way that an architect enjoys more prestige than does a handyman, so does the classic programmer aspire to be held in high regard, contrary to the developers quoted in [3] who said: "At the end of the day, we are all merely plumbers...". An organization that aspires to promote and encourage code reuse via extensive example usage should address this issue explicitly and highlight the creativity that lies in the composition of existing pieces. An interesting addition to the development process would be writing examples. I argue that every programmer should provide examples that illustrate how each code snippet he or she writes can be used. This should be anchored in the development process much like testing and documentation; as programmers are expected to document and test their code, so should they be expected to write examples that use their code. Systematic enforcement of example writing would strive to create example coverage of the code. Example coverage promotes building blocks with inner strength and weak decoupling, and hence are reusable. Making example writing a habit would make it easier to build in-house example repositories. Java guru Joshua Bloch describes the centrality of examples in software development and the importance of writing good examples: “Code lives on as examples… [API] examples tend to get emulated heavily. If you get them right you've seeded the market with good uses of your API. If you get them wrong, conversely, you've ensured that there will be broken programs floating around the web for years. Example programs should be exemplary. […] My rule of thumb is you should spend 10 times as much time on example code as you do on production code”.4 5.5
Tools
Software tools are useful for activity implementation in at least two ways. First, it is easier to identify repetitive tasks if a key activity has been identified. In many cases, these tasks can then be automated or at least supported by an automatic software tool that performs them easily while, in some cases, enhancing accuracy. Second, a software tool may help capture and streamline the sub-elements of the software activity. Such a framework guides the developer along the activity’s major steps. For example, the xUnit software tool [5] provides not only support for repetitive tasks introducing a large set of assertions, but also a method of streamlining the setup-test-teardown sequence. Another important aspect to consider when adopting a new software tool, and consequently a new practice, is tool integration. Modern integrated development environments
4
http://www.youtube.com/watch?v=aAb7hSCtvGw
(IDEs) create new opportunities for augmenting existing development environments with new tools, deployed as plugins, and relieving the context-switch involved in using an external standalone tool. When I reviewed the practices involved in example embedding, I listed a few of the activity's potential building blocks. Tool support should address each of these activities individually, as well as the integration between them, for example, by including IDE-example repository integration [25] [17] [9] and IDE-browser integration. Consider an IDE autocomplete mechanism extension (e.g. Microsoft’s IntelliSense) that, in addition to function signature, brings you desirable code snippets from the Web. Imagine that this tool is able to extract relevant code examples (similar to the extract method refactoring), using slicing or some other techniques of code analysis [21] [31], and embed them in the new context maintaining parameter names and styling conventions 5.6
Training
In my experience, many academic computer science and software engineering training programs do not give modern development activities and practices the attention they deserve. Moreover, such programs teach the writing of programs from scratch as the fundamental skill of software development. Only in advanced courses, where such exist, do students encounter other development scenarios such as maintenance, building on top of existing systems, agile processes, and so on. One can imagine an opposite approach in which writing programs from scratch is considered to be an advanced topic, while the fundamentals of software engineering are, say, reading and understanding existing code. Consider how students learn a foreign language in school; at least in my school, reading comprehension questions and unseen-passage questions came before the writing of essays. Obrenović et al [26] report that using opportunistic software development principles in software engineering education encourages students to be creative, innovative, and to develop solutions that cross the boundaries of different technologies. Carr [10] suggests, on the other hand, that search-oriented information retrieval behavior might have a negative effect on a person's ability to stay focused for long. In his article "Is Google Making Us Stupid?" he quotes Maryanne Wolf [32] who said: "We are not only what we read – we are how we read". When we read online, she says, we tend to become "mere decoders of information." Our ability to interpret text, to make the rich mental connections that form when we read deeply and without distraction, remains largely disengaged.
6. The Case of Referencing Previous Academic Work Let us revisit the ecosystem concept by investigating another case of building upon previous work, this time outside the software construction domain. Such is the case of the referencing of previous and related work in academic research. Academic work is not performed in a void. Progress in research is achieved by the accumulation of knowledge. Standing on others’ shoulders allows all researchers to see farther than they could on their own. Furthermore, referencing previous and related work situates the current work in context and allows the community to appreciate its unique contribution. Indeed, referencing previous work is a fundamental part of academic research. Let us investigate how referencing previous academic work is woven into the academic ecosystem: Catalogs and repositories – Academic work is organized in libraries. The ACM digital library is one example of such a library in the domain of computer science and related areas. Works are organized by categories, keywords, and technical terms, so that items can be easily found and browsed through. Tools and technologies – Extensive incorporation of references into large works is a tedious, exhausting and errorprone activity. Software tools exist, however, to assist in managing this process. In this work, for example, I used the BibTeX format and tools to organize and arrange its references. Process – Previous academic work can shape the research process in different ways. One course of research may be driven by previous work. Another may start with a clean slate, and only after obtaining results may previous work be used to situate them in context and within a theoretical framework. Community – The academic community enforces the referencing of academic work by rejecting articles for publication if their authors fail to cite previous and related work. This works because an awareness of the issue is integrated into the peer review mechanism. Practices – Some people find it easier to write from scratch than to incorporate new contributions into an existing framework. This requires the practitioner to develop appropriate skills and techniques for presenting previous work in new research. Training – Many graduate schools offer scientific writing courses in which referencing issues are also discussed. Such courses often provide the novice with practical advice regarding whom to reference, the dates of the references, their accessibility, ranking, and so on.
Although the analogy to software construction works only to a certain extent, the mechanism described above for incorporating previous work into the academic ecosystem may offer inspiration for integrating example usage into the software engineering ecosystem.
7. Summary Example embedding goes beyond being a mere programming technique. It should be considered as a fundamental software construction activity and an expression of community knowledge accumulation and of the software reuse principle. Habitual and methodological example usage expresses awareness of the existing body of knowledge and promotes faster and better code writing. In this essay I outlined an ecosystem, a comprehensive approach towards example usage, that takes into account various aspects of software development. Many developers claim to use examples all the time and for every purpose; we are, however, lagging behind in providing them the tools, both technical and conceptual, to do so effectively.
References [1] O. Barzilay, O. Hazzan, and A. Yehudai. Characterizing example embedding as a software activity. In SUITE 2009: Proceedings of the 1st international workshop on SearchDriven Development - Users, Infrastructure, Tools and Evaluation at ICSE ’09, pages 9–12. IEEE Computer Society, 2009. [2] O. Barzilay, O. Hazzan, and A. Yehudai. Using social media to study the diversity of example usage among professional developers. In Proceedings of the 19th ACM SIGSOFT symposium and the 13th European conference on Foundations of software engineering, SIGSOFT/FSE ’11, pages 472–475, New York, NY, USA, 2011. ACM. [3] O. Barzilay, A. Yehudai, and O. Hazzan. Developers attentiveness to example usage. In Human Aspects of Software Engineering, HAoSE ’10, pages 1–8, NY, USA, 2010. ACM. [4] K. Beck. Extreme Programming Explained: Change. Addison-Wesley Professional, 1999.
Embrace
[5] K. Beck. Test Driven Development: By Example. AddisonWesley, 2002. [6] K. Beck and M. Fowler. Planning Extreme Programming. Addison-Wesley Professional, 2000. [7] B. Bokowski. Coffeestrainer: statically-checked constraints on the definition and use of types in java. In Proceedings of the 7th European software engineering conference held jointly with the 7th ACM SIGSOFT international symposium on Foundations of software engineering, ESEC/FSE-7, pages 355–374, London, UK, 1999. Springer-Verlag. [8] J. Brandt. Example-Centric Programming: Integrating Web Search into the Development Process. PhD thesis, Stanford University, 2010.
[9] J. Brandt, M. Dontcheva, M. Weskamp, and S. R. Klemmer. Example-centric programming: integrating web search into the development environment. In Proceedings of the 28th international conference on Human factors in computing systems, CHI ’10, pages 513–522, NY, USA, 2010. ACM. [10] N. Carr. Is Google making us stupid? The Atlantic, July 2008. [11] M. Fowler. Refactoring www.refactoring.com.
Home
Page.
http://-
[12] M. Fowler. Refactorings in alphabetical order. http://refactoring.com/catalog/index.html. [13] M. Fowler. Refactoring: Improving the Design of Existing Code. Addison-Wesley, 1999. [14] M. Gabel and Z. Su. A study of the uniqueness of source code. In Proceedings of the eighteenth ACM SIGSOFT international symposium on Foundations of software engineering, FSE ’10, pages 147–156, New York, NY, USA, 2010. ACM. [15] E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design patterns: Abstraction and reuse of object-oriented design. In O. Nierstrasz, editor, ECOOP ’93 – Object-Oriented Programming, volume 707 of Lecture Notes in Computer Science, pages 406–431. Springer Berlin / Heidelberg, 1993. [16] E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design patterns: elements of reusable object-oriented software. Addison-Wesley, 1995. [17] R. Holmes and G. C. Murphy. Using structural context to recommend source code examples. In ICSE ’05: Proceedings of the 27th international conference on Software engineering, pages 117–125. ACM, 2005. [18] I. Jacobson, M. Griss, and P. Jonsson. Software reuse: architecture, process and organization for business success. ACM Press/Addison-Wesley Publishing Co., NY, USA, 1997. [19] E. A. Karlsson. Software Reuse: A Holistic Approach. John Wiley & Sons, Chichester, 1998. [20] G. Kiczales. Beyond the black box: Open implementation. IEEE Softw., 13(1):8–11, 1996. [21] M. Kim, L. Bergman, T. Lau, and D. Notkin. An ethnographic study of copy and paste programming practices in OOPL. In ISESE ’04: Proceedings of the 2004 International Sympo-
sium on Empirical Software Engineering, pages 83–92. IEEE Computer Society, 2004. [22] D. E. Knuth. The art of computer programming. AddisonWiley, 1968. [23] W. Lim. Effects of reuse on quality, productivity, and economics. Software, IEEE, 11(5):23 –30, Sept. 1994. [24] M. Nanard, J. Nanard, and P. Kahn. Pushing reuse in hypermedia design: golden rules, design patterns and constructive templates. In Proceedings of the ninth ACM conference on Hypertext and hypermedia: links, objects, time and space— structure in hypermedia systems, HYPERTEXT ’98, pages 11–20, New York, NY, USA, 1998. ACM. [25] L. R. Neal. A system for example-based programming. SIGCHI Bull., 20(SI):63–68, 1989. [26] Z. Obrenovic, D. Gasevic, and A. Eliëns. Stimulating creativity through opportunistic software development. IEEE Softw., 25(6):64–70, 2008. [27] W. F. Opdyke. Refactoring Object-Oriented Frameworks. PhD thesis, University of Illinois at Urbana-Champaign, 1993. [28] D. F. Redmiles. Reducing the variability of programmers’ performance through explained examples. In Proceedings of the INTERACT ’93 and CHI ’93 conference on Human factors in computing systems, CHI ’93, pages 67–73, New York, NY, USA, 1993. ACM. [29] I. Rus and M. Lindvall. Guest editors’ introduction: Knowledge management in software engineering. IEEE Software, 19:26–38, 2002. [30] J. Stylos and B. Myers. Mica: A web-search tool for finding api components and examples. In Visual Languages and Human-Centric Computing, 2006. VL/HCC 2006. IEEE Symposium on, pages 195 –202, 2006. [31] M. Weiser. Program slicing. In Proceedings of the 5th international conference on Software engineering, ICSE ’81, pages 439–449, Piscataway, NJ, USA, 1981. IEEE Press. [32] M. Wolf. Proust and the squid : the story and science of the reading brain. HarperCollins, NY, 2007.