digitalmars.D.learn - disable this for structs
- Steve Teale (5/5) Feb 27 2014 Could someone please explain what you would use this for to an
- Namespace (8/13) Feb 27 2014 It's for explicit initialization:
- Steve Teale (3/20) Feb 27 2014 So it is just a reminder that you need to initialize Bar in some
- John Colvin (4/29) Feb 27 2014 pretty much, yes.
- Namespace (2/27) Feb 27 2014 aye
- Adam D. Ruppe (12/12) Feb 27 2014 Basically, disabling the default constructor just forces the user
- Mike Parker (14/19) Feb 27 2014 I use it for namespaces.
- Namespace (6/29) Feb 27 2014 For such namespaces I use final abstract classes:
- bearophile (5/7) Feb 27 2014 Is this in Bugzilla somewhere? If it's a good idea then it could
- Dicebot (2/4) Feb 28 2014 Ideally one should use modules as namespaces :P
- Remo (4/8) Feb 28 2014 Ideally D should have build in namespaces.
- Tobias Pankrath (4/11) Feb 28 2014 Why? C like tag namespaces are awful and do C++ like namespaces
- Dicebot (4/13) Feb 28 2014 No. By design namespace is a module. You don't use classes for
- Mike Parker (13/17) Feb 28 2014 I don't buy that. That works fine to resolve conflicts, but it doesn't
- Dicebot (10/25) Feb 28 2014 D design is based on module as smallest composition unit. If you
- Mike Parker (32/45) Feb 28 2014 Consider this.
- Dicebot (16/36) Feb 28 2014 I'd write it this way:
- Mike Parker (18/32) Feb 28 2014 And as a user of your library, I'm going to be extremely annoyed that I
- Dicebot (4/4) Feb 28 2014 One feature I miss is "partial static import" - one that
- Steve Teale (4/4) Feb 28 2014 On Friday, 28 February 2014 at 16:02:26 UTC, Dicebot wrote:
Could someone please explain what you would use this for to an old man rooted in C++, but who loves D. Where does it fit in relative to 42? ;=( Steve
Feb 27 2014
On Thursday, 27 February 2014 at 18:10:38 UTC, Steve Teale wrote:Could someone please explain what you would use this for to an old man rooted in C++, but who loves D. Where does it fit in relative to 42? ;=( SteveIt's for explicit initialization: struct Foo { } Foo f; // no problem struct Bar { disable this(); } Bar b; // error
Feb 27 2014
On Thursday, 27 February 2014 at 18:13:43 UTC, Namespace wrote:On Thursday, 27 February 2014 at 18:10:38 UTC, Steve Teale wrote:So it is just a reminder that you need to initialize Bar in some specific way?Could someone please explain what you would use this for to an old man rooted in C++, but who loves D. Where does it fit in relative to 42? ;=( SteveIt's for explicit initialization: struct Foo { } Foo f; // no problem struct Bar { disable this(); } Bar b; // error
Feb 27 2014
On Thursday, 27 February 2014 at 18:26:10 UTC, Steve Teale wrote:On Thursday, 27 February 2014 at 18:13:43 UTC, Namespace wrote:pretty much, yes. More precisely, it disables the implicit no-op default constructor, forcing the user to use a different one.On Thursday, 27 February 2014 at 18:10:38 UTC, Steve Teale wrote:So it is just a reminder that you need to initialize Bar in some specific way?Could someone please explain what you would use this for to an old man rooted in C++, but who loves D. Where does it fit in relative to 42? ;=( SteveIt's for explicit initialization: struct Foo { } Foo f; // no problem struct Bar { disable this(); } Bar b; // error
Feb 27 2014
On Thursday, 27 February 2014 at 18:26:10 UTC, Steve Teale wrote:On Thursday, 27 February 2014 at 18:13:43 UTC, Namespace wrote:ayeOn Thursday, 27 February 2014 at 18:10:38 UTC, Steve Teale wrote:So it is just a reminder that you need to initialize Bar in some specific way?Could someone please explain what you would use this for to an old man rooted in C++, but who loves D. Where does it fit in relative to 42? ;=( SteveIt's for explicit initialization: struct Foo { } Foo f; // no problem struct Bar { disable this(); } Bar b; // error
Feb 27 2014
Basically, disabling the default constructor just forces the user to think about what they want there to initialize it, which also gives you a chance to check their values or funnel them toward a particular constructor/factory method. They can still choose to explicitly leave it unitialized with =void, or call a constructor with some value. Just when you write Foo f; and the compiler complains that default constructor is disabled, now you have to actually think about what to do next. If you consult the docs, it might say "use Foo.create() instead" and now you know. Or you might give it some value that makes sense.
Feb 27 2014
On 2/28/2014 3:10 AM, Steve Teale wrote:Could someone please explain what you would use this for to an old man rooted in C++, but who loves D. Where does it fit in relative to 42? ;=( SteveI use it for namespaces. struct Foo { disable this(); disable this( this ); private static { // members } public static { // methods } } Ideally, I'd love for the compiler to pick up on this idiom and not generate any typeinfo in this situation.
Feb 27 2014
On Friday, 28 February 2014 at 01:16:41 UTC, Mike Parker wrote:On 2/28/2014 3:10 AM, Steve Teale wrote:For such namespaces I use final abstract classes: final abstract class Foo { static: // members }Could someone please explain what you would use this for to an old man rooted in C++, but who loves D. Where does it fit in relative to 42? ;=( SteveI use it for namespaces. struct Foo { disable this(); disable this( this ); private static { // members } public static { // methods } } Ideally, I'd love for the compiler to pick up on this idiom and not generate any typeinfo in this situation.
Feb 27 2014
Mike Parker:Ideally, I'd love for the compiler to pick up on this idiom and not generate any typeinfo in this situation.Is this in Bugzilla somewhere? If it's a good idea then it could and should go in Bugzilla. Bye, bearophile
Feb 27 2014
On Friday, 28 February 2014 at 01:16:41 UTC, Mike Parker wrote:Ideally, I'd love for the compiler to pick up on this idiom and not generate any typeinfo in this situation.Ideally one should use modules as namespaces :P
Feb 28 2014
On Friday, 28 February 2014 at 11:59:40 UTC, Dicebot wrote:On Friday, 28 February 2014 at 01:16:41 UTC, Mike Parker wrote:Ideally D should have build in namespaces. Using class to mimic namespace, but then all the functions are virtual per default ?Ideally, I'd love for the compiler to pick up on this idiom and not generate any typeinfo in this situation.Ideally one should use modules as namespaces :P
Feb 28 2014
On Friday, 28 February 2014 at 12:52:38 UTC, Remo wrote:On Friday, 28 February 2014 at 11:59:40 UTC, Dicebot wrote:Why? C like tag namespaces are awful and do C++ like namespaces offer any benefit over modules? Keep in mind that we have no Koenig lookup.On Friday, 28 February 2014 at 01:16:41 UTC, Mike Parker wrote:Ideally D should have build in namespaces.Ideally, I'd love for the compiler to pick up on this idiom and not generate any typeinfo in this situation.Ideally one should use modules as namespaces :P
Feb 28 2014
On Friday, 28 February 2014 at 12:52:38 UTC, Remo wrote:On Friday, 28 February 2014 at 11:59:40 UTC, Dicebot wrote:No. By design namespace is a module. You don't use classes for namespaces, you create more modules. One may not like it but it is how D module system was created and it was intentional.On Friday, 28 February 2014 at 01:16:41 UTC, Mike Parker wrote:Ideally D should have build in namespaces. Using class to mimic namespace, but then all the functions are virtual per default ?Ideally, I'd love for the compiler to pick up on this idiom and not generate any typeinfo in this situation.Ideally one should use modules as namespaces :P
Feb 28 2014
On Friday, 28 February 2014 at 13:23:51 UTC, Dicebot wrote:On Friday, 28 February 2014 at 12:52:38 UTC, Remo wrote:Right now I do not really miss namespacec in D. I like modules in D. What I hate already are problems with structs and ctors. Most time while porting C++ code to D I spend a lot of time to resolve all the problems that happens because of struct ctors. If I forget to do this then it still compiles but does not work at all...On Friday, 28 February 2014 at 11:59:40 UTC, Dicebot wrote:No. By design namespace is a module. You don't use classes for namespaces, you create more modules. One may not like it but it is how D module system was created and it was intentional.On Friday, 28 February 2014 at 01:16:41 UTC, Mike Parker wrote:Ideally D should have build in namespaces. Using class to mimic namespace, but then all the functions are virtual per default ?Ideally, I'd love for the compiler to pick up on this idiom and not generate any typeinfo in this situation.Ideally one should use modules as namespaces :P
Feb 28 2014
On Friday, 28 February 2014 at 13:32:13 UTC, Remo wrote:What I hate already are problems with structs and ctors. Most time while porting C++ code to D I spend a lot of time to resolve all the problems that happens because of struct ctors. If I forget to do this then it still compiles but does not work at all...It is a long-standing bug and I am sorry for that. See http://forum.dlang.org/post/wziedbjjmxvabubvankk forum.dlang.org
Feb 28 2014
On 2/28/2014 8:59 PM, Dicebot wrote:On Friday, 28 February 2014 at 01:16:41 UTC, Mike Parker wrote:I don't buy that. That works fine to resolve conflicts, but it doesn't work for fine-grained namespace management. And when using named imports, that means everything in the module then belongs to that namespace, which isn't at all what I want. Besides which, using either fully-qualified names or named imports puts the impetus on the caller. If I design my modules around namespaces with the understanding that the caller will type foo.bar.myfunc all the time, there are bound to be conflicts when they forget to do it. On the other hand, by wrapping my namespaced stuff in structs or classes, I can have multiple namespaces per module, some things completely outside the namespace, and the user gets a compiler error if they don't use it. To me, that's much, much neater.Ideally, I'd love for the compiler to pick up on this idiom and not generate any typeinfo in this situation.Ideally one should use modules as namespaces :P
Feb 28 2014
On Friday, 28 February 2014 at 12:59:32 UTC, Mike Parker wrote:D design is based on module as smallest composition unit. If you find yourself in situation where you want to have two namespaces in a single module, you should split it into two modules. Putting impetus on caller (named imports) is good here and huge advantage over C++ way in my opinion. It gives more control over application naming scheme.Ideally one should use modules as namespaces :PI don't buy that. That works fine to resolve conflicts, but it doesn't work for fine-grained namespace management. And when using named imports, that means everything in the module then belongs to that namespace, which isn't at all what I want. Besides which, using either fully-qualified names or named imports puts the impetus on the caller. If I design my modules around namespaces with the understanding that the caller will type foo.bar.myfunc all the time, there are bound to be conflicts when they forget to do it.On the other hand, by wrapping my namespaced stuff in structs or classes, I can have multiple namespaces per module, some things completely outside the namespace, and the user gets a compiler error if they don't use it. To me, that's much, much neater.It simply does not fit with D type system, most importantly with accessiblity attributes. I'd hate to encounter all that you mention as "benefits" in some D library I am forced to use.
Feb 28 2014
On 2/28/2014 10:21 PM, Dicebot wrote:D design is based on module as smallest composition unit. If you find yourself in situation where you want to have two namespaces in a single module, you should split it into two modules.Consider this. enum Foo {...} interface Bar {} struct BarManager { public static { void initialize(); void terminate(); ... more stuff } } This is my use-case. I don't want my users to have to refer to Foo or Bar with any sort of prefix except to avoid name-clashes. However, I want to logically group the functions to manage Bars under a single grouping. I don't need or want a Singleton for it. I could use free functions, but I use the initialize/terminate idiom a lot. As a user of my own library, it would be horribly annoying to have to fully qualify each call. Plus, now and again I have multiple "namespace structs" in a single module. If I see them as all being closely related, why should I split them off into different modules?Putting impetus on caller (named imports) is good here and huge advantage over C++ way in my opinion. It gives more control over application naming scheme.One of the most annoying things for me in C++ is to see something like some::ridiculously::long::namespace, that I then have to use on each type declared in that namespace. That makes me add using statements to the top of each module, which defeats the purpose in the first place. I would find it equally annoying in D if every module I imported required me to use a fully-qualified module name. Luckily, that isn't the case. We only need to do it do avoid conflicts. My purpose for using namespaces in this way is twofold: to indicate that those particular functions serve a collective purpose, and to make give more meaning to the user code. I don't need to worry about naming conflicts, thanks to the module system, but I don't see the module as the smallest unit of organization.On the other hand, by wrapping my namespaced stuff in structs or classes, I can have multiple namespaces per module, some things completely outside the namespace, and the user gets a compiler error if they don't use it. To me, that's much, much neater.It simply does not fit with D type system, most importantly with accessiblity attributes. I'd hate to encounter all that you mention as "benefits" in some D library I am forced to use.
Feb 28 2014
On Friday, 28 February 2014 at 13:42:21 UTC, Mike Parker wrote:Consider this. enum Foo {...} interface Bar {} struct BarManager { public static { void initialize(); void terminate(); ... more stuff } } This is my use-case. I don't want my users to have to refer to Foo or Bar with any sort of prefix except to avoid name-clashes. However, I want to logically group the functions to manage Bars under a single grouping. I don't need or want a Singleton for it. I could use free functions, but I use the initialize/terminate idiom a lot. As a user of my own library, it would be horribly annoying to have to fully qualify each call. Plus, now and again I have multiple "namespace structs" in a single module. If I see them as all being closely related, why should I split them off into different modules?I'd write it this way: === something/bar.d === interface Bar {} === something/barmanager.d === import something.bar; // possibly public import void initialize(); void terminate(); === app.d === import something.bar; import barmanager = something.barmanager; // refer to Bar directly and to init function via barmanager.initialize() ========= Or, even better, turn bar into package and have something.bar.manager with same usage pattern.
Feb 28 2014
On 2/28/2014 11:37 PM, Dicebot wrote:I'd write it this way: === something/bar.d === interface Bar {} === something/barmanager.d === import something.bar; // possibly public import void initialize(); void terminate(); === app.d === import something.bar; import barmanager = something.barmanager; // refer to Bar directly and to init function via barmanager.initialize() ========= Or, even better, turn bar into package and have something.bar.manager with same usage pattern.And as a user of your library, I'm going to be extremely annoyed that I have to keep remembering to declare named imports to disambiguate all the intialize/terminate functions in all the modules that have them. If you're going to design your library that way, you should do it for me :) I see modules, loosely, as a way to group immediate family and packages as a way to group extended family. To me, Bar and BarManager are closely related, so they belong in the same module. It also makes long-term maintenance simpler, since everything related to Bar is in one place. And then there's D's module-scope access to private methods/members, which at some level encourages this approach (and which I make good use of). If I were to break all of my modules up as you have in this example, it unnecessarily inflates the number of modules, increases the maintenance cost somewhat, and takes away my module access to private. Anyway, I have a project I'm working on right now that I'll be putting up on github within a few weeks that serves as a more complete example. One of the great things about D is that it has enough room for both approaches.
Feb 28 2014
One feature I miss is "partial static import" - one that essentially automates `import modname = packname.modname`, allowing to qualify by module name only. That could have removed some repeating boilerplate from my code.
Feb 28 2014
On Friday, 28 February 2014 at 16:02:26 UTC, Dicebot wrote: ... Mmm, simple question, complicated answer. But the first one was enough for me at this point.
Feb 28 2014