www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How can I do lazy variable initialization?

reply Jack <jckj33 gmail.com> writes:



  static Lazy<T> lazy =
        new Lazy<T>
            (() => heavyLoadOperation());
  static T value { get { return lazy.Value; } }
and heavyLoadOperation() is only called when variable "value" is actually used. How can I do something like this in D? I've tried something like this I still can't make it compile:
T delegate() lazy lazy = { return heavyOperation(); }
T X(lazy T delegate() dg) { return dg(); }
T value = X;
Jan 09
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
Explicit with a lambda:

import std;

int heavyLoadOperation() {
   writeln("Expensive!");
   return uniform(0, 10);
}

void main(string[] args) {
   const l = {
     bool inited = false;
     static int i;
     if (!inited) {
       i = heavyLoadOperation();
     }
     return i;
   }();

   if (args.length == 1) {
     writefln!"Using lazy variable: %s %s"(l, l);
   }
}

Getting help from memoize (this one is lovely):

alias lightLoadOperation = memoize!heavyLoadOperation;

   const l = lightLoadOperation();


lazy as well.

Ali
Jan 09
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 1/9/21 12:35 PM, Ali =C3=87ehreli wrote:

 alias lightLoadOperation =3D memoize!heavyLoadOperation;

    const l =3D lightLoadOperation();
Well, that doesn't work the way you want but this does: if (args.length =3D=3D 1) { writefln!"Using lazy variable: %s %s"(lightLoadOperation(),=20 lightLoadOperation()); } No matter how many times you call lightLoadOperation, it will be called=20 just once (which can be configured with maxSize): https://dlang.org/library/std/functional/memoize.html Ali
Jan 09
parent Jack <jckj33 gmail.com> writes:
On Saturday, 9 January 2021 at 20:39:26 UTC, Ali Çehreli wrote:
 On 1/9/21 12:35 PM, Ali Çehreli wrote:

 alias lightLoadOperation = memoize!heavyLoadOperation;

    const l = lightLoadOperation();
Well, that doesn't work the way you want but this does: if (args.length == 1) { writefln!"Using lazy variable: %s %s"(lightLoadOperation(), lightLoadOperation()); } No matter how many times you call lightLoadOperation, it will be called just once (which can be configured with maxSize): https://dlang.org/library/std/functional/memoize.html Ali
In case of a function that takes no arguments ever, using memoize may add memory overhead and something like this: bool loaded = false; T heavyLoadOperation() { if(!loaded) { // ... heavy operation. loaded = true; } return value; } can actually be better in terms of memory usage? I thought the lazy keyword could somehow help here but I think the way to go is is just use a flag, such as loaded bool variable.
Jan 09