new@udel.EDU (09/28/89)
One thing I have always liked about the C language was the separation between the "header" files (.h) and the "code" files (.c). In other languages, such as Modula-II and (I think) Ada, it is not possible to define multiple "implementation" modules for a single "definition" module. Note that I mean multiple implementation modules implementing different parts of the same header module; I do not mean different complete implementations of the same header module. For example, in C I can make one header file that defines the prototype information for all the string functions. I can then write each string function into a different implementation file. Thus, with one "include" (Import) statement, I get all the declarations for all the string functions. However, the linker only links in the functions I use. As another example, all the file stuff is in "stdio.h". However, it can be implemented with open, read, write, close, and delete in five different code files, allowing me to avoid loading the writing code if I don't write, allowing me to link the open/close in one overlay and the read/write in another overlay, and allowing me to avoid recompiling the entire I/O library when making a change to just one routine. I know of no other compiled language defined in this way (except, of couse, C++). This would be less of an issue if linkers or compilers were smart enough to only include the functions from a single module that were actually used and if we all had demand-paged VM. Even this, however, would not solve the "recompile everything" problem. I know very little Ada, but it seems to me that I've not heard of this ability in Ada. Does anyone know of any relatively popular languages that allow this sort of separation other than C and C++? If not, why not? Discussion? -- Darren
billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (09/28/89)
From article <24955@louie.udel.EDU>, by new@udel.EDU: > [Header files idea] > This would be less of an issue if linkers or compilers were smart > enough to only include the functions from a single module that were > actually used and if we all had demand-paged VM. Even this, however, > would not solve the "recompile everything" problem. I know very little > Ada, but it seems to me that I've not heard of this ability in Ada. Try the Telesoft TeleGen2 compiler. If you want the really serious details of how extensive the optimization is in this compiler, take a look at the Tri-Ada '88 proceedings; I believe there are several articles just on this one compiler's heavy-duty optimization strategies. This particular optimization is almost essential if one is to properly support ADTs (one of the things Ada is really good at doing), since the user will almost never use all of the ADT services provided. It would really be kind of ridiculous NOT to trim away the extra code. As far as recompilation is concerned, you can make use of Ada's separate compilation facility to achieve this directly. I don't do this because it would be a pain to have things scattered into umpteen different files, and I have no idea why you would consider this to be desirable. Bill Wolfe, wtwolfe@hubcap.clemson.edu
jdarcy@multimax.encore.com (Jeff d'Arcy) (09/28/89)
billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ): > As far as recompilation is concerned, you can make use of Ada's > separate compilation facility to achieve this directly. I don't > do this because it would be a pain to have things scattered into > umpteen different files, and I have no idea why you would consider > this to be desirable. When you have multiple software engineers working on the same major component, smaller files reduce contention for the sources, which (quite obviously) can improve overall productivity. Jeff d'Arcy jdarcy@encore.com (508) 460-0500 Encore has provided the medium, but the message remains my own
chase@Ozona.orc.olivetti.com (David Chase) (09/28/89)
In article <24955@louie.udel.EDU> new@udel.EDU (Darren New) writes: >One thing I have always liked about the C language was the separation >between the "header" files (.h) and the "code" files (.c). In other >languages, such as Modula-II and (I think) Ada, it is not possible to >define multiple "implementation" modules for a single "definition" >module. >Does anyone know of any relatively popular languages that allow this >sort of separation other than C and C++? If not, why not? Discussion? Modula-3 allows this separation (popular?). It's a bit of a pain, actually, since there's (for the moment) data structures which need initialization at run-time. Given, say "MODULE A EXPORTS B", it isn't really clear whether or not the code generated for this module should initialize the data structures for B, since there might also be some MODULE C exporting B. These run-time structures are required because Modula-3(revised unpublished report) has Neat New Features like "opaque supertypes" (that's a supertype, but you don't know how many methods it has or what or how large the fields are) and constants of types exported by "required interfaces" (meaning that the constant is initialized at *run time* by the implementation of the required interface) and default field values for allocated records and objects (even for the fields in the opaque supertype). What we do now is generate the init code in all possible exporters; typically the number of exporters is small, so this doesn't kill us, but it isn't wonderful. The pre-linker is getting smarter too, so in several cases the redundant code is generated, but not executed. Still, it is a hassle. Several things would be easier if (a) we weren't generating C as an intermediate language and (b) the Unix linker (SunOS 3.5, and apparently also 4.0) wasn't quite as dumb as a rock. David
billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (09/28/89)
From jdarcy@multimax.encore.com (Jeff d'Arcy): >> As far as recompilation is concerned, you can make use of Ada's >> separate compilation facility to achieve this directly. I don't >> do this because it would be a pain to have things scattered into >> umpteen different files, and I have no idea why you would consider >> this to be desirable. > > When you have multiple software engineers working on the same major > component, smaller files reduce contention for the sources, which > (quite obviously) can improve overall productivity. The basic Ada strategy is to divide things into various packages (for example, each ADT would have its own package). Now since the implementation of a package can be recompiled without any recompilation of anything depending on the package's specification, there is no source code contention if one person is assigned to a given package, which is generally the case. If a package is too big for one person to handle, it most likely should be rethought and broken down into more than one package. One could also use separate compilation to take the separation down to the level of each procedure or function within the package, but this is really going hog-wild. At this point, the hassle of trying to locate source files exceeds any benefit which might exist, and since a package is intended to be a very manageable unit there wouldn't be any real benefit anyway. Bill Wolfe, wtwolfe@hubcap.clemson.edu
nick@lfcs.ed.ac.uk (Nick Rothwell) (09/28/89)
In article <24955@louie.udel.EDU>, new@udel writes: >One thing I have always liked about the C language was the separation >between the "header" files (.h) and the "code" files (.c). >Does anyone know of any relatively popular languages that allow this >sort of separation other than C and C++? If not, why not? Discussion? ML can do the same sort of thing: signature SMALL_PART = sig type ... and ... and ... val ... : ty1 and ... : ty2 and ... end; signature ANOTHER_SMALL_PART = ... signature ENTIRE_THING = sig include SMALL_PART include ANOTHER_SMALL_PART end This gives you inclusion of interfaces. There's also nesting of interfaces; the ENTIRE_THING signature could specify two sub-modules with smaller signatures. The actual module to match ENTIRE_THING could be a single object containing all the type specs and functions, or could be built from two (or more) separate ones: functor EntireThing(structure Part1: SMALL_PART structure Part2: ANOTHER_SMALL_PART ) = struct open Part1 (* simple case: inclusion. *) open Part2 end; You can also have several implementations maching the same interface of course (but you said you weren't interested in that). > -- Darren Nick. -- Nick Rothwell, Laboratory for Foundations of Computer Science, Edinburgh. nick@lfcs.ed.ac.uk <Atlantic Ocean>!mcvax!ukc!lfcs!nick ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ Fais que ton reve soit plus long que la nuit.
wright@hsi.UUCP (Gary Wright) (09/28/89)
In article <24955@louie.udel.EDU> new@udel.EDU (Darren New) writes: >Does anyone know of any relatively popular languages that allow this >sort of separation other than C and C++? If not, why not? Discussion? Eiffel does not have use header files but does support separate compliation. Each eiffel class resides in its own file. An individual class may be compiled or an entire system of classes may be compiled. To create an executable, one class is designated as the root class. Starting at the root class, the compiler examines the heirarchy of dependancies and recompiles any classes that have changed or that use another class whose *interface* has changed (if only the implementation has changed, not the interface, then clients of that class need not be recompiled). The compiler handles any client cycles automatically. There is no need to play games to avoid including header files more than once, building make file dependencies, or waiting until link time to find all the pieces of a class. -- Gary Wright ...!uunet!hsi!wright Health Systems International wright@hsi.com
bga@odeon.ahse.cdc.com (Bruce Albrecht) (09/29/89)
In article <24955@louie.udel.EDU>, new@udel.EDU writes: > One thing I have always liked about the C language was the separation > between the "header" files (.h) and the "code" files (.c). ... > Does anyone know of any relatively popular languages that allow this > sort of separation other than C and C++? If not, why not? Discussion? I will probably have several people tell me I'm wrong about this, but #include is a directive for the c pre-processor and not part of the language itself. The implication of this, therefore, is that if you have a preprocessor for your favorite language, you can do this with any language that supports separately compiled modules.
loren@rutabaga.Rational.COM (Loren Rosen) (09/29/89)
You can do more or less what you want in Ada, through the use of separate subprograms. Also, many of the production Ada compilers will remove code for unused subprograms from the executable. Header files have drawbacks of their own. It's all too easy in a large system to try to load two things that have the same name, or leave something out. You don't find out until the loader complains about multiply-defined or undefined names. -- -- Loren Rosen, the token irrationalist at ... Rational, 3320 Scott Blvd. Santa Clara Ca. 95054 loren@rational.com uunet!igor!loren
dor@lanl.gov (David O. Rich) (09/29/89)
In article <24955@louie.udel.EDU>, new@udel.EDU writes: > One thing I have always liked about the C language was the separation > between the "header" files (.h) and the "code" files (.c). ... > Does anyone know of any relatively popular languages that allow this > sort of separation other than C and C++? If not, why not? Discussion? Yup, Modula-2. A program can be decomposed into a set of DEFINITION and corresponding IMPLEMENTATION modules. For details (opinions, etc) try comp.lang.modula2. --dave
johnl@esegue.segue.boston.ma.us (John R. Levine) (09/29/89)
In article <2427@odeon.ahse.cdc.com> bga@odeon.ahse.cdc.com (Bruce Albrecht) writes: >I will probably have several people tell me I'm wrong about this, but >#include is a directive for the c pre-processor and not part of the language >itself. ... Don't confuse the language with the implementation you happen to use. On most unix systems the # directives are handled by a separate pass before the rest of the compiler, but there are lots of versions where it's all done in one pass. The ANSI C standard says quite a lot about what preprocessor actions are supposed to do without saying anything about how they're supposed to be implemented. -- John R. Levine, Segue Software, POB 349, Cambridge MA 02238, +1 617 492 3869 johnl@esegue.segue.boston.ma.us, {ima|lotus}!esegue!johnl, Levine@YALE.edu Massachusetts has 64 licensed drivers who are over 100 years old. -The Globe
bschwart@elbereth.rutgers.edu (dare-gale skylark) (10/07/89)
In article <2427@odeon.ahse.cdc.com> bga@odeon.ahse.cdc.com (Bruce Albrecht) writes: >I will probably have several people tell me I'm wrong about this, but >#include is a directive for the c pre-processor and not part of the language >itself. The implication of this, therefore, is that if you have a preprocessor >for your favorite language, you can do this with any language that supports >separately compiled modules. (a) The new C standard will make '#include' part of the language definition. (b) This does not prevent a crafty person from running his sources through cpp (or m4 or another macroprocessor) before compiling. There isn't even a compatibility problem, because you hand out the macroprocessed sources instead of the originals. The authors of sendmail configuration files figured out a long time ago that you can use a macroprocessor outside of C programming. -- Barry Schwartz, Chief SAPsucker bbs@cdspr.rutgers.edu Grad Student, Dept. of Elec. and Comp. Engg. bschwart@elbereth.rutgers.edu Rutgers University College of Engg. bbs@hankel.rutgers.edu Piscataway, NJ 08854 U.S.A. rutgers!cdspr!bbs