Re: lazy variables

2018-10-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/18/18 12:11 PM, aliak wrote:

On Thursday, 18 October 2018 at 14:11:36 UTC, Steven Schveighoffer wrote:


Yes, but that's what lazy variables do.



Not in Swift at least...


Apparently so (I have not used them before), but this is D! So you 
should be aware that lazy parameters work that way (the expression is 
evaluated each time the variable is used).


In any case, you can certainly create a Swift-like lazy variable and I 
think the other responses probably show you the way.


-Steve


Re: lazy variables

2018-10-18 Thread aliak via Digitalmars-d-learn

On Thursday, 18 October 2018 at 16:10:04 UTC, aliak wrote:
On Thursday, 18 October 2018 at 14:16:56 UTC, Simen Kjærås 
wrote:

On Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:

Hi,

Is there any notion of lazy vars in D (i see that there're 
parameters)?


What the language doesn't provide, it generally provides the 
tools to make:


struct Lazy(T) {
T delegate() _payload;
this(lazy T t) {
_payload = () => t;
}
T get() {
return _payload();
}
alias get this;
}

int fun() {
n++;
return 2;
}

int n;

unittest {
Lazy!int a = 1 + fun();
assert(n == 0); // Ensure fun hasn't been called.
auto b = a + 2;
assert(b == 5); // Ensure calculation is correct.
assert(n == 1); // Ensure fun has been called.
}

--
  Simen


yes! perfect! Thank you


With single eval:

struct Lazy(T) {
private T delegate() _payload;
private T _value;
private bool set = false;
this(lazy T t) {
_payload = () {
writeln("evaled");
return t;
};
}
@property T value() {
if (!set)
_value = _payload();
set = true;
return _value;
}

@property void value(T newValue) {
if (!set)
_value = _payload();
set = true;
_value = newValue;
}

alias value this;
}


Re: lazy variables

2018-10-18 Thread aliak via Digitalmars-d-learn

On Thursday, 18 October 2018 at 14:16:56 UTC, Simen Kjærås wrote:

On Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:

Hi,

Is there any notion of lazy vars in D (i see that there're 
parameters)?


What the language doesn't provide, it generally provides the 
tools to make:


struct Lazy(T) {
T delegate() _payload;
this(lazy T t) {
_payload = () => t;
}
T get() {
return _payload();
}
alias get this;
}

int fun() {
n++;
return 2;
}

int n;

unittest {
Lazy!int a = 1 + fun();
assert(n == 0); // Ensure fun hasn't been called.
auto b = a + 2;
assert(b == 5); // Ensure calculation is correct.
assert(n == 1); // Ensure fun has been called.
}

--
  Simen


yes! perfect! Thank you


Re: lazy variables

2018-10-18 Thread aliak via Digitalmars-d-learn
On Thursday, 18 October 2018 at 14:11:36 UTC, Steven 
Schveighoffer wrote:


Yes, but that's what lazy variables do.

-Steve


Not in Swift at least...


Re: lazy variables

2018-10-18 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 18 October 2018 at 14:08:11 UTC, aliak wrote:
On Wednesday, 17 October 2018 at 23:34:55 UTC, Paul Backus 
wrote:


auto x = () {
// do some heavy stuff
};

if (condition) {
func(x().y); // heavy stuff evaluated here
}


That would do heavy stuff everytime i wanted to get y though 
right?


Yes. If that's a problem, you could use `std.functional.memoize`, 
or Ali's solution.


Re: lazy variables

2018-10-18 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:

Hi,

Is there any notion of lazy vars in D (i see that there're 
parameters)?


What the language doesn't provide, it generally provides the 
tools to make:


struct Lazy(T) {
T delegate() _payload;
this(lazy T t) {
_payload = () => t;
}
T get() {
return _payload();
}
alias get this;
}

int fun() {
n++;
return 2;
}

int n;

unittest {
Lazy!int a = 1 + fun();
assert(n == 0); // Ensure fun hasn't been called.
auto b = a + 2;
assert(b == 5); // Ensure calculation is correct.
assert(n == 1); // Ensure fun has been called.
}

--
  Simen


Re: lazy variables

2018-10-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/18/18 10:08 AM, aliak wrote:

On Wednesday, 17 October 2018 at 23:34:55 UTC, Paul Backus wrote:

On Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:

lazy S x = () {
    // do some heavy stuff
}();

if (condition) {
  func(x.y); // heavy stuff evaluated here
}


auto x = () {
    // do some heavy stuff
};

if (condition) {
    func(x().y); // heavy stuff evaluated here
}


That would do heavy stuff everytime i wanted to get y though right?


Yes, but that's what lazy variables do.

-Steve


Re: lazy variables

2018-10-18 Thread aliak via Digitalmars-d-learn

On Wednesday, 17 October 2018 at 23:34:55 UTC, Paul Backus wrote:

On Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:

lazy S x = () {
// do some heavy stuff
}();

if (condition) {
  func(x.y); // heavy stuff evaluated here
}


auto x = () {
// do some heavy stuff
};

if (condition) {
func(x().y); // heavy stuff evaluated here
}


That would do heavy stuff everytime i wanted to get y though 
right?






Re: lazy variables

2018-10-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/17/18 3:32 AM, aliak wrote:

Hi,

Is there any notion of lazy vars in D (i see that there're parameters)?

i.e:

struct S {
   //...
   int y;
   //...
}


/*

lazy S x = () {
     // do some heavy stuff
}();

*/

auto x() { // do some heavy stuff
}



if (condition) {
   func(x.y); // heavy stuff evaluated here
}



-Steve


Re: lazy variables

2018-10-18 Thread aliak via Digitalmars-d-learn

On Wednesday, 17 October 2018 at 20:32:40 UTC, Ali Çehreli wrote:

On 10/17/2018 12:32 AM, aliak wrote:

[...]


Not very clean but something like this:

import std.stdio;

struct LazyVar(alias exp) {
alias T = typeof(exp());
T value() {
static bool initialized = false;
static T val;

if (!initialized) {
val = exp();
initialized = true;
}
return val;
}

alias value this;
}

LazyVar!(() {
writeln("Doing heavy stuff");
return 42;
}) a;

void main() {
auto b = a.value;// Must specify .value or
int c = a;   // must specify type of value (int).
 // Otherwise, b and c have type 
LazyVar!(...)


// Some more usage
b = c = a;

assert(b == 42);
assert(c == 42);
}

Ali


Well I guess that's certainly a way to go about it :) Not very 
clean indeed though.


Re: lazy variables

2018-10-17 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:

lazy S x = () {
// do some heavy stuff
}();

if (condition) {
  func(x.y); // heavy stuff evaluated here
}


auto x = () {
// do some heavy stuff
};

if (condition) {
func(x().y); // heavy stuff evaluated here
}

If you want to make it a little prettier, you could define a 
couple helper functions:


T delegate() delay(lazy T expr)
{
return () => expr;
}

T force(T delegate() thunk)
{
return thunk();
}


Re: lazy variables

2018-10-17 Thread Ali Çehreli via Digitalmars-d-learn

On 10/17/2018 12:32 AM, aliak wrote:

Hi,

Is there any notion of lazy vars in D (i see that there're parameters)?

i.e:

struct S {
   //...
   int y;
   //...
}

lazy S x = () {
     // do some heavy stuff
}();

if (condition) {
   func(x.y); // heavy stuff evaluated here
}

Cheers,
- Ali






Not very clean but something like this:

import std.stdio;

struct LazyVar(alias exp) {
alias T = typeof(exp());
T value() {
static bool initialized = false;
static T val;

if (!initialized) {
val = exp();
initialized = true;
}
return val;
}

alias value this;
}

LazyVar!(() {
writeln("Doing heavy stuff");
return 42;
}) a;

void main() {
auto b = a.value;// Must specify .value or
int c = a;   // must specify type of value (int).
 // Otherwise, b and c have type LazyVar!(...)

// Some more usage
b = c = a;

assert(b == 42);
assert(c == 42);
}

Ali



Re: lazy variables

2018-10-17 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:

Hi,

Is there any notion of lazy vars in D (i see that there're 
parameters)?


i.e:

struct S {
  //...
  int y;
  //...
}

lazy S x = () {
// do some heavy stuff
}();

if (condition) {
  func(x.y); // heavy stuff evaluated here
}

Cheers,
- Ali


This might be helpful:

https://dlang.org/articles/lazy-evaluation.html


Re: lazy variables cannot be lvalues - why?

2010-11-01 Thread Jonathan M Davis
On Monday, November 01, 2010 08:57:09 Adam Cigánek wrote:
 Hello,
 
 why is the following code illegal?
 
 
   import std.stdio;
 
   void delegate() fun;
 
   void capture(lazy void f) {
 fun = f;
   }
 
   void main() {
 capture(writeln(hello));
 fun();
   }
 
 
 It says Error: lazy variables cannot be lvalues, pointing to the
 fun = f line.
 
 It can be worked around by rewriting it like this:
 
 void capture(lazy void f) {
   fun = delegate void() { f(); };
 }
 
 So it's not big deal, just a minor inconvenience. But still, why is it
 illegal? According to the docs
 (http://www.digitalmars.com/d/2.0/lazy-evaluation.html), lazy
 expressions are implicitly converted to delegates, so it seems to me
 that it should work.
 
 adam.

1. I 'm stunned that the compiler doesn't complain about you declaring f as 
void. It strikes me as a bug with lazy. You can't declare variables of type 
void. It makes no sense.

2. A lazy parameter is for all intents an purposes the exact same thing as a 
non-lazy parameter except that it's not actually calculated until the function 
is called. The fact that a delegate to make it lazy is used is an 
implementation 
detail. Use typeof on it, and you'll notice that its type is the same as if it 
weren't lazy, not a delegate.

- Jonathan M Davis