[clean-list] Comments on the module system

Marco Kesseler m.wittebrood@mailbox.kun.nl
Sun, 28 Jul 2002 00:11:40 +0200


Hi Fabien,

>Hi Marco, please let me state my reasoning explicitly, that motivates my
>opinion on namespaces.
>
>*	Assume <namespace> is an identifier for some namespace in a program.
>The uses of the <namespace> identifier boils down to the following three
>cases :
>
>*	Assigning a freshly defined entity to an <identifier> within the
>scope of the namespace, for example by writing :
>
>		within listNameSpace
>		  map	:: (.a -> .b) ![.a] -> [.b]
>		  ...definition of map...
>
>		In the above, the 'within <namespace>' statement is used to
>introduce the scope of the namespace. Let's call that the scope the
>'defining scope' of the namespace.

okay, with the remark that as far as I am concerned such a scope may 
be spread out over several modules. Furthermore, the 'within 
<namespace>' statement rather looks like a namespace definition (what 
is in it?) than a namespace declaration (this is a namespace).

So perhaps there is a 4th use that declares a namespace:

  namespace listNameSpace

Possibly with some properties like what type of symbols may be in it 
(functions, data types, particular types of functions, maybe even a 
list of identifiers).

Now I come to think of it: it may also be sensible to disambiguate 
instances with the same name by qualifying their class name...

>*	Using in an entity definition an explicitly qualified identifier
>referring to some entity defined within the scope of some namespace. For
>example :
>
>		twiceMap :: ( a -> a ) [ a ] -> [ a ]
>		twiceMap f l = listNameSpace::map ( f o f ) l
>
>		In the above, the identifier 'listNameSpace::<identifier>'
>is the explicitly qualified identifier.
>
>		That use of qualified names is not supported by the current
>Clean module system where one cannot writes <module>.<identifier>.

okay, assuming you actually mean <namespace>.<identifier>.

>*	Using import statements to import identifiers from a namespace in
>the current scope :
>
>*	Explicit import statements : 
>
>			using listNameSpace // Import all identifiers
>
>			twiceMap :: ( a -> a ) [ a ] -> [ a ]
>			twiceMap f l = map ( f o f ) l // 'map' Really
>refers to 'listNameSpace::map'
>
>*	Implicit import statements :
>
>			from listNameSpace using map // Import 'map' only.
>
>			twiceMap :: ( a -> a ) [ a ] -> [ a ]
>			twiceMap f l = map ( f o f ) l // 'map' Really
>refers to 'listNameSpace::map'
>
>		These uses are similar to the import statements for the
>current Clean module system.

Maybe. The comments suggest that 'using' also imports the 
identifiers. If you mean that no traditional 'import' statement is 
needed anymore, I might disagree:
you cannot do this if namespaces have no relation to the module 
system. This is the case for example in C# and C++, where 'using' 
does _not_ mean 'import'. This contrasts with Java, where namespaces 
take the form of packages.
 
>*	In Clean, modules are the basic compilation unit. That is, any
>identifier used in a compileable program must be defined in some
>implementation module, and may be declared in some definition module.
>
>*	The above rule must hold for namespaces identifiers.
>
>*	Now the interesting point is to consider the interaction of
>namespaces and modules. I see the following cases :
>*	A.Defining a namespace :
>*	1.The defining scope of a namespace is included within the defining
>scope of a module. That is, if  the <namespace> identifier is exported by
>both modules A and B, then :
>
>			import A
>			import B
>
>			will cause a name clash on the <namespace>
>identifier.
>
>*	2.The defining scope of a namespace may span several modules. That
>is, if  the <namespace> identifier is exported by both modules A and B, then
>:
>
>			import A
>			import B
>
>			will not cause a name clash on the <namespace>
>identifier.
>
>			Somehow the set of definitions intoduced in the
>definining scope of the namespace in the module A and in the defining scope
>of the namespace in the module B should be merged.
>			This is the kind of flexibility you are asking for.

I think so.

>*	B.Using a namespace :
>*	1.The identifier referring to the namespace must have been imported
>somehow, by importing a module defining that namespace.
>*	2.The identifier referring to the namespace need not be imported.
>
>*	In case A.1 you cannot extend a namespace without touching the
>corresponding module. This is not what you want. So let's rule this out now.
>
>*	Case A2 allows for the extension of a namespace without touching
>existing modules.
>		In case A.2 we have to consider the subcases B.1 and B.2.
>*	Cases A.2 & B.1 :
>			If a namespace may span several modules, we need
>somehow an arbitrary rule to know which module must be imported in order
>that the namespace identifier be imported.
>			Assume that it is enough to import one module with a
>'within <namespace>' clause to import the <namespace> identifier.
>			It is not reasonable to assume that the compiler
>infer the modules we want to import, where all the definitions of a
>particular namespace are located. Thus, the actual set of identifiers that
>the compiler will allow to be visible in the namespace scope depends on a
>list of imported modules that the programmer must somehow specify.
>			The meaning of a namespace identifier used in a
>module then depends on the context of compilation of that module, and cannot
>be deduced from the analysis on the text of that module only.

First of all, one needs to import the module that declares the 
namespace (in the sense described above: 'namespace ...'). This is 
not just an arbitrary module and it does NOT imply importing ALL 
members of this namespace. The programmer merely has to import the 
modules he needs in the same way he does now.

This is very similar to type classes, where you define the type class 
in one module, but are allowed to define instances in others.

>*	Cases A.2 & B.2 :
>			If the identifier of a namespace need not be
>explictly imported, we rely on the compiler and the current compiling
>context to give a meaning to the identifier. This is the same conclusion as
>above.

If namespaces can be declared implicitly, then that must be all there 
is to know about its  identifier. It is a namespace. Giving meaning 
to it is trivial.

>Here is my line of reasoning. Based on this I consider that namespaces are
>an unnecessary complication. :)

I do not think there is anything complicated about it.

>Essentially the only thing that the module system lacks IMO is the use of
>qualified names <module>.<identifier> that would allow us to override the
>default scoping rules.

I would call this <namespace>.<identifier>

>Now, it may well be that I have missed some essential point in your proposal
>for namespace :)

I hope this clarifies things a bit.

regards,
Marco