Generic programming is an effective methodology for developing reusable software libraries. Many programming languages provide generics and have features for describing interfaces, but none completely support the idioms used in generic programming. To address this need we developed the language G. The central feature of G is the concept, a mechanism for organizing constraints on generics that is inspired by the needs of modern C++ libraries. G provides modular type checking and separate compilation (even of generics). These characteristics support modular software development, especially the smooth integration of independently developed components. In this article we present the rationale for the design of G and demonstrate the expressiveness of G with two case studies: porting the Standard Template Library and the Boost Graph Library from C++ to G. The design of G shares much in common with the concept extension proposed for the next C++ Standard (the authors participated in its design) but there are important differences described in this article.
Deep Dive into A Language for Generic Programming in the Large.
Generic programming is an effective methodology for developing reusable software libraries. Many programming languages provide generics and have features for describing interfaces, but none completely support the idioms used in generic programming. To address this need we developed the language G. The central feature of G is the concept, a mechanism for organizing constraints on generics that is inspired by the needs of modern C++ libraries. G provides modular type checking and separate compilation (even of generics). These characteristics support modular software development, especially the smooth integration of independently developed components. In this article we present the rationale for the design of G and demonstrate the expressiveness of G with two case studies: porting the Standard Template Library and the Boost Graph Library from C++ to G. The design of G shares much in common with the concept extension proposed for the next C++ Standard (the authors participated in its desig
The 1968 NATO Conference on Software Engineering identified a software crisis affecting large systems such as IBM's OS/360 and the SABRE airline reservation system [1,2]. At this conference McIlroy gave an invited talk entitled Mass-produced Software Components [3] proposing the systematic creation of reusable software components as a solution to the software crisis. He observed that most software is created from similar building blocks, so programmer productivity would be increased if a standard set of blocks could be shared among many software products. We are beginning to see the benefits of software reuse; Douglas McIlroy's vision is gradually becoming a reality. The number of commercial and open source software libraries is steadily growing and application builders often turn to libraries for user-interface components, database access, report creation, numerical routines, and network communication, to name a few. Furthermore, larger software companies have benefited from the creation of in-house domainspecific libraries which they use to support entire software product lines [4].
As the field of software engineering progresses, we learn better techniques for building reusable software. In the 1980s Musser and Stepanov developed a methodology for creating highly reusable algorithm libraries [5,6,7,8], using the term generic programming for their work. 1 Their approach was novel in that they wrote algorithms not in terms of particular data structures but rather in terms of abstract requirements on structures based on the needs of the algorithm. Such generic algorithms could operate on any data structure provided that it meet the specified requirements. Preliminary versions of their generic algorithms were implemented in Scheme, Ada, and C. In the early 1990s Stepanov and Musser took advantage of the template feature of C ++ [9] to construct the Standard Template Library (STL) [10,11]. The STL became part of the C ++ Standard, which brought generic programming into the mainstream. Since then, the methodology has been successfully applied to the creation of libraries in numerous domains [12,13,14,15,16].
The ease with which programmers develop and use generic libraries varies greatly depending on the language features available for expressing polymorphism and requirements on type parameters. In 2003 we performed a comparative study of modern language support for generic programming [17]. The initial study included C ++ , SML, Haskel, Eiffel, Java, and C#, and we evaluated the languages by porting a representative subset of the Boost Graph Library [13] to each of them. We recently updated the study to include OCaml and Cecil [18]. While some languages performed quite well, none were ideal for generic programming.
Unsatisfied with the state of the art, we began to investigate how to improve language support for generic programming. In general we wanted a language that could express the idioms of generic programming while also providing modular type checking and separate compilation. In the context of generics, modular type checking means that a generic function or class can be type checked independently of any instantiation and that the type check guarantees that any welltyped instantiation will produce well-typed code. Separate compilation is the ability to compile a generic function to native assembly code that can be linked into an application in constant time.
Our desire for modular type checking was a reaction to serious problems that plague the development and use of C ++ template libraries. A C ++ template definition is not type checked until after it is instantiated, making templates difficult to validate in isolation. Even worse, clients of template libraries are exposed to confusing error messages when they accidentally misuse the library. For example, the following code tries to use stable_sort with the iterators from the list class.
std::list l; std::stable_sort(l.begin(), l.end()); Fig. 1 shows a portion of the error message from GNU C ++ . The error message includes functions and types that the client should not have to know about such as __inplace_stable_sort and _List_iterator. It is not clear from the error message who is responsible for the error. The error message points inside the STL so the client might conclude that there is an error in the STL. This problem is not specific to the GNU C ++ implementation, but is instead a symptom of the delayed type checking mandated by the C ++ language definition. stl algo.h: In function ‘void std:: inplace stable sort( RandomAccessIter, RandomAccessIter)
[with RandomAccessIter = std:: List iterator<int, int&, int * >]’: stl algo.h:2565: instantiated from ‘void std::stable sort( RandomAccessIter, RandomAccessIter)
[with RandomAccessIter = std:: List iterator<int, int&, int * >]’ stable sort error.cpp:5: instantiated from here stl algo.h:2345: error: no match for ‘std:: List iterator<int, int&, int * >& std:: List iterator<int, int&, int *
…(Full text truncated)…
This content is AI-processed based on ArXiv data.