Re: Lazy functions, lazy arrays

2015-03-20 Thread John Colvin via Digitalmars-d-learn

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!()


Re: Lazy functions, lazy arrays

2015-03-20 Thread Dennis Ritchie via Digitalmars-d-learn

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.


Re: Lazy functions, lazy arrays

2015-03-20 Thread Tobias Pankrath via Digitalmars-d-learn

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?


Re: Lazy functions, lazy arrays

2015-03-20 Thread John Colvin via Digitalmars-d-learn

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.


Re: Lazy functions, lazy arrays

2015-03-20 Thread Dennis Ritchie via Digitalmars-d-learn

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.


Re: Lazy functions, lazy arrays

2015-03-20 Thread Dennis Ritchie via Digitalmars-d-learn

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]);
}


Re: Lazy functions, lazy arrays

2015-03-20 Thread Adam D. Ruppe via Digitalmars-d-learn

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.


Re: Lazy functions, lazy arrays

2015-03-20 Thread Tobias Pankrath via Digitalmars-d-learn
Now I am totally confused. lazy and eager evaluation are 
unrelated to compile time  and run time.


Re: Lazy functions, lazy arrays

2015-03-20 Thread John Colvin via Digitalmars-d-learn

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.


Re: Lazy functions, lazy arrays

2015-03-20 Thread Dennis Ritchie via Digitalmars-d-learn

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)
}


Lazy functions, lazy arrays

2015-03-19 Thread Dennis Ritchie via Digitalmars-d-learn

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?