C is ubiquitous, and C++ nearly as much, but I'm curious which other languages follow a similar model of header files. Specifically, in which other languages is it idiomatic to edit pairs or groups of "header" and "implementation" files? (A group as in multiple headers with one corresponding implementation file or a single header with multiple implementation files, as also seen in C.) For example, the pair "blah.h" and "blah.c".

C's header files are tied into the C preprocessor, but that's not the detail I'm focusing on here. For example, PHP has various include mechanisms, but you don't have a pair/group of "blah-header.php" plus "blah-notheader.php".

Some languages generate a file from source in a one-to-one mapping, such as Java, but that's not what I'm talking about either. I'm interested in cases where the programmer directly edits both/all files in the pair/group.

Perhaps to put it another way: which languages have a declaration file ("header") and definition file ("implementation") such that a person would generally edit both files in tandem?

  • @Roger, I'm not certain why you state that C has paired files. C programmers use two types of files for source, but implementation files are not required to have a matching header file. There isn't a "main.h" included by default for C programs. In addition, PHP includes aren't required to have a "php" file extension. Drupal uses "inc" to denote its PHP include files. – Huperniketes Oct 17 '10 at 1:26
  • 1
    @Huperniketes: It's conventional in C, but of course not required and some uses (e.g. a header with only macros) don't need it even in projects where it's conventional. – Roger Pate Oct 17 '10 at 1:28
  • @Roger, might you be mixing convention for modules and libraries, which indeed do typically use pairs or groups to indicate relationship, with that of module/library clients which can include headers from multiple modules/libraries? Because these P-named languages share that same behavior. – Huperniketes Oct 17 '10 at 1:35
  • @Huperniketes: I believe you're misunderstanding. I'm not talking about Python modules and import statements, for example, because those only have one file that's edited per module. – Roger Pate Oct 17 '10 at 1:38
  • @Roger, didn't you say that a "group as in…a single header with multiple implementation files, as also seen in C" is what you were looking for? – Huperniketes Oct 17 '10 at 1:44


Any Ada package on the other hand consists of two parts, the specification (header) and body (code). The specification however is a completely stand alone entity which can be compiled on its own and so must include specifications from other packages to do so. An Ada package body at compile time must refer to its package specification to ensure legal declarations, but in many Ada environments it would look up a compiled version of the specification.

--file example.ads, the package specification.
package example is
end example;

--file example.adb, the package body.
package body example is
end example;

Source: http://www.adahome.com/ammo/cpp2ada.html#2

| improve this answer | |
  • I have never heard of an Ada programming support environment that did not include a database of compiled compilation units. (Frequently, the implementation provides a hierarchy of databases, to allow an overall "baseline" database and individual developer "sandbox" databases.) – John R. Strohm Oct 18 '10 at 2:40

Objective-C (and and its C++ counterpart, Objective-C++) can #include C (C or C++) header files as well as #import Objective-C header files. That pairs are even used is by convention.

In additon, ASP, Perl, Python, Pascal, and, since the file extension used for its includes doesn't have to follow a standard, PHP.

Edit: Most assembler source code also use "paired" included/implementation files by convention.

EDIT2 - ADDENDUM Apparently there's some confusion as to the use cases that prompted the use of separate header files in C, and so some developers are dubious that certain other languages would also use header files to deal with those use cases in the same way.

  • as the earliest C compilers ran on machines with a small amount of memory, it wasn't possible to load up symbol tables with all the source that would be incorporated into the final build. So each source file was run through multiple passes separately to generate the object code with necessary interfaces for other sources included in headers;
  • as the earliest C compilers ran on machines with a small amount of memory, it was more efficient to distribute the shared elements of a module among more specialized headers which could be included selectively by sources rather than in one;
  • as the earliest C compilers ran on slow machines, especially since they had a small amount of memory, it was time-consuming to compile lots of source files belonging to a module when only a few had been changed;
  • sometimes source code maintainers don't share their code with outside groups, but instead make the object code available with headers of the required interfaces to aid in proper integration with linked code;
  • and most importantly these days, programs and the language runtime sometimes deal with libraries, especially platform-dependent libraries, which are from an external environment or other language but which they can integrate with appropriate interface specifications in a header.

The last point is particularly true when a language supports a platform's GUI. I know it's been true on the Mac since its earliest days (when Pascal was its first high-level language) to now for Perl (now automated), Python, and PHP. Its runtime environment may not make the inclusion process visible to you, but it's happening; especially if you use platform-specific symbols.

Creating bindings for C libraries in Free Pascal

h2xs builds a Perl extension from C header files, or use SWIG, or support C++

Interfacing Python to a C lib doesn't require just a header, but writing an extension!

| improve this answer | |
  • I know Perl, Python, and PHP don't make the separation into header/implementation that I'm talking about here. Are you sure ASP and Pascal do? – Roger Pate Oct 17 '10 at 1:27
  • Delphi (and other Pascal variants) can use .inc files, but they aren't usually used in the C manner. – Gerry Oct 17 '10 at 7:14
  • 3
    +1 for objc. Delphi/Pascal use the same file (a unit, foo.pas) which contains both interface and implementation clauses, corresponding to foo.h and foo.c. There are include files, but they're not used in the same manner as C – Frank Shearar Oct 17 '10 at 11:16

F#: It optionally allows a .fsi file to declare the symbols like C headers. See http://en.wikibooks.org/wiki/F_Sharp_Programming/Modules_and_Namespaces#Module_Signatures

| improve this answer | |

I think Modula 2 uses a similar pattern

| improve this answer | |
  • 2
    Details from Wikipedia: Modula-2 programs are composed of modules, each of which is made up of two parts: a definition module, the interface portion, which contains only those parts of the subsystem that are exported (visible to other modules), and an implementation module, which contains the working code that is internal to the module. – Roger Pate Oct 17 '10 at 0:57

You can do this in D with .di files. It's useful for distributing closed source libraries and such. The .di files can also be generated automatically from the .d files. However, unless you need to distribute a closed-source library or compile times become a major issue and you need to cut down on what the compiler has to parse, it's not idiomatic.

| improve this answer | |
  • I had looked at D before posting, but didn't see this. However, .di files don't match what I'm looking for, if you generally don't edit them directly. – Roger Pate Oct 17 '10 at 3:13

I've seen the C Preprossessor used in Haskell to include code from a header. Its not that common as far as I know though.

| improve this answer | |

Erlang has header files that are often used (among other things) to declare data structures used in a module. They are not necessary, though, and many, if not most, modules don't use them.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy