immutable singleton pattern with static opCall

Justin Johansson no at spam.com
Mon Jun 28 06:43:26 PDT 2010


Steven Schveighoffer wrote:
> On Mon, 28 Jun 2010 08:07:40 -0400, Justin Johansson <no at spam.com> wrote:
> 
>> Steven Schveighoffer wrote:
>>> On Sat, 26 Jun 2010 20:19:44 -0400, Michal Minich 
>>> <michal.minich at gmail.com> wrote:
>>>
>>>> On Sun, 27 Jun 2010 09:36:04 +0930, Justin Johansson wrote:
>>>>
>>>>> immutable class Foo
>>>>> {
>>>>>     static private Foo instance;
>>>>>
>>>>>     static this() {            // line 9
>>>>>        instance = new Foo;
>>>>>     }
>>>>>
>>>>>     static Foo opCall() {        // line 13
>>>>>        return instance;
>>>>>     }
>>>>> }
>>>>>
>>>>> test.d(9): Error: function test.Foo._staticCtor2 without 'this' cannot
>>>>> be const/immutable
>>>>> test.d(13): Error: function test.Foo.opCall without 'this' cannot be
>>>>> const/immutable
>>>>
>>>> there is bug report on this subject
>>>>
>>>> http://d.puremagic.com/issues/show_bug.cgi?id=3598
>>>>
>>>> Your example also uses static variable, which was not considered in the
>>>> bug report. This makes things more complex to design properly, 
>>>> because it
>>>> seems now that one does not want static functions to be affected by
>>>> immutable attribute of class, but it should affect static data...
>>>  static variables inside an immutable class should be immutable.  
>>> That was considered in the bug report and purposefully left out.
>>>  The issue is that the compiler incorrectly labels static *functions* 
>>> as immutable which makes no sense, static functions cannot be 
>>> immutable ever.  Static data can be.
>>>  BTW, you can work around this problem like this:
>>>  class Foo
>>> {
>>>    static immutable instance; // no need to make private, it can 
>>> never change
>>>     static this() {
>>>       instance = new Foo;  // not sure if this works, you may have to 
>>> cast.
>>>    }
>>>     static immutable(Foo) opCall() {
>>>       return instance;
>>>    }
>>>     immutable:
>>>     // member functions
>>> }
>>>  -Steve
>>
>> Thanks Steve.
>>
>> btw. The reason I marked the static instance member as private
>> was simply to enforce stylist use of Foo() rather than Foo.instance
> 
> Yuck Foo().xyz :)
> 
> But, whatever floats your boat.

I should explain the method to my madness.

Initially I was doing something else with static opCall and immutability
and then ran into the problem covered in this thread.  To save writing a
long story on this ng I reduced the problem to something that could be 
easily understood by choosing to demonstrate it via the singleton
pattern.

My actual use case is not a singleton pattern at all.  Rather my static
opCall for the immutable class(es) in question will normally take one
or more arguments.  The arguments will be validated first by the static
opCall.  Only then if the arguments are valid will a constructor be
called for some appropriate concrete subclass of the (abstract) class
in which the static opCall is declared.  This technique is
reminiscent of a factory pattern though I'll be using it to effect
a mechanism for memoizing results.  The overall agenda, being truly
idiomatic of functional programming, is to create a new instance of
some class only if there has not already been an invocation of the
static opCall with the same arguments.

Cheers and thanks again to Steve & Michal for all help.
Justin


More information about the Digitalmars-d mailing list