I want to add a Phobos module with template mixins for common idioms.

Idan Arye GenericNPC at gmail.com
Mon May 20 17:03:19 PDT 2013


On Monday, 20 May 2013 at 23:18:59 UTC, Diggory wrote:
> On Monday, 20 May 2013 at 22:02:57 UTC, Idan Arye wrote:
>> If `hasInstance()` returns `true`, you can assume that there 
>> is an instance for you to access, because even if the instance 
>> is not ready yet, some other thread has entered the 
>> synchronization block and the user can't get the instance 
>> until that thread finishes the instantiation - so from the 
>> thread's point of view, whenever it'll call `instance()` it'll 
>> get a ready instance that was not created beacause of it.
>
> It can return true even if the instance has not been 
> initialised yet or false if it has because there's no 
> synchronisation on the read. Given that in either situation it 
> can return either true or false, there's no use for it.

If it returns `true` that means that either the instance is 
already initialized, or that it is currently being initialized in 
another thread. For all threads but the one that initializes the 
singleton, there is no difference between these two states:

1) a call to `instance()` will *not* create a new instance, and 
will return the *ready* instance.
2) a call to `singleton_tryInitInstance()` will *not* invoke the 
lazy initializer argument and will return `false`.
3) a call to `singleton_initInstance()` will *not* invoke the 
lazy initializer argument and will throw a `SingletonException`.

and ofcourse:

4) a call to `hasInstance()` will return `true`.

The only thing that will behave differently is a direct access to 
`__singleton_instance` - but this is something users of this 
library shouldn't be doing anyways!

>> First and foremost - this is library library code, so it 
>> should expose as much interface as possible without exposing 
>> or breaking the implementation.
>
> Only if the interface is useful and not likely to promote bad 
> code... It's better to give someone multiple tools, each well 
> suited for its purpose, than one tool that tries to do 
> everything but is not well suited to anything.

Programmers are lazy - they won't check if a singleton has been 
instantiated just for fun, not when the singleton handles 
instantiation automatically, or the method for manual 
instantiation does that check for you.

Bad usage of `hasInstance()`(beside busy waiting that Dmitry 
Olshansky mentioned - I'm going to provide a condition waiting 
function for that) involves more effort and gives nothing in 
return - therefore, people won't use it.

>> Personally, I think `hasInstance()` would be mainly used in 
>> the second use case you suggested. It would be useful if you 
>> have a long running loop(for example - a game loop) that needs 
>> to interact with the singleton instance if it exists, but 
>> can't or shouldn't instantiate it.
>
> In the second example you may as well do:
> if (getRandomBool()) {
>     ...
> } else {
>     ...
> }
>
> It has the exact same guarantees as your code.
>
> So what's the point of 'hasInstance'?

     class Foo{
         mixin LowLockSingleton;

         public this(int x){
             ...
         }

         public void bar(){
             ...
         }
     }

     ......

     if(getRandomBool()){
         /*1*/ Foo.instance.bar();
     }

     if(Foo.hasInstance){
         /*2*/ Foo.instance.bar();
     }

/*1*/ has a chance to throw an `SingletonException` if `Foo` has 
not been instantiated yet.
/*2*/ will not throw(unless `bar()` throws), because if 
`Foo.hasInstance` returns true, that means that either:
1) Foo is already instantiated.
2) Foo is in the instantiation process, which means that 
`Foo.instance` will reach a synchronization block, wait until 
`Foo` is instantiated.
In both of those cases, the fact that `Foo.hasInstance` returned 
`true` guarantee that `Foo.instance` will return a reference to a 
ready-to-use instance.


More information about the Digitalmars-d mailing list