Difference between revisions of "Namespaces"

From Free Pascal wiki
Jump to navigationJump to search
Line 84: Line 84:
 
** Then units defined in a namespace.
 
** Then units defined in a namespace.
  
 +
// our project also has a SysUtils unit, but because RTL already has one, we
 +
// must define a namespace for it.
 
  unit SysUtils namespace myproject;
 
  unit SysUtils namespace myproject;
 
  uses
 
  uses

Revision as of 14:15, 26 July 2010

Namespaces in FPC

This page contains proposals and ideas, which could lead to the a better implementation of namespaces that what Delphi currently has. These ideas may or may not work, that's the whole point of this wiki page. Throw ideas around until we find something that could work.

Why?

Namespaces are not perfect, but they do work, and they do greatly reduce the chances for Unit name or Class name conflicts. Other languages and frameworks (Java, .NET, C++ etc) have already seen the problem and introduced namespace support.

How visible is the unit name conflict problem? Just think, how many projects are there that use the unit names (or would like to use these common names):

 constants.pas
 utils.pas
 etc...

Extremely common names, and are really good names for what they contain (they describe the purpose of the unit clearly), so why can't we use them in our projects? Namespaces will resolve such problem.

  • To reduce the chances of conflicting unit names
  • Allow developers to use ideal names for units without the worry of conflicting unit names with the FPC compiler or other component libraries. eg: constants.pas or utils.pas or strutils.pas
  • No need for cryptic 2 or 3 letter prefixes to unit names.

Interested Parties

  • Graeme Geldenhuys


Usage Examples

Please add any new ideas to the end of the list.

Suggestion 1 - "dotted unit name notation"

Use the same style as implemented in Delphi 2009 onwards.

Pros

  • Delphi compatible

Cons

  • The force rather long unit names. eg: freepascal.rtl.classes.pas
  • Unit names now contain a '.' character which doesn't make them truly valid identifiers.
  • Ambiguities could appear, but they are rather easy to overcome with a simple language rule. Object Pascal already have many language rules, this will just be a new one. See the following Mantis report for details: Mantis report 14439

Suggestion 2 - new keyword & new compiler parameter

This idea works similar to Compiler Defines. They can be applied to a unit, or to a project as a whole. Add a new keyword namespace <value> to the Object Pascal language that gets added to the unit line of a source file. Also add a new -namespace=<value> compiler parameter to apply a namespace to a whole project

Example

   // per unit
  unit utils namespace companyxyz;
  uses
    ...
  end.

...or applied at compile time to all units being compiled.

   // our sample unit - as normal, nothing new
   unit utils;
   uses
     ...
   end.
   $ fpc -namespace=companyxyz utils.pas constants.pas ...

... if a conflict occurs, then you reference the unit with the full namespace.

     uses
        companyxyz.utils;  // because unit names must be valid identifier and thus,
                           // can't contain dots, when the compiler sees this, it knows
                           // companyxyz. is a namespace reference.


Pros

  • Namespaces can be applied per unit or for a whole project. The unit specific namespace takes preference compared to the namespace declared as a compiler parameter.
 unit buttons namespace fpgui;
 uses
   Classes
  ...
 end.
  • Namespaces can be applied via the compiler command line parameter so no need to modify each individual unit.
 fpc -namespace=fpgui buttons.pas groupbox.pas panel.pas
  • Least amount of intrusion to existing code.
  • Unit names still stay short
  • Unit names are still valid identifiers (unlike the "dotted" notation of Delphi).
  • If no explicit namespace is declared in the unit, or per compiler parameter, then in automatically get added to the "global" namespace, and works like FPC and Delphi prior to v2009.
  • The usage of the namespace is only required when you get a unit name conflict. All other times, simply using the unit name as-is will suffice.
  • When a unit references a unit in a uses clause without the namespace, then the following search priority is taken.
    • "global" (or undefined) namespaces take preference. For example the RTL in FPC will not be compiled with a namespace to get higher priority. So if a project also contains a SysUtils.pas unit, the RTL's SysUtils will take preference, and the developer will have to introduce a project wide namespace.
    • Then units part of a project.
    • Then units defined in a namespace.
// our project also has a SysUtils unit, but because RTL already has one, we
// must define a namespace for it.
unit SysUtils namespace myproject;
uses
  ...
end.
 
unit mytools;
uses
  SysUtils,             // from the RTL
  myproject.SysUtils,   // from this project / the myproject namespace.
  Classes;

Cons

  • In corner cases, some ambiguities could appear (if the developer doesn't understand the preferences of namespaces).

Suggestion 3 - directory layout

Similar to what JAVA does, by using the directory hierarchy to define the namespace.

Pros

  • ?

Cons

  • I see lots of issues with this idea because FPC supports multiple search and library paths per project. So this is probably the crappiest idea. :-)