1

I want to know how source file trees are organized in Pascal. From the Language Reference Guide from FPC, it seems that programs and units must be entirely contained in single files (unless the ${INCLUDE} directive is used).

I can think of several ways of organizing my programs:

  • Stick everything in one huge file (really don't like that),
  • Write several big unit files,
  • Write many small unit files (might turn into a spaghetti of dependencies),
  • Write several big units but split them into files using ${INCLUDE}

Using ${INCLUDE} at all seems like a bit of a hack to me, since a proper module system should make it unnecessary. On the other hand, I'm afraid that single-file modules would get big enough to be unwieldy.

How is this usually done in actual projects? Is there some option I have missed?

Staven
  • 3,113
  • 16
  • 20

2 Answers2

2

There is absolutely no need to use a single file, nor is there a need to use {$INCLUDE} unless you have a specific need to do so.

I have several Delphi projects that are 100+ separate code units, used as needed with an addition to the appropriate uses clause (interface or implementation sections) where they are needed. You can see this pattern in the FPC source as well:

unit One;

interface
  uses System;

type
  TSomeThing=class(TBaseThing)
  ...
  public
  ...
  private
  ...
  end;

implementation

uses
  Math;

....

Break your source into logical units (eg., a unit for classes that are related to each other, types that are related or dependent on each other, functional units, and so forth). There are many examples of doing so in FP (they follow the same pattern as Delphi's VCL/RTL) to see how this is typically done.

Ken White
  • 123,280
  • 14
  • 225
  • 444
0

If you design your application properly then each UNIT should be a reasonable size and have a single well-defined purpose. Dependencies should be somewhat hierarchical and you can always group any number of closely related UNITs into a library if your application is large enough to warrant it.

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • -1 It won't help in FPC where *.p* files also depend on crcs and dates of .inc files. One of the differences with Delphi. – Marco van de Voort Oct 31 '12 at 20:43
  • Thanks for the down-vote - I was answering in the context of Pascal in general, but evidently *some* of the above above answer doesn't apply to FPC. – Paul R Oct 31 '12 at 21:41
  • @Paul: I didn't downvote, but most of what you wrote hasn't been applicable to modern Pascal dialects for more than a decade. It may have been true with Wirth's original Pascal, but Turbo Pascal in the early '90s didn't need to worry about saving compilation by moving implementation stuff to include files, and the use of a `uses` clause in both `interface` and `implementation` sections has been available at least that long as well. (The only `{$I ...}` I ever use is to set different `{$DEFINE}`s for different compiler and RTL versions.) – Ken White Oct 31 '12 at 23:11
  • @KenWhite does that mean that modern Pascal compilers check for changes in implementation sections before recompiling (as opposed to just comparing access times)? – Staven Nov 01 '12 at 02:13
  • @Stavan: No. It means that modern Pascal compilers are usually fast enough that the compile itself isn't meaningful, and changes in `implementation` and `interface` both require recompile/relinking of an executable in order to run the code. There is absolutely no benefit to moving the `implementation` details to a separate file and `{$I ...}` to include them into the `interface`. As I said, I only use include files for compiler/RTL differences, and those differences require a recompile anyway. – Ken White Nov 01 '12 at 02:22
  • @Staven: what I meant is that FPC also checkes the access times of .incs in deciding to rebuild an unit. Afaik Delphi does not – Marco van de Voort Nov 01 '12 at 08:12
  • OK - point taken - my Pascal experience is pretty out of date it seems, in this area at least - I'll delete most of the above answer. – Paul R Nov 01 '12 at 09:46