Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 20, 2015 Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
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? |
March 20, 2015 Re: Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | 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. |
March 20, 2015 Re: Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | 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!()
|
March 20, 2015 Re: Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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.
|
March 20, 2015 Re: Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | 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:
>> 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.
Use case?
|
March 20, 2015 Re: Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | > 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]);
}
|
March 20, 2015 Re: Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | Now I am totally confused. lazy and eager evaluation are unrelated to compile time and run time. |
March 20, 2015 Re: Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On Friday, 20 March 2015 at 13:35:10 UTC, Dennis Ritchie wrote:
>> 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]);
> }
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.
|
March 20, 2015 Re: Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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:
>>> 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]);
>> }
>
> 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.
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.
|
March 20, 2015 Re: Lazy functions, lazy arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | 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.
|
Copyright © 1999-2021 by the D Language Foundation