digitalmars.D.learn - Lazy functions, lazy arrays
- Dennis Ritchie (3/3) Mar 19 2015 Hi,
- Dennis Ritchie (6/6) Mar 20 2015 For example,
- John Colvin (10/16) Mar 20 2015 I don't understand what you mean. You mean a function that isn't
- Dennis Ritchie (2/4) Mar 20 2015 Yes. That's exactly what I mean.
- Tobias Pankrath (2/6) Mar 20 2015 Use case?
- Dennis Ritchie (23/24) Mar 20 2015 No. I need to be able to make an array "factorials" is not
- Tobias Pankrath (2/2) Mar 20 2015 Now I am totally confused. lazy and eager evaluation are
- John Colvin (32/57) Mar 20 2015 Why? To make a smaller executable? For faster compilation?
- John Colvin (10/77) Mar 20 2015 I made a mistake about the static variable and thread-local
- Dennis Ritchie (31/40) Mar 20 2015 Thank you, but I can not figure out how I do this:
- John Colvin (3/46) Mar 20 2015 Both of those work for me on multiple dmd versions including git
- Adam D. Ruppe (4/5) Mar 20 2015 I do this with local imports so a module works without
Hi, Is it possible for D to create lazy functions, lazy arrays? Or in addition to the function arguments can't be lazy in D?
Mar 19 2015
For example, lazy int sum(int a = 3, int b = 5) { return a + b; } That is, if the function is not invoked, it should not be calculated at compile time.
Mar 20 2015
On Friday, 20 March 2015 at 10:02:27 UTC, Dennis Ritchie wrote:For example, lazy int sum(int a = 3, int b = 5) { return a + b; } That is, if the function is not invoked, it should not be calculated at compile time.I don't understand what you mean. You mean a function that isn't compiled if it isn't used anywhere? Template functions that are only compiled if instantiated, so you could write int sum()(int a, int b) { return a+b; } /\ empty braces for a 0-arg template. Can be called just like a normal function, the only time it would be necessary to explicitly write sum!() would be if you wanted to take it's address: &sum!()
Mar 20 2015
On Friday, 20 March 2015 at 10:38:17 UTC, John Colvin wrote:I don't understand what you mean. You mean a function that isn't compiled if it isn't used anywhere?Yes. That's exactly what I mean.
Mar 20 2015
On Friday, 20 March 2015 at 12:15:22 UTC, Dennis Ritchie wrote:On Friday, 20 March 2015 at 10:38:17 UTC, John Colvin wrote:Use case?I don't understand what you mean. You mean a function that isn't compiled if it isn't used anywhere?Yes. That's exactly what I mean.
Mar 20 2015
Use case?No. I need to be able to make an array "factorials" is not evaluated, if I don't. import std.stdio; enum N = 15; static int[] factorials = memoizeFactorials(N); // lazy array? :) int[] memoizeFactorials(int n) { if (!__ctfe) { // Make sure that this function is never called at run time assert(false); } int[] result = new int[n]; result[0] = 1; foreach (i; 1 .. n) { result[i] = result[i - 1] * i; } return result; } void main() { writeln(factorials[10]); }
Mar 20 2015
Now I am totally confused. lazy and eager evaluation are unrelated to compile time and run time.
Mar 20 2015
On Friday, 20 March 2015 at 13:35:10 UTC, Dennis Ritchie wrote:Why? To make a smaller executable? For faster compilation? This can work auto factorials()() property { //if we're here, factorials are used somewhere //generate them at compile-time. enum int[N] resultsE = memoizeFactorials(N); //put them in thread-local array on first access static resultsS = resultsE; return resultsS[]; } void main() { writeln(factorials[10]); } or much easier and simpler, but different: auto factorials()(int n) { //generate them at compile-time. enum int[N] results = memoizeFactorials(N); return results[n]; } void main() { writeln(factorials(10)); } However, none of this is a good idea at all. There are only 13 factorials (0 through 12) that fit in an int, so it's such a small array that you might as well write enum int[N] factorials = memoizeFactorials(N); and be done.Use case?No. I need to be able to make an array "factorials" is not evaluated, if I don't. import std.stdio; enum N = 15; static int[] factorials = memoizeFactorials(N); // lazy array? :) int[] memoizeFactorials(int n) { if (!__ctfe) { // Make sure that this function is never called at run time assert(false); } int[] result = new int[n]; result[0] = 1; foreach (i; 1 .. n) { result[i] = result[i - 1] * i; } return result; } void main() { writeln(factorials[10]); }
Mar 20 2015
On Friday, 20 March 2015 at 14:20:16 UTC, John Colvin wrote:On Friday, 20 March 2015 at 13:35:10 UTC, Dennis Ritchie wrote:I made a mistake about the static variable and thread-local storage. immutable(int)[] factorials()() property { static immutable int[N] results = memoizeFactorials(N); return results[]; } is the correct way to do it if you have to. Still, it's totally not worth doing for such a short array.Why? To make a smaller executable? For faster compilation? This can work auto factorials()() property { //if we're here, factorials are used somewhere //generate them at compile-time. enum int[N] resultsE = memoizeFactorials(N); //put them in thread-local array on first access static resultsS = resultsE; return resultsS[]; } void main() { writeln(factorials[10]); } or much easier and simpler, but different: auto factorials()(int n) { //generate them at compile-time. enum int[N] results = memoizeFactorials(N); return results[n]; } void main() { writeln(factorials(10)); } However, none of this is a good idea at all. There are only 13 factorials (0 through 12) that fit in an int, so it's such a small array that you might as well write enum int[N] factorials = memoizeFactorials(N); and be done.Use case?No. I need to be able to make an array "factorials" is not evaluated, if I don't. import std.stdio; enum N = 15; static int[] factorials = memoizeFactorials(N); // lazy array? :) int[] memoizeFactorials(int n) { if (!__ctfe) { // Make sure that this function is never called at run time assert(false); } int[] result = new int[n]; result[0] = 1; foreach (i; 1 .. n) { result[i] = result[i - 1] * i; } return result; } void main() { writeln(factorials[10]); }
Mar 20 2015
On Friday, 20 March 2015 at 14:27:06 UTC, John Colvin wrote:I made a mistake about the static variable and thread-local storage. immutable(int)[] factorials()() property { static immutable int[N] results = memoizeFactorials(N); return results[]; } is the correct way to do it if you have to. Still, it's totally not worth doing for such a short array.Thank you, but I can not figure out how I do this: import std.stdio; enum N = 12; immutable(int)[] factorials()() property { static immutable int[N] results = memoizeFactorials(N); return results[]; } int[] memoizeFactorials(int n) { if (!__ctfe) // Make sure that this function is never called at run time assert(false); int[] result = new int[n]; result[0] = 1; foreach (i; 1 .. n) result[i] = result[i - 1] * i; return result; } void main() { bool flag; if (flag) { factorials(); writeln(factorials[10]); // 3628800 } else writeln(factorials[10]); // range violation(35) }
Mar 20 2015
On Friday, 20 March 2015 at 16:01:51 UTC, Dennis Ritchie wrote:On Friday, 20 March 2015 at 14:27:06 UTC, John Colvin wrote:Both of those work for me on multiple dmd versions including git HEAD.I made a mistake about the static variable and thread-local storage. immutable(int)[] factorials()() property { static immutable int[N] results = memoizeFactorials(N); return results[]; } is the correct way to do it if you have to. Still, it's totally not worth doing for such a short array.Thank you, but I can not figure out how I do this: import std.stdio; enum N = 12; immutable(int)[] factorials()() property { static immutable int[N] results = memoizeFactorials(N); return results[]; } int[] memoizeFactorials(int n) { if (!__ctfe) // Make sure that this function is never called at run time assert(false); int[] result = new int[n]; result[0] = 1; foreach (i; 1 .. n) result[i] = result[i - 1] * i; return result; } void main() { bool flag; if (flag) { factorials(); writeln(factorials[10]); // 3628800 } else writeln(factorials[10]); // range violation(35) }
Mar 20 2015
On Friday, 20 March 2015 at 12:52:16 UTC, Tobias Pankrath wrote:Use case?I do this with local imports so a module works without dependencies unless you use the specific functions that need the additional module.
Mar 20 2015