digitalmars.D.learn - lazy variables
- aliak (17/17) Oct 17 2018 Hi,
- Chris Katko (3/20) Oct 17 2018 This might be helpful:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (30/56) Oct 17 2018 Not very clean but something like this:
- aliak (3/35) Oct 18 2018 Well I guess that's certainly a way to go about it :) Not very
- Paul Backus (17/23) Oct 17 2018 auto x = () {
- aliak (3/17) Oct 18 2018 That would do heavy stuff everytime i wanted to get y though
- Steven Schveighoffer (3/22) Oct 18 2018 Yes, but that's what lazy variables do.
- aliak (3/5) Oct 18 2018 Not in Swift at least...
- Steven Schveighoffer (7/13) Oct 18 2018 Apparently so (I have not used them before), but this is D! So you
- Paul Backus (3/15) Oct 18 2018 Yes. If that's a problem, you could use `std.functional.memoize`,
- Steven Schveighoffer (6/25) Oct 18 2018 */
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (27/30) Oct 18 2018 What the language doesn't provide, it generally provides the
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
Oct 17 2018
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, - AliThis might be helpful: https://dlang.org/articles/lazy-evaluation.html
Oct 17 2018
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, - AliNot 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
Oct 17 2018
On Wednesday, 17 October 2018 at 20:32:40 UTC, Ali Çehreli wrote:On 10/17/2018 12:32 AM, aliak wrote:Well I guess that's certainly a way to go about it :) Not very clean indeed though.[...]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
Oct 18 2018
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(); }
Oct 17 2018
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:That would do heavy stuff everytime i wanted to get y though right?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 }
Oct 18 2018
On 10/18/18 10:08 AM, aliak wrote:On Wednesday, 17 October 2018 at 23:34:55 UTC, Paul Backus wrote:Yes, but that's what lazy variables do. -SteveOn Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:That would do heavy stuff everytime i wanted to get y though right?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 }
Oct 18 2018
On Thursday, 18 October 2018 at 14:11:36 UTC, Steven Schveighoffer wrote:Yes, but that's what lazy variables do. -SteveNot in Swift at least...
Oct 18 2018
On 10/18/18 12:11 PM, aliak wrote:On Thursday, 18 October 2018 at 14:11:36 UTC, Steven Schveighoffer wrote: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. -SteveYes, but that's what lazy variables do.Not in Swift at least...
Oct 18 2018
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:Yes. If that's a problem, you could use `std.functional.memoize`, or Ali's solution.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?
Oct 18 2018
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
Oct 18 2018
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
Oct 18 2018
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:yes! perfect! Thank youHi, 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
Oct 18 2018
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: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; }On Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:yes! perfect! Thank youHi, 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
Oct 18 2018