C(ID:577/c::002)Unix systems programming languageDennis Ritchie, Bell Labs, ca. 1972. Originally a systems language for Unix on the PDP-11, briefly named NB. Influenced by BCPL through Thompson's B. Terse, low-level and permissive. Preprocessor. Partly due to its distribution with Unix, C became the language most widely used for software implementation. Places People: Structures: Related languages
References: in SIGPLAN Notices 13(11) Nov 1978 view details in SIGPLAN Notices 13(11) Nov 1978 view details Introduction While it is not yet clear whether Ada, BLISS, Mary/2, Modula-2, Mesa, C, CLU, Edison, Concurrent Euclid, Icon, Newton, PLAIN, PLUS, Praxis, Smalltalk, SQURL, Y, or some other language is "best" for systems programming, each language represents an advance towards the goal of supporting an understandable and efficient organization of the many details and relationships inherent in systems programming. Unfortunately, no one language has yet achieved the delicate balance between simplicity and power that would distinguish it as ideal, but it appears that Modula-2 comes quite close. Modula-2 represents a step forward in language design, both because it incorporates existing features instead of inventing its own, and because of its evident concern for simplicity. Modula-2 offers the following valuable language features: Simplicity. Few primitive datatypes are defined, few control constructs are supported (there is no "go to"), and input-output operations are not provided as part of the language (they can be provided via extensions written in Modula-2). This simplicity allows for easier standardization and better portability than can be achieved with most other languages. Modules A module is a named collection of variables and procedures, similar to an Ada package. It controls the interfacing and encapsulation of the conceptual parts making up large software systems. Modules provide a more flexible solution to the problem of partitioning the name space of a large program than does the more familiar hierarchical nesting of procedures. They are so valuable they are even being force-fitted onto existing languages. Separate Compilation. Modules may be compiled separately, providing good management for large programsr and definition modules allow for specifying interfaces without giving implementation details. Flexible Datatypes. Strong datatypes are enforced, but this can be relaxed when necessary in systems programming to just declaring a parameter to be a word, an address, or an array of words. Machine Access. Access to specific memory addresses and other characteristics of the underlying machine is supported. Tasking. Flexible and efficient tasking is provided by coroutine management routines. in SIGPLAN Notices 17(08) August 1982 view details in SIGPLAN Notices 17(08) August 1982 view details in Computer Languages 13(2) view details Extract: Introduction Introduction Calico is a new C-based object-oriented language supported by an integrated software-development environment. We designed Calico to provide a rapid development environment for object-oriented systems that would leverage off of the Unix/C environment and provide strengths from several languages and systems, including Smalltalk, CLOS, C++, and Eiffel. None of these languages directly addressed our needs, but each contributed ideas we wanted to develop and use. Calico introduces some unique language features, but its primary contribution is the productivity advantage that this feature integration provided to the Unix/C environment. Calico features + a simple, uniformly applied object model, + a syntax easily mastered by C programmers, + a new multiple inheritance model, + simple method-call semantics with some novel extensions, and + effective support for the team development process. Extract: DEVELOPMENT GOALS DEVELOPMENT GOALS We designed Calico because we wanted to significantly increase the productivity of teams programming in the Unix/C environment. This led to the following design requirements for Calico: It should have a uniformly applied object model, in which all data items are (conceptually, at least) objects whose behavior is defined by a class and whose encapsulation is preserved in all programming aspects. Although we wanted multiple inheritance for design flexibility, we required that it add minimal complexity to the language. We felt that inheritance should maintain strict encapsulation of and paradigms in a way that amplifies the natural strengths of Unix and C. Extract: DEVELOPMENT GOALS DEVELOPMENT GOALS We designed Calico because we wanted to significantly increase the productivity of teams programming in the Unix/C environment. This led to the following design requirements for Calico: + It should have a uniformly applied object model, in which all data items are (conceptually, at least) objects whose behavior is defined by a class and whose encapsulation is preserved in all programming aspects. Although we wanted multiple inheritance for design flexibility, we required that it add minimal complexity to the language. We felt that inheritance should maintain strict encapsulation of classes so large projects would remain manageable even when developrs had to cooperate as suppliers and users of inheritance relationships. + It should have an efficient, unobtrusive, automatic storage-management system (a garbage collector) that, with the uniform object model, would free programmers from all concerns related to explicit use of pointers and release of dynamic storage. + It should provide a very rapid compile/ edit/debug cycle - as fast as that offered by Lisp and Smalltalk environments. + It should provide easy integration with new and existing C code. We wanted programmers to be able to use ordinary Unix tools (like SCCS, Grep, and Sed) at any point in the development process. This ability should apply to source code, binary programs, and, whenever possible, data. + It should support team development by making it easy to share files and to view an application?s source code hierarchically and multidimensionally. (Dimensions include the application?s structure and its multiple versions.) We wanted to provide an environment that combined support for controlling shared source and object code among team members with a highly interactive, tightly integrated environment for individual programmers. We designed and implemented Calico because we knew ofno available languageenvironment combination that met these requirements. Calico?s strength lies in its prudent integration of existing techniques and paradigms in a way that amplifies the natural strengths of Unix and C. Extract: LANGUAGE FEATURES LANGUAGE FEATURES The Calico language is distinguished from its predecessors by seamlessly integrating: + A C calling interface: Calico flexibly interoperates with C by calling C routines in a syntactically simple and natural way + An integrated reflection mechanism: Calico?s flexible method-call options provide a form of reflection. + C syntax: Calico?s statement and expression syntax is very close to C?s, yet it implements all data manipulations as method calls on first-class objects, like Smalltalk + An encapsulation-preserving inheritance model: Calico?s inheritance model uses delegation and is based solely on on 0bject interfaces Extract: Summary Calico offers the C community a powerful programming style that has until now been available only for languages like Lisp and Smalltalk. The ease with which Calico and C code can be integrated lets developers make the necessary trade-offs between productivity and performance. For most large applications, supplementing Calico with C or C++ provides a very effective trade-off between application speed and rapid delivery. To a great extent, the power and responsiveness of the Calico programming environment is due to the nature of the Calico language, which, unlike C and C++, has no source-level interfile dependencies. The design of the Calico environment stemmed born a conscious effort to maintain encapsulation and avoid interclass dependencies in the language?s design and implementation. Fortunately, the same paradigm that encourages good application design also supports a high-productivity development environment. Calico makes it easy for C users to learn object-oriented programming techniques because its expressions and control statements behave in a way that C programmers understand. This lets new Calico users focus on the object paradigm instead of trying to learn a totally new syntax, semantics, and paradigm at the same time. Calico?s close adherence to C syntax makes it easier for users to work concurrently in C and Calico and to combine the two in the same application. in IEEE Software 8(3) May 1991 view details in IEEE Software 8(3) May 1991 view details in IEEE Software 8(3) May 1991 view details in IEEE Software 8(3) May 1991 view details OBJECT-ORIENTED PROGRAMMING AND C Born in a log cabinet, C quickly rose to prominence. Although most people interested in both C and object technology have focused on the O-O extensions of C discussed in the next chapter (C++, Objective-C, Java), it remains interesting to see how C itself can be made to emulate O-O concepts, if only to understand the techniques that have made C so useful as a stepping stone towards the implementation of more advanced languages. Some context C was designed at AT&T’s Bell Laboratories as a portable language for writing operating systems. The first version of Unix had used assembly language, but a portable version soon appeared necessary, and C was designed around 1970 to make it possible. It was derived from ideas found in BCPL, a language of the sixties which, like C, can be mentioned in the same breath as “high-level”, “machine-oriented” and “portable”: highlevel thanks to control structures comparable to those of Algol or Pascal; machineoriented because you can manipulate data at the most elementary level, through addresses, pointers and bytes; portable because the machine-oriented concepts are so defined as to cover a wide variety of computer types. C’s timing could not have been better. In the late seventies Unix became the operating system of choice for many universities, and C spread with it. Then in the eighties the microcomputer revolution burst out, and C was ready to serve as its lingua franca — more scalable than Basic, more flexible than Pascal. At the same time Unix also enjoyed some commercial success, and along with Unix still came C. In a few years, a boutique product became the dominant language in large segments of the computing industry, including much of where the action really was. Anyone interested in the progress of programming languages — even people who do not care too much for the language itself — has a political debt to C, and sometimes a technical one as well: • Politically, C ended the fossilized situation that prevailed in the programming language world until around 1980. No one in industry wanted to hear (particularly after the commercial failure of Algol) about anything else than the sacred troika, Fortran for science, Cobol for business and PL/I for true blue shops. Outside of academic circles and a few R&D departments, any attempt at suggesting other solutions was met with as much enthusiasm as if it were a proposal to introduce a third brand of Cola drink. C broke that mindset, making it acceptable to think of the programming language as something you choose from a reasonably broad and evolving catalog. (A few years later, C itself became so entrenched that in some circles the choices seemed to have gone from three to one, but it is the fate of successful subversives that they become the new Establishment.) • Technically, the portability and machine-closeness of C have made it an attractive solution as a target language of compilers for higher-level languages. The first C++ and Objective-C implementations used this approach, and compilers for many other languages, often having no visible connection to C, have followed their example. The advantages for the compiler writers and their users are: portability, since you can have a single C-generating compiler for your language and use C compilers (available nowadays for almost any computer architecture) to take care of platform dependencies; efficiency, since you can rely on the extensive optimization techniques that have been implemented in good C compilers; and ease of integration with ubiquitous C-based tools and components. With time, the contradiction between the two views of C — high-level programming language, and portable assembly language — has become more acute. Recent evolution of the ANSI standard for C (first published in 1990, following the earlier version known as K&R from the authors of the first C book, Kernighan and Ritchie) have made the language more typed — and hence less convenient for its use as a compiler’s target code. It has even been announced that forthcoming versions will have a notion of class, obscuring the separation from C++ and Java. Although an O-O extension of C simpler than C++ and Java may be desirable, one can wonder whether this evolution is the right one for C; a hybrid C-based O-O language will always remain a strange contraption, whereas the idea of a simple, portable, universally available, efficiently compilable machine-oriented language, serving both as a target language for high-level compilers and as a low-level tool for writing very short routines to access operating system and machine-dependent facilities (that is to say, for doing the same thing that assembly language used to do for C, only at the next level) remains as useful as it ever was. External link: online copy in IEEE Software 8(3) May 1991 view details in IEEE Software 8(3) May 1991 view details |