Possible way to achieve lazy loading with const objects

Jonathan M Davis jmdavisProg at gmx.com
Sun Sep 25 17:18:30 PDT 2011


On Monday, September 26, 2011 02:02:06 Simen Kjaeraas wrote:
> On Sat, 24 Sep 2011 13:19:33 +0200, Peter Alexander
> 
> <peter.alexander.au at gmail.com> wrote:
> > Lazy loading and caching are the same thing.
> > 
> > struct Foo
> > {
> > 
> >      T m_lazyObj = null;
> >      bool m_isLoaded = false;
> >      
> >      T getObj()
> >      {
> >      
> >          if (!m_isLoaded)
> >          {
> >          
> >              m_lazyObj = func();
> >              m_isLoaded = true;
> >          
> >          }
> >          return m_lazyObj;
> >      
> >      }
> > 
> > }
> > 
> > Change m_lazyObj to m_cachedObj and m_isLoaded to m_isCached and you
> > have caching.
> 
> This is too simple. If the system also rewrites all members to @properties
> that
> sets m_isLoaded = true, it might work. Example:
> 
> struct S {
>      int n;
>      lazy int otherN = () { return n + 2; } // compile time error here if
> you refer to lazily initialized members.
> }

Why would that be a compile time error? otherN won't be initialized until 
after n is. I suppose that it would be a problem if you tried to use otherN in 
the constructor, but if that's the case, why lazily load it? We could simply 
disallow the use of lazy member variables in constructors - though then you'd 
have to worry about whether a lazy member variable were used in any functions 
which the constructor called, so you'd probably have to disallow calling other 
member functions inside of the constructors of objects with lazy member 
variables. So, it does start to get a bit restrictive.

> =>
> 
> struct S {
>      int __n;
>      int __otherN;
>      bool __otherNloaded = false;
> 
> 
>      @property
>      int n( ) {
>          return __n;
>      }
> 
>      @property
>      int n(int value) {
>          if (__n != value) {
>              __n = value;
>              __otherNloaded = false;
>          }
>          return __n;
>      }
> 
>      @property
>      int otherN( ) {
>         if (!__otherNloaded) {
>             __otherN = () { return n + 2; }();
>             __otherNloaded = true;
>         }
>         return __otherN;
>      }
> }
> 
> Now, the overhead might be troublesome, but this seems to me to work.

That doesn't scale, and the compiler would have to know that it need to do 
that to n because the function inilializing otherN used n. I just don't think 
that that's tenable. So, it may be that further restrictions would have to be 
put on the initializing function for this to work, and if we do that, the idea 
could quickly become too limited to be very useful. Obviously, some more 
details need to be ironed out.

- Jonathan M Davis


More information about the Digitalmars-d mailing list