View mode: basic / threaded / horizontal-split · Log in · Help
March 20, 2005
is there a way to enforce module 'namespace' semantics?
Hi,

Say I have module foo, and it has funtion bar, like this

------foo.d---------------
module foo;

void bar()
{
}
--------------------------

Now, I'm writing a library and I don't want the user of the library to 
be able to call bar by itself, like this

------main.d--------------
import foo;

bar(); // nose
--------------------------

Instead, I want to make it so the only way the user can call bar is like 
this

------main.d--------------
import foo;

foo.bar(); // yes
--------------------------

Is there a way I can enforce the functions inside of the module? Maybe 
like this?

------foo.d---------------
module foo;

enforce // enforces module 'namespace'
{
  void bar()
  {
  }
}
--------------------------

The reason I want to enforce the module 'namespace' is because I'm using 
modules as a replacement for a global class. I have multiple modules 
with similar function names, and as the library writer, I don't want my 
users to just call 'bar()', because it is not how I want the module to 
be used and the compiler will complain if they import another module 
with the same function name 'bar()'

Is there a good solution to this problem? Or should there be some way to 
enforce module 'namespace' within D?

Thanks.
 - Clay
March 20, 2005
Re: is there a way to enforce module 'namespace' semantics?
clayasaurus wrote:
> Instead, I want to make it so the only way the user can call bar is like 
> this
> ------main.d--------------
> import foo;
> 
> foo.bar(); // yes
> --------------------------

A darn good question: I'd very much like this myself.  One possible 
(albeit hackish) solution I thought of off the top of my head would be 
to use static members of an abstract class... ie:

# module foo;
#
# abstract class Foo {
#   static void bar() { }
# }

# module main;
# import foo;
#
# // ...
# Foo.bar();
# // ...

Granted it probably provides feeding ground for cute errors from missing 
capitalization, but it should work.  Maybe I'll test it later.

-- Grant
March 20, 2005
Re: is there a way to enforce module 'namespace' semantics?
> The reason I want to enforce the module 'namespace' is because I'm using 
> modules as a replacement for a global class. I have multiple modules with 
> similar function names, and as the library writer, I don't want my users 
> to just call 'bar()', because it is not how I want the module to be used

why not? D is designed to be used that way. Can you give more details about 
the API? Personally I wouldn't fight the standard D style but one is free to 
make whatever API one wants, I suppose. If the standard approach results in 
errors or painful usage then I suggest posting examples so that Walter can 
try to find a nice solution.

> and the compiler will complain if they import another module with the same 
> function name 'bar()'

It should only complain when they try to use it. When that happens they will 
have to use the foo.bar or an alias to fix the conflict.

You might be seeing import conflicts because of public imports, too. This, 
actually, is one reason why private imports are better than public ones 
because it can be nasty to track down conflicts when you nest several public 
imports and somewhere along the chain a conflict happens. Keeping everything 
private prevents that from happening.

-Ben
March 20, 2005
Re: is there a way to enforce module 'namespace' semantics?
Chris Sauls wrote:
> clayasaurus wrote:
> 
>> Instead, I want to make it so the only way the user can call bar is 
>> like this
>> ------main.d--------------
>> import foo;
>>
>> foo.bar(); // yes
>> --------------------------
> 
> 
> A darn good question: I'd very much like this myself.  One possible 
> (albeit hackish) solution I thought of off the top of my head would be 
> to use static members of an abstract class... ie:
> 
> # module foo;
> #
> # abstract class Foo {
> #   static void bar() { }
> # }
> 
> # module main;
> # import foo;
> #
> # // ...
> # Foo.bar();
> # // ...
> 
> Granted it probably provides feeding ground for cute errors from missing 
> capitalization, but it should work.  Maybe I'll test it later.
> 
> -- Grant

That may be a decent alternative, but it doesn't cut it for me, since it 
is using pseudo-module namespace, and you can call weird things like...

foo.Foo.bar() // i think

It would be simpler to just let the compiler bite the user when they try 
to do this

----------------------------
import foo1; // has bar()
import foo2; // has bar()

bar();
----------------------------

but it would be more consistent to be able to enforce the 'namespace', 
so this kind of thing can never happen (it does when programmers get 
shortsighted/lazy)


Thanks for the reply : )
- Clay
March 20, 2005
Re: is there a way to enforce module 'namespace' semantics?
Ben Hinkle wrote:
>>The reason I want to enforce the module 'namespace' is because I'm using 
>>modules as a replacement for a global class. I have multiple modules with 
>>similar function names, and as the library writer, I don't want my users 
>>to just call 'bar()', because it is not how I want the module to be used
> 
> 
> why not? D is designed to be used that way. Can you give more details about 
> the API? Personally I wouldn't fight the standard D style but one is free to 
> make whatever API one wants, I suppose. If the standard approach results in 
> errors or painful usage then I suggest posting examples so that Walter can 
> try to find a nice solution.

I would rather use a 'module global' instead of a 'class global', 
because with classes you have to 'new' it, and you have to give it a 
name, which would probably be something like 'gClass'. With a 'module 
global', the name is the module name, and I don't have to 'new' it.

These globals are ok for me, because they are there for the entire 
length of the program, and everything needs easy access to them.

Also, with module global, there is no need for declaration, as you just 
use 'import module' : ) I see this as a nice solution, and easy for the 
user of your program to use, for instance

----------------------------------
import input;

input.open()
input.process()

if (input.keyDown('a'))
   writefln("a key is down")
----------------------------------

versus

----------------------------------
import input;

gInput = new Input();

gInput.open();
gInput.process()

if (gInput.keyDown("a"))
   writefln("a key is down");
----------------------------------

Also, I have a module named window, which holds window width, size, etc, 
and that has similar function names so the code is familiar.

I am not asking that all D modules require this, I am just asking for a 
keyword (or something else?) to enforce the module namespace, or asking 
if someone can think of a better solution (I know I am not a master 
programmer)

What I have, a snippet from my code, is something like this...

---- input.d --------------
module input;

private
{
  // vars
}

public
{
  // funcs
  open()
  close()
}
---------------------------

I have a very similar

------- window.d ----------
module window;

private
{
  // vars
}

public
{
  open()
  close()
}
--------------------------

Now, with my program, window and input and guarenteed to be used 
together, and if one calls

open(); // depending on the cirsumstance, will either err or be 'ok',
        // but for consistency, I would rather force the code to be
        // input.open() or window.open(), so the programmer knows what
        // is happening and so, depending on what you import, you don't
        // all of a sudden get the compiler complaining to you

Maybe I'm making a big deal out of nothing, and I'll just let an 
ignorant programmer write weird code that could mean different things 
depending on what I import.


> 
> 
>>and the compiler will complain if they import another module with the same 
>>function name 'bar()'
> 
> 
> It should only complain when they try to use it. When that happens they will 
> have to use the foo.bar or an alias to fix the conflict.

if i can choose to have the compiler complain about foo in the first 
place, no worries :) as they'll have to use foo.bar.

also, they will not want to use an alias, because there is no better 
name they can alias too :)

> 
> You might be seeing import conflicts because of public imports, too. This, 
> actually, is one reason why private imports are better than public ones 
> because it can be nasty to track down conflicts when you nest several public 
> imports and somewhere along the chain a conflict happens. Keeping everything 
> private prevents that from happening.

It might be nice for D to force either 'public' or 'private' on all 
things within the module, and not default everything to 'public' or 
'priavte'

I know, at first, I didn't understand that D defaulted all module access 
to public. And, I don't think it hurts productivity to force either 
public or private, rather it makes the programmer think about what they 
really want to be shared within a module, potentially avoiding hard to 
track down future module conflicts within large programs.

Anyway, what it boils down to for me is that if i have module

module foo; // has bar() in it
module dance; // has bar() in it

bar(); // the compiler will complain, no?

Bar, is a public function, I want it to be public, I need it to be 
public. I know what I can hide and what I can't. :)

I just think it would be nice if I could make the compiler complain in 
the first place, so my library can not be abused.

> 
> -Ben 
> 
>
March 20, 2005
Re: is there a way to enforce module 'namespace' semantics?
clayasaurus wrote:

> Ben Hinkle wrote:
>>>The reason I want to enforce the module 'namespace' is because I'm using
>>>modules as a replacement for a global class. I have multiple modules with
>>>similar function names, and as the library writer, I don't want my users
>>>to just call 'bar()', because it is not how I want the module to be used
>> 
>> 
>> why not? D is designed to be used that way. Can you give more details
>> about the API? Personally I wouldn't fight the standard D style but one
>> is free to make whatever API one wants, I suppose. If the standard
>> approach results in errors or painful usage then I suggest posting
>> examples so that Walter can try to find a nice solution.
> 
> I would rather use a 'module global' instead of a 'class global',
> because with classes you have to 'new' it, and you have to give it a
> name, which would probably be something like 'gClass'. With a 'module
> global', the name is the module name, and I don't have to 'new' it.

I use classes with static methods and properties, thus having something like
a namespace. You don't have to 'new' a class to use its static methods and
members and you are forced to use MyClass.method() instead of just method()
like in modules.

ie.

module input;
class Input
{
 static
 {
   void open() { bla }
   void process() { bla }
   ...
 }
}

and

import input;

Input.open();
Input.process();

...
March 20, 2005
Re: is there a way to enforce module 'namespace' semantics?
> I use classes with static methods and properties, thus having something 
> like
> a namespace. You don't have to 'new' a class to use its static methods and
> members and you are forced to use MyClass.method() instead of just 
> method()
> like in modules.
>
> ie.
>
> module input;
> class Input
> {
>  static
>  {
>    void open() { bla }
>    void process() { bla }
>    ...
>  }
> }
>
> and
>
> import input;
>
> Input.open();
> Input.process();
>
> ...

Maybe it's just me but I don't want to see this become common in D. The 
whole point of the module rules is to free users from having to type Input. 
or whatever. Please don't force me as a user of your library to work in Java 
style where dummy classes wrap top-level functions. If you (meaning a 
library author) wants to always include the module name in your code because 
you think it looks nice then feel free to do that (it is legal D so it isn't 
a problem). But please let's keep D libraries free from the hacks that other 
languages need. The module rules in D are flexible enough to keep everyone 
happy. If they aren't then we need to alert Walter so that he can fix it up.
March 21, 2005
Re: is there a way to enforce module 'namespace' semantics?
Ben Hinkle wrote:
>>I use classes with static methods and properties, thus having something 
>>like
>>a namespace. You don't have to 'new' a class to use its static methods and
>>members and you are forced to use MyClass.method() instead of just 
>>method()
>>like in modules.
>>
>>ie.
>>
>>module input;
>>class Input
>>{
>> static
>> {
>>   void open() { bla }
>>   void process() { bla }
>>   ...
>> }
>>}
>>
>>and
>>
>>import input;
>>
>>Input.open();
>>Input.process();
>>
>>...
> 
> 
> Maybe it's just me but I don't want to see this become common in D. The 
> whole point of the module rules is to free users from having to type Input. 
> or whatever.

When you have two modules with the same functions, you are forced to 
type input anyway, the compiler will complain.

In my lib, you are guarenteed to have two modules with the same function 
names, out of design.

What happens when it goes wrong is that it you get a weird error 
message, like "foo.d(3): function foo.fooo conflicts with bar.fooo at 
bar.d(3)," that doesn't give you the name of the source file where the 
actual conflict occurs (in this case main.d), and it is a bit hard to 
track down in a large program.

I thought it would be better to enforce module namespace so these errors 
do not happen, and if you forget to do it then the compiler can tell you 
the line of code it goes wrong on.

> Please don't force me as a user of your library to work in Java 
> style where dummy classes wrap top-level functions. If you (meaning a 
> library author) wants to always include the module name in your code because 
> you think it looks nice then feel free to do that (it is legal D so it isn't 
> a problem). But please let's keep D libraries free from the hacks that other 
> languages need. The module rules in D are flexible enough to keep everyone 
> happy. If they aren't then we need to alert Walter so that he can fix it up. 
> 

I've decided i'm not going to use static classes or whatever (though 
neat trick!)

I'll just let the compiler bite when it feels it is time :-) And then 
they can have fun tracking it down, without DMD telling you the line or 
source where the conflict occurs. fun.
March 21, 2005
Re: is there a way to enforce module 'namespace' semantics?
clayasaurus wrote:
> 
> I've decided i'm not going to use static classes or whatever (though 
> neat trick!)
> 
> I'll just let the compiler bite when it feels it is time :-) And then 
> they can have fun tracking it down, without DMD telling you the line or 
> source where the conflict occurs. fun.
> 
> 

I'm with Ben here. What if in one of your modules you forget your 
proposed "enforce" attribute?

module a;
enforce:
void foo() {}

module b;
//oops, forgot enforce
void foo() {}

module usercode;
void bar()
{
    foo();     // user made a mistake: he meant a.foo
}

The compiler would not complain about it and the user would get a wrong 
result.

Again, I also prefer the flexibility that D gives right now.

_______________________
Carlos Santander Bernal
March 21, 2005
Re: is there a way to enforce module 'namespace' semantics?
clayasaurus wrote:
...

> When you have two modules with the same functions, you are forced to 
> type input anyway, the compiler will complain.
> 
> In my lib, you are guarenteed to have two modules with the same function 
> names, out of design.
> 
> What happens when it goes wrong is that it you get a weird error 
> message, like "foo.d(3): function foo.fooo conflicts with bar.fooo at 
> bar.d(3)," that doesn't give you the name of the source file where the 
> actual conflict occurs (in this case main.d), and it is a bit hard to 
> track down in a large program.

I think this part of the issue can best be solved by a better error 
message. Maybe if we mention these substandard error messages enough 
times, Walter will have a chance to fix them. ;)

-- 
Justin (a/k/a jcc7)
http://jcc_7.tripod.com/d/
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home