www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Tango Style: Struct with no members?

reply Benji Smith <dlanguage benjismith.net> writes:
I've been reading a lot of the Tango source code lately, to educate 
myself on how the library works, and more generally, how to write good 
idiomatic D code.

As I've looked around, I've noticed a peculiar idiom popping up again 
and again that I've never seen or heard of before: struct definitions 
with no member fields, only functions. You can see it in 
"tango.time.WallClock" or "lib.common.tango.core.Runtime".

What's the rationale behind that?

I suppose it's something like a class with nothing but static methods. 
But then why not just define a module with only free functions? Is there 
a hidden benefit to implementing a pseudo-module as an empty struct?

Thanks!

--benji
Sep 06 2008
next sibling parent reply "Bill Baxter" <wbaxter gmail.com> writes:
On Sun, Sep 7, 2008 at 6:58 AM, Benji Smith <dlanguage benjismith.net> wrote:
 I've been reading a lot of the Tango source code lately, to educate myself
 on how the library works, and more generally, how to write good idiomatic D
 code.

 As I've looked around, I've noticed a peculiar idiom popping up again and
 again that I've never seen or heard of before: struct definitions with no
 member fields, only functions. You can see it in "tango.time.WallClock" or
 "lib.common.tango.core.Runtime".

 What's the rationale behind that?

 I suppose it's something like a class with nothing but static methods. But
 then why not just define a module with only free functions? Is there a
 hidden benefit to implementing a pseudo-module as an empty struct?

It prevents namespace pollution. In general you don't want to have a bunch of generically named functions like "getTime" floating around in the top level namespace. A user *can* do static or renamed import to prevent this, but since those are not the default, most users don't do that. In C++ you'd do the same thing with an explicit namespace, but D doesn't have a namespace construct separate from module namespaces. You have to use a struct or template to get that sort of effect. --bb
Sep 06 2008
parent reply Don <nospam nospam.com.au> writes:
Bill Baxter wrote:
 On Sun, Sep 7, 2008 at 6:58 AM, Benji Smith <dlanguage benjismith.net> wrote:
 I've been reading a lot of the Tango source code lately, to educate myself
 on how the library works, and more generally, how to write good idiomatic D
 code.

 As I've looked around, I've noticed a peculiar idiom popping up again and
 again that I've never seen or heard of before: struct definitions with no
 member fields, only functions. You can see it in "tango.time.WallClock" or
 "lib.common.tango.core.Runtime".

 What's the rationale behind that?

 I suppose it's something like a class with nothing but static methods. But
 then why not just define a module with only free functions? Is there a
 hidden benefit to implementing a pseudo-module as an empty struct?

It prevents namespace pollution. In general you don't want to have a bunch of generically named functions like "getTime" floating around in the top level namespace. A user *can* do static or renamed import to prevent this, but since those are not the default, most users don't do that. In C++ you'd do the same thing with an explicit namespace, but D doesn't have a namespace construct separate from module namespaces. You have to use a struct or template to get that sort of effect. --bb

Those structs date from before static import existed, when you HAD to do that. I wonder if they are still necessary?
Sep 23 2008
parent Sean Kelly <sean invisibleduck.org> writes:
Jarrett Billingsley wrote:
 On Tue, Sep 23, 2008 at 9:10 AM, Don <nospam nospam.com.au> wrote:
 Bill Baxter wrote:
 On Sun, Sep 7, 2008 at 6:58 AM, Benji Smith <dlanguage benjismith.net>
 wrote:
 I've been reading a lot of the Tango source code lately, to educate
 myself
 on how the library works, and more generally, how to write good idiomatic
 D
 code.

 As I've looked around, I've noticed a peculiar idiom popping up again and
 again that I've never seen or heard of before: struct definitions with no
 member fields, only functions. You can see it in "tango.time.WallClock"
 or
 "lib.common.tango.core.Runtime".

 What's the rationale behind that?

 I suppose it's something like a class with nothing but static methods.
 But
 then why not just define a module with only free functions? Is there a
 hidden benefit to implementing a pseudo-module as an empty struct?

bunch of generically named functions like "getTime" floating around in the top level namespace. A user *can* do static or renamed import to prevent this, but since those are not the default, most users don't do that. In C++ you'd do the same thing with an explicit namespace, but D doesn't have a namespace construct separate from module namespaces. You have to use a struct or template to get that sort of effect. --bb

that. I wonder if they are still necessary?

Static import is not enforceable, nor do most people want to have to write "tango.text.convert.Utf.toString". Renamed imports would be better, but they are also not enforceable. (Of course there's the DMD bug where renamed imports are implicitly public, regardless of the protection you put on it. Sigh.)

I'm of the opinion that the user shouldn't be forced to use namespaced names if they don't want them, so renamed imports are just fine. And with overload sets in D2 there's much less reason to force namespaces on the user anyway. So I'd consider this approach to be an anachronism. Sean
Sep 23 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Tue, Sep 23, 2008 at 9:10 AM, Don <nospam nospam.com.au> wrote:
 Bill Baxter wrote:
 On Sun, Sep 7, 2008 at 6:58 AM, Benji Smith <dlanguage benjismith.net>
 wrote:
 I've been reading a lot of the Tango source code lately, to educate
 myself
 on how the library works, and more generally, how to write good idiomatic
 D
 code.

 As I've looked around, I've noticed a peculiar idiom popping up again and
 again that I've never seen or heard of before: struct definitions with no
 member fields, only functions. You can see it in "tango.time.WallClock"
 or
 "lib.common.tango.core.Runtime".

 What's the rationale behind that?

 I suppose it's something like a class with nothing but static methods.
 But
 then why not just define a module with only free functions? Is there a
 hidden benefit to implementing a pseudo-module as an empty struct?

It prevents namespace pollution. In general you don't want to have a bunch of generically named functions like "getTime" floating around in the top level namespace. A user *can* do static or renamed import to prevent this, but since those are not the default, most users don't do that. In C++ you'd do the same thing with an explicit namespace, but D doesn't have a namespace construct separate from module namespaces. You have to use a struct or template to get that sort of effect. --bb

Those structs date from before static import existed, when you HAD to do that. I wonder if they are still necessary?

Static import is not enforceable, nor do most people want to have to write "tango.text.convert.Utf.toString". Renamed imports would be better, but they are also not enforceable. (Of course there's the DMD bug where renamed imports are implicitly public, regardless of the protection you put on it. Sigh.)
Sep 23 2008
prev sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Tue, Sep 23, 2008 at 1:59 PM, Sean Kelly <sean invisibleduck.org> wrote:
 Jarrett Billingsley wrote:
 On Tue, Sep 23, 2008 at 9:10 AM, Don <nospam nospam.com.au> wrote:
 Bill Baxter wrote:
 On Sun, Sep 7, 2008 at 6:58 AM, Benji Smith <dlanguage benjismith.net>
 wrote:
 I've been reading a lot of the Tango source code lately, to educate
 myself
 on how the library works, and more generally, how to write good
 idiomatic
 D
 code.

 As I've looked around, I've noticed a peculiar idiom popping up again
 and
 again that I've never seen or heard of before: struct definitions with
 no
 member fields, only functions. You can see it in "tango.time.WallClock"
 or
 "lib.common.tango.core.Runtime".

 What's the rationale behind that?

 I suppose it's something like a class with nothing but static methods.
 But
 then why not just define a module with only free functions? Is there a
 hidden benefit to implementing a pseudo-module as an empty struct?

It prevents namespace pollution. In general you don't want to have a bunch of generically named functions like "getTime" floating around in the top level namespace. A user *can* do static or renamed import to prevent this, but since those are not the default, most users don't do that. In C++ you'd do the same thing with an explicit namespace, but D doesn't have a namespace construct separate from module namespaces. You have to use a struct or template to get that sort of effect. --bb

Those structs date from before static import existed, when you HAD to do that. I wonder if they are still necessary?

Static import is not enforceable, nor do most people want to have to write "tango.text.convert.Utf.toString". Renamed imports would be better, but they are also not enforceable. (Of course there's the DMD bug where renamed imports are implicitly public, regardless of the protection you put on it. Sigh.)

I'm of the opinion that the user shouldn't be forced to use namespaced names if they don't want them, so renamed imports are just fine. And with overload sets in D2 there's much less reason to force namespaces on the user anyway. So I'd consider this approach to be an anachronism.

You just don't like Kris' coding style ;)
Sep 23 2008