Suggestion: module opcall

Bill Baxter wbaxter at gmail.com
Thu Jan 8 10:52:18 PST 2009


On Fri, Jan 9, 2009 at 2:33 AM, bearophile <bearophileHUGS at lycos.com> wrote:
> bobef Wrote:
>> The need for this is because often a module happens to be named as the functionality it contains and you have to write the stuff two times.<
>
> A design bug in the D1 module system is that when you import foo normally you import in the namespace both the module name and the names it contains. So if you have foo inside foo you are in troubles. I'm waiting such design errors to be fixed still.

I think this problem you refer to only applies to modules without
package names.  I.e. "module Foo" containing "class Foo".  Things seem
to work ok if you have "module x.Foo" with "class Foo" inside.

So you are saying you want this to be an error?

import std.string;
void foo() {
    std.string.format("hi");  // error no such symbol "std.string"
    format("hi");   // ok
}



> Anyway, you can solve your problem like this:
> from foo import foo;

He can solve his problem by using Python with semicolons?

I don't think that really solves it though.  The original request used
the full package name.  I'm a big fan of static imports, but I have to
agree that I just can't bring myself to use static imports when the
names are things like mylibs.util.Array.Array.   It just looks stupid.
 But when you have a module that basically implements only one class
what *should* you call that module?  There's no good way to do it,
except to try to organize your library like Phobos and put lots of
stuff in every module.

So I think there is a need for a way to have eponymous one-class
modules.  The D package stuff seems to have been inspired largely by
Java's, but the big difference is that in java it's always
one-module<=>one-class so they don't have this problem.

But I don't think module opCall is the right solution.  It looks ok
for the Stdout case because typical usage of Stdout is Stdout().  But
what about .flush?   For that you'd still be doing
tango.io.Stdout.Stdout.flush.  If anything it's more like a module
opDot that you want.   I don't think that's really the right way to go
either, though.

I think the situation is more like the template stuff.

template Foo(T) {
     void Foo(T x) { }
}
Foo(3);  ///   Foo.Foo not needed

Compare with:

static import Foo;
auto x = new Foo;  // Foo.Foo should not be needed if class Foo is the
only thing inside Foo.


On the other hand, I'd really like to see the template thing fixed so
there's some way to put private stuff inside there too.  Similarly
it'd be nice if it would work for modules as long as class Foo was the
only non-public thing.

I think both cases might be made cleaner by some judicious re-use of
the 'this' keyword.  Such as:

template AReallyLongTemplateNameIDontWannaTypeTwice(T) {
     void this(T x) { }
}

and with the modules it would be:

module pkg.Foo;
class this {
   // Hi I'm the single representative class for Foo, implicitly
accessible via the module name pkg.Foo.
}

I love how I don't have to change all the constructor names in D
whenever I change a class name.  Extending that DRY goodness to
templates (and maybe modules too) would be nice I think.

--bb



More information about the Digitalmars-d mailing list