Leaf

Are explicit namespaces required?

I’m working on modules in Leaf, implementing namespace support. The moment I write my first test a feeling of uneasiness sets in. As I stare at the sample code I see a lot of problems forming. Supporting a C++ style namespace will put a lot of tension in how forward declarations are handled. I’m sure it could be resolved, but do I even need these namespaces at all?

The C++ Namespace

Namespaces in C++ are primarily used to delineate module boundaries, as the language itself has no notion of a module. The function of a namespace is to provide groupings and hierarchies of names. This isn’t the same as merely prefixing all names (the C approach); the hierarchy aspect is important. Consider the below pseudo-code.

namespace a {
	namespace b {
		print(value)
		print(sub::value)
	}
	print(b::value)
}

In fully qualified names, the lookup of ‘value’ will proceed as ‘::a::b::value’, ‘::a::value’ then ‘::value’. The lookup of ‘sub::value’ will be ‘::a::b::sub::value’, ‘::a::sub::value’, ‘::sub::value’. The first namespace match is the winner. It doesn’t matter if the variable actually exists in that namespace. This can be seen with the final ‘b::value’ which will only check ‘::a::b::value’. If there is no variable ‘::a::b::value’ the compiler will produce an error. In this sense, a namespace is also a symbol.

I’ve created some test code at ideone.

C++ also has something called argument dependent lookup. When resolving the names of functions it looks into the namespaces of the type of each of its arguments (simple example). A typical use of this is for operator, and common function overloading. It allows the definitions of the overload to be within a namespace, but not need qualification to be referenced. This definitely helps in creating generic templates, but throw in implicit conversions and partial specializations and it can get quite confusing.

The Python Namespace

Namespaces are created automatically in Python modules. The definitions of a module do not overlap with other modules. An ‘import’ statement must be written to use them. Since modules are explicitly bound to symbols they simply follow the normal name resolution rules.

What troubles me in Python is that typical programs tend to import a lot of names. Obviously you don’t have to do this: functions can be referenced via a module name rather than imported directly. I often find that retaining the module name clarifies the code, but at times can be an inconvenience (especially for longer names). Without truly understanding why these individual name imports are done I’m afraid I’d be forced to also allow the practice in Leaf.

Perhaps a larger issue in Python is the difficulty in making and using a hierarchy of modules/packages. Okay, the making side is easy, but the referencing from other code is difficult. I’ve looked around and found several approaches, but nothing that looks like a best practice. I think this discourages one from using them as often as one should. In contrast, C++ namespaces are quite simple to setup and reference. This aspect in Python is annoying because I otherwise feel as though the general model is correct and may be sufficient to replace namespaces.

Anonymous

I tend to use a lot of anonymous namespaces in C++. These make the names private to the translation unit, of primary importance to the linking phase where they might otherwise conflict. This doesn’t feel like a good reason to require namespaces though. It is a workaround to how the toolchain is working. I’d much prefer that my symbols names are private unless I otherwise mark them for export.

Classes

Object oriented programming also introduces namespaces in the form of classes. Each class encapsulates a set of names specific to that class. We may not always think of it from this angle, but it is definitely a namespace and probably the most commonly used one. Not just for functions, the class namespace is often filled with type aliases, structure types, and enumerations.

Often one finds a class filled with static functions and variables. I find this appropriate only if they are intimately tied to the class. Either they are private support functions, or static identity functions (usually to support templates in C++). A function filled with many public static utility methods is highly suspicious: it looks like an explicit namespace. Would not a module work better?

Something Else?

Between modules, classes, and perhaps even enumerations, I’m not sure if an explicit namespace is actually needed. C++ definitely needs them since it lacks modules and all files share the same global namespace. Is there any other reason why they are required? I’d be interesting in knowing whatever uses you have for explicit namespaces. If nothing comes up, I won’t have them in Leaf.

Categories: Leaf, Programming

Tagged as: , , ,

11 replies »

  1. You should take a look at the module system used in haskell. It offer a tight control of what you are importing/exporting, be it qualified or not.

    • Is there a way to control visibility at the point of symbol declaration itself? I don’t like the idea of declaring public items far removed from where they are actually defined.

    • It is a concern that some people share: http://www.haskell.org/haskellwiki/No_export_lists

      Personnaly, I don’t very like the asterisk syntax. Maybe something like that would do the job :

      module Important where

      {- * Important functions -}

      {- | most important function -}
      public foo :: Int
      foo = 2

      {- * Important data types -}

      {- | most important data type -}
      data Number* =
      Zero
      | public One*
      | public Two*
      | public Three*
      | Many

      But the exact syntax really depend of what fit better in the language.

  2. I think the Java way of namespaces is the way to go. It’s clean, it’s simple, and it enforces a sane directory layout. The static method approach gives the final bit of namespacing that avoids 95% of all name clashes. I wouldn’t think too much about precision control because what matters by far more is productivity. Think about how your IDE can help you with any name resolution

    That said, java packages need a version system. Maybe a separate standard file in a package directory denoting package version number, and in the import, a version dependency? Other metadata can be added while at it. License?

    Java usually exports about enough, but the fourth “hidden” keyword (package-private) is ugly since it’s empty. it should have a proper name like “pack” or something. Optionally a C++style “friend” declaration could also work, but I have never really felt this to be a big need

    something else: I would be happy if pre- and post-conditions could be specified in interfaces, and optionally checked at runtime (or parsed by a theorem prover)

    • It’s unfortunate that Java chose a silly naming convention for their packages. Having really long names, irrelevant to what the package does, significantly detracts from the system. That is, the whole reverse domain prefixing is a poor system. I think it was built to avoid a problem which I’ve never encountered in practice (clashing package names).

      Java also suffers from a flat namespace for packages. While the names look like a hiearchy they don’t really form one. If you import “ugh.silly.prefix.Module” you can’t refer to a sub-module as “Module.SubModule”. You’re forced to import the submodule by full name again. Python also has this problem. It would be very nice to allow modules to form a hiearchy so that sub-modules are easy to use.

      I definitely think versioning would be a good addition. I prefer a system where the version is directly at the “import” statement as opposed to a separate file. However, that would be painful if you had to do this repeatedly at every import location. For Leaf I’ve allowed to have one import for the entire module, so a versioned import would actually make sense.

  3. Hm. You have a point of the versioning going badly with the imports the way they are now. I actually have no idea how to sanely handle imports of conflicting versions from one file (nasty!). clashing package names… I guess I see it could happen if you just took the java package roots and truncated them away. e.g. there could be more than one jdom.*. Do we dare think there never would be more than one supplier for a java XML DOM model? I suspect it would happen the day you assumed otherwise. The long names aren’t really a problem, you just hit ctrl+space in any normal editor and it solves it for you. the same way rewriting an entire absolute path in an import is no problem either; the editor takes care of that too. But I do agree that the names could be shortened to at least myOrganization.myPackage, without the org. Minor problem though; but I see that the java system cannot be taken straight anyhow

    I definitely think a key to language success is that one does not need to type oneself to death. But one way of achieving this is optimizing it such that it is easy for an IDE to do it’s share of work too. I cannot stress tooling enough – I would never use a language without refactoring tools or an editor with typing auto-completion

    • I disagree about the IDEs. I consider a language broken if the only effective way to use it is in an IDE. It’s no longer a source code based language then. Having an IDE just throw in boilerplate is a string indicator that the language is highly redundant.

      A project should never have multiple providers of a DOM model. Sure, they may be multiple implementations available, but a single application should never use multiple ones. I recall the agony of trying to debug where there are multiple definitions of “Node”. One project should never import different versions of the same library. It’s an insane state for a project to be in. You have no idea why version is being used where,and you have no idea if there are conflicts.

    • Regarding libraries: you have to be careful in how you define an application here. an application may very well use any number of XML libraries, for the simple reason that it uses libraries that *in turn* use their favourite XML library. This is the common way of ending up needing multiple versions of the same library as well

      In principle I agree a single *library* should not use multiple XML implementations. but some sub-libraries may actually expose the library they used in turn, thus forcing you into using a combination. You may argue that the libraries are breaking an abstraction, and that it’s their fault, but it’s one those things that occur and the last thing you want at that moment is the language itself pissing on you

    • I think this could lead us to a debate on architecture. The more libraries you add, and the more sub-libraries they expose, the more difficult it becomes to maintain an application. Adding more features, like direct version control, should be to simplify, not to allow even more complex hieararchies.

      That is, I know what problem you are having and wish to solve, but I don’t think Java has gone in the right direction to solve it. I’m not saying I know the correct direction though.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s