[m-rev.] for review: namespace changes
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri May 4 05:01:36 AEST 2001
On 03-May-2001, Peter Ross <peter.ross at miscrit.be> wrote:
>
> The current convention is that the namespaces are derived from the
> module name, with some exceptions for foreign code and the std lib. ie
> the module foo will create a namespace foo, the submodule bar in the
> module foo will create a namespace foo.bar an so on. However due to the
> object oriented nature of the .NET backend we need to have a class name
> declared inside the namespace to hold the code. Seeing that we are
> going to be generating IL representation of the mercury code,
> mercury_code seemed as good a name as any for the class.
OK, so let me get this straight. If I understand correctly,
the intended naming convention is as follows: (Tyson and Pete,
please correct me where I'm wrong, and fill in the gaps...)
1. Modules.
For a Mercury module named m1.m2.[...].mn (for n >= 1), we
generate a namespace named m1.m2.[...].mn, unless the module is
a Mercury standard library module, in which case the namespace
is named named mercury.m1.m2.[...].mn.
Inside that namespace we generate a class named
mercury_code, so the fully qualified name of the class is
m1.m2.[...].mn.mercury_code or (for standard library modules)
mercury.m1.m2.[...].mn.mercury_code.
2. Procedures.
For each Mercury procedure in the Mercury module, we generate
one or more static methods inside the mercury_code class.
These are named as documented in mlds.m.
3. Variables.
Inside each static method we generate variables which are
named as documented in mlds.m.
4. Foreign language code
For each Mercury module containing MC++ foreign code, we generate
a class named [please fill in this gap] and we put all the MC++
`pragma foreign_decl' and `pragma foreign_code' declarations from
the Mercury source module inside this class. [Is that right?]
This class also contains code for `pragma foreign_proc'
procedures: for each MC++ `pragma foreign_proc' procedure,
we generate a static method named [please fill in this gap]
whose body contains the code from the `pragma foreign_proc'.
We handle C sharp foreign code similarly, except that [please
fill in this gap].
5. Types.
In the `il' grade (which implies `--high-level-data'),
for each discriminated union type in the Mercury module,
we generate one or more classes. Normally there is a base
class corresponding to the type, and derived classes corresponding
to each constructor. In the MLDS, these derived classes are
implemented as nested classes, being nested inside the base class;
this is needed to avoid name collisions in the case of having
more than one constructor with the same name but different type
in a given module.
What should happen when this gets mapped to IL?
Should the classes corresponding to discriminated union types and
their constructors get put inside the mercury_code class or not?
> > > - return mercury::array__c_code::__Unify____array_1_0(
> > > + return mercury::array__c_code::mercury_code::__Unify____array_1_0(
> >
> > That name is getting pretty ugly. Why does it have both c_code and
> > mercury_code in it?
>
> Because it is not that trivial to fix. I would prefer to use the name
> mercury::array::c_code::__Unify____array_1_0. I do plan to fix this in
> the future, but it is not the best use of my time while I have trd here.
OK, I'm happy if this gets fixed later. But I think it would be worthwhile
now to at least document what the current state of affairs is and what
the intended future state of affairs is.
> > The name also doesn't match the documentation in the log message,
> > which says "For the module foo.m, place all the code in a type called
> > mercury_code in the namespace foo". Here the type called mercury_code
> > is in a namespace "mercury::array__c_code", but there's no source
> > file named "mercury::array__c_code.m". So I don't understand what's going on.
>
> There is a filename called array__c_code.cpp, so that is where the name
> comes from.
Ah. Why is the file named foo__c_code.cpp rather than just foo.cpp?
Is that just for consistency with what we do with the --target asm back-end?
For the --target asm back-end, we name the foreign code file
foo__c_code.c rather than foo.c so that when we compile it the
C compiler doesn't overwrite the foo.o file that was generated by
assembling foo.s. Oh, I guess the same issue arises for the .NET
back-end, if we generated both foo.il and foo.cpp then
we'd end up with foo.dll being overwritten.
So it makes sense to use a different filename.
But does the namespace name need to match the file name? I don't think
it does. In fact, I'm pretty sure it doesn't. So for foreign code,
we could output the code to a file named foo__c_code.cpp, but instead
of containing a namespace named `foo__c_code' that contained a class
named `mercury_code', that file would contain a namespace named `foo'
containing a class named `c_code'.
> The mercury, I believe, is your fault. There is a whole
> bunch of special case code which appends the mercury in front of anything
> which comes from the std library. I actually don't like that because it
> doesn't seem very elegant to me
Well, invading the global namespace would be even less elegant.
> and just leads to maintainability headaches,
I don't think the extra effort should be significant.
There shouldn't "a whole bunch of special case code",
there should be just one piece of code that handles that.
There should be one piece of code that converts
a Mercury module name to an MLDS class name,
and one piece of code that converts an MLDS class name
to an IL namespace name and/or an IL class name,
and only one of those two pieces of code should need
to handle this conversion.
> if that is what we wanted then we should move the std library
> into a sub module of mercury.
My long-term plan is indeed to move the std library modules into sub-modules,
but sub-modules of a module named `std', not sub-modules of a module named
`mercury'.
Different languages do this differently:
Haskell: builtin language stuff:
Prelude.<foo>
other standard library stuff:
<this>.<foo>, <that>.<foo>, etc.
Java: builtin language stuff:
java.lang.<foo>
other standard library stuff:
java.<this>.<foo>, java.<that>.<foo>, etc.
Ada: builtin language stuff:
Standard.<foo>
most other standard library stuff:
Ada.<this>.<foo>, Ada.<that>.<foo>, etc.
implementation-dependent stuff:
System.<foo>
stuff for interfacing with other languages:
Interfaces.<lang>.<foo>
C++: all standard library stuff:
std::<foo>
(The standard Library is described in sections named
"language support library", "io library", etc.,
but these are all in namespace `std'.)
Mercury, now:
builtin language stuff:
builtin__<foo>
other standard library stuff:
<this>__<foo>
Mercury, planned:
builtin language stuff:
std.builtin.<foo>
other standard library stuff:
std.<this>.<foo>
Having considered all this, I still strongly prefer using `std'.
Using `mercury' would make foreign language interfacing slightly simpler.
However, using `std' would be more appropriate for pure Mercury programming,
and would also be more concise. For a key aspect like this I think we should
prefer to make pure Mercury programming easier rather than making foreign
language interfacing easier.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list