Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread rempas via Digitalmars-d-learn
On Wednesday, 29 December 2021 at 17:20:59 UTC, max haughton 
wrote:
This is handled by the compiler backend. The simplest way it 
can do this kind of optimization is by "inlining" the function.


This is done by transplanting the function body into the place 
it's used. At this point the compiler simply sees "= 30 + 30" 
which it can trivially turn into "= 60" through something 
called constant-folding.


The compiler can create new function bodies (like the temp one 
you introduce above) but this is a much more niche 
optimization. They favour inlining much more aggressively.


I'm tempted to do a YouTube video of a D program being compiled 
all the way down the machine code, to show what the compiler 
does for you.


I didn't knew that compilers work like that. I thought that it 
will treat the values normally like they were values that cannot 
get computed at compile time even if you pass them as literals. 
That's good to know


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread max haughton via Digitalmars-d-learn

On Wednesday, 29 December 2021 at 16:51:47 UTC, rempas wrote:
On Wednesday, 29 December 2021 at 16:27:22 UTC, max haughton 
wrote:
Inlining + constant propagation. Fancier iterations on those 
exist too but 90% of the speedup will come from those since 
for it to matter they likely would've been used in first place.


Sounds like black magic? So If I write this:

```
int add(int num, int num2) { return num1 + num2; }

void main() {
  int number = add(10, 20);
}
```

The parameters are literals so will D translate this to:

```
int add(int num, int num2) { return num1 + num2; } // Normal one
int add_temp_func() { return 30; } // Created for the function 
call in main. No `add` instruction


void main() {
  int number = add(10, 20); // Will actually create and call 
"add_temp_func"

}
```

Or even better, this:

```
int add(int num, int num2) { return num1 + num2; }
void main() {
  int number = add(10, 20); // What we will type and it will 
get replaced with the following line
  int number = 30; // So it calculates the result at compile 
times and doesn't even do a function call

}
```

Is this what D can do? This is what I'm talking about when 
saying been able to use values at compile time.


This is handled by the compiler backend. The simplest way it can 
do this kind of optimization is by "inlining" the function.


This is done by transplanting the function body into the place 
it's used. At this point the compiler simply sees "= 30 + 30" 
which it can trivially turn into "= 60" through something called 
constant-folding.


The compiler can create new function bodies (like the temp one 
you introduce above) but this is a much more niche optimization. 
They favour inlining much more aggressively.


I'm tempted to do a YouTube video of a D program being compiled 
all the way down the machine code, to show what the compiler does 
for you.


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread rempas via Digitalmars-d-learn
On Wednesday, 29 December 2021 at 16:27:22 UTC, max haughton 
wrote:
Inlining + constant propagation. Fancier iterations on those 
exist too but 90% of the speedup will come from those since for 
it to matter they likely would've been used in first place.


Sounds like black magic? So If I write this:

```
int add(int num, int num2) { return num1 + num2; }

void main() {
  int number = add(10, 20);
}
```

The parameters are literals so will D translate this to:

```
int add(int num, int num2) { return num1 + num2; } // Normal one
int add_temp_func() { return 30; } // Created for the function 
call in main. No `add` instruction


void main() {
  int number = add(10, 20); // Will actually create and call 
"add_temp_func"

}
```

Or even better, this:

```
int add(int num, int num2) { return num1 + num2; }
void main() {
  int number = add(10, 20); // What we will type and it will get 
replaced with the following line
  int number = 30; // So it calculates the result at compile 
times and doesn't even do a function call

}
```

Is this what D can do? This is what I'm talking about when saying 
been able to use values at compile time.


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread max haughton via Digitalmars-d-learn

On Wednesday, 29 December 2021 at 15:53:38 UTC, rempas wrote:
On Wednesday, 29 December 2021 at 11:09:04 UTC, max haughton 
wrote:
If the value is known at compile time the compiler can pretty 
easily do that for you unless you're really unlucky.


How is this even possible?


Inlining + constant propagation. Fancier iterations on those 
exist too but 90% of the speedup will come from those since for 
it to matter they likely would've been used in first place.


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread rempas via Digitalmars-d-learn
On Wednesday, 29 December 2021 at 14:49:40 UTC, Steven 
Schveighoffer wrote:

On 12/29/21 3:55 AM, rempas wrote:

Thanks! That's cool but I don't want this to be this way. Or 
at least I want it to be able to take a default value so we 
don't have to get passed all the time.

OK:



```
extern (C) void main() {
   void print_num(int mul = 100)(int num) {
     static if (is(mul == ten)) {
   printf("%d\n", num * 10);
     } else static if (is(mul == three)) {
   printf("%d\n", num * 3);
     } else {
   printf("%d\n", num);
     }
   }

   int multi = 211;
   print_num!3(10); // Set the value
   print_num(30);    // Get the default value, have the 
"else" branch executed

}
```


Template parameters are just like regular parameters, but 
compile time.


-Steve


Oh! Didn't knew you could do something like that! It works as 
expected! Thanks a lot!


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread rempas via Digitalmars-d-learn
On Wednesday, 29 December 2021 at 11:09:04 UTC, max haughton 
wrote:
If the value is known at compile time the compiler can pretty 
easily do that for you unless you're really unlucky.


How is this even possible?


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/29/21 3:56 AM, rempas wrote:

On Tuesday, 28 December 2021 at 22:26:33 UTC, max haughton wrote:

Why do you need this? What's wrong with a normal branch in this case.


Runtime performance. I want the value to get checked at compile time and 
use "static if" with it


Oof, just let the compiler do its job. Inlining and optimization will 
take care of this for you (for the most part).


-Steve


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/29/21 3:55 AM, rempas wrote:

Thanks! That's cool but I don't want this to be this way. Or at least I 
want it to be able to take a default value so we don't have to get 
passed all the time.

OK:



```
extern (C) void main() {
   void print_num(int mul = 100)(int num) {
     static if (is(mul == ten)) {
   printf("%d\n", num * 10);
     } else static if (is(mul == three)) {
   printf("%d\n", num * 3);
     } else {
   printf("%d\n", num);
     }
   }

   int multi = 211;
   print_num!3(10); // Set the value
   print_num(30);    // Get the default value, have the "else" branch 
executed
}
```


Template parameters are just like regular parameters, but compile time.

-Steve


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread max haughton via Digitalmars-d-learn

On Wednesday, 29 December 2021 at 08:56:47 UTC, rempas wrote:
On Tuesday, 28 December 2021 at 22:26:33 UTC, max haughton 
wrote:
Why do you need this? What's wrong with a normal branch in 
this case.


Runtime performance. I want the value to get checked at compile 
time and use "static if" with it


If the value is known at compile time the compiler can pretty 
easily do that for you unless you're really unlucky.


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread rempas via Digitalmars-d-learn
On Wednesday, 29 December 2021 at 01:34:22 UTC, Stanislav Blinov 
wrote:

One can also do this kind of stuff:


```d
import core.stdc.stdio;

struct Literal(alias val)
{
enum value = val;
}

enum lit(alias val) = Literal!val.init;

void print_num(Arg)(int num, Arg mul)
{
static if (is(Arg == Literal!val, alias val))
{
static if (is(typeof(val) == string))
printf("mul by compile-time string \"%s\"!\n", 
val.ptr);

else static if (is(typeof(val) == int) && (val == 3))
printf("mul by compile-time 3!\n");
else
printf("mul by compile-time thing\n");
}
else
{
printf("mul by runtime thing\n");
}
}

void main()
{
print_num(10, lit!"hello"); // mul by compile-time string 
"hello"!

print_num(10, lit!3);   // mul by compile-time 3!
print_num(10, lit!'a'); // mul by compile-time thing
print_num(10, 10);  // mul by runtime thing
}
```


Thanks! That's awesome tho It will be annoying to have to type 
"lit!3" and not just pass it a literal or an "enum" or anything 
else that is guaranteed to be able to read at compile time.


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread rempas via Digitalmars-d-learn

On Tuesday, 28 December 2021 at 22:26:33 UTC, max haughton wrote:
Why do you need this? What's wrong with a normal branch in this 
case.


Runtime performance. I want the value to get checked at compile 
time and use "static if" with it


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-29 Thread rempas via Digitalmars-d-learn
On Tuesday, 28 December 2021 at 22:06:50 UTC, Steven 
Schveighoffer wrote:

On 12/28/21 4:19 PM, rempas wrote:

Here:


```
extern (C) void main() {
   void print_num(int mul)(int num) {
     static if (is(mul == ten)) {
   printf("%d\n", num * 10);
     } else static if (is(mul == three)) {
   printf("%d\n", num * 3);
     } else {
   printf("%d\n", num);
     }
   }

   int multi = 211;
   print_num!3(10); // Ok, accept this
   print_num!multi(10); // Error, do not accept this
}
```


-Steve


Thanks! That's cool but I don't want this to be this way. Or at 
least I want it to be able to take a default value so we don't 
have to get passed all the time. So something like this:


```
extern (C) void main() {
  void print_num(int num, comp_time_type int mul = 100) {
static if (is(mul == ten)) {
  printf("%d\n", num * 10);
} else static if (is(mul == three)) {
  printf("%d\n", num * 3);
} else {
  printf("%d\n", num);
}
  }

  int multi = 211;
  print_num(10, 3); // Set the value
  print_num(30);// Get the default value, have the "else" 
branch executed

}
```

Is this possible?



Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-28 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 28 December 2021 at 22:30:30 UTC, Ali Çehreli wrote:

On 12/28/21 2:06 PM, Steven Schveighoffer wrote:


   void print_num(int mul)(int num) {


Wasn't there a way of telling whether an 'auto ref' parameter 
is copied or not?


void print_num()(int num, auto ref int mul) {
  // ?
}

And that would indicate  that the argument was an rvalue?


__traits(isRef, mul).

I realize that rvalues are not exactly what the OP is 
interested in.


Yup, different thing.

One can also do this kind of stuff:


```d
import core.stdc.stdio;

struct Literal(alias val)
{
enum value = val;
}

enum lit(alias val) = Literal!val.init;

void print_num(Arg)(int num, Arg mul)
{
static if (is(Arg == Literal!val, alias val))
{
static if (is(typeof(val) == string))
printf("mul by compile-time string \"%s\"!\n", 
val.ptr);

else static if (is(typeof(val) == int) && (val == 3))
printf("mul by compile-time 3!\n");
else
printf("mul by compile-time thing\n");
}
else
{
printf("mul by runtime thing\n");
}
}

void main()
{
print_num(10, lit!"hello"); // mul by compile-time string 
"hello"!

print_num(10, lit!3);   // mul by compile-time 3!
print_num(10, lit!'a'); // mul by compile-time thing
print_num(10, 10);  // mul by runtime thing
}
```


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-28 Thread Ali Çehreli via Digitalmars-d-learn

On 12/28/21 2:06 PM, Steven Schveighoffer wrote:


   void print_num(int mul)(int num) {


Wasn't there a way of telling whether an 'auto ref' parameter is copied 
or not?


void print_num()(int num, auto ref int mul) {
  // ?
}

And that would indicate  that the argument was an rvalue?

I realize that rvalues are not exactly what the OP is interested in.

Ali



Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-28 Thread max haughton via Digitalmars-d-learn

On Tuesday, 28 December 2021 at 21:19:29 UTC, rempas wrote:
I would like to know if that's possible. Actually I would like 
to do something like the following:


```
extern (C) void main() {
  void print_num(int num, comp_time_type int mul) {
static if (is(mul == ten)) {
  printf("%d\n", num * 10);
} else static if (is(mul == three)) {
  printf("%d\n", num * 3);
} else {
  printf("%d\n", num);
}
  }

  int multi = 211;
  print_num(10, 3); // Ok, accept this
  print_num(10, multi); // Error, do not accept this
}
```

So I want to have "mul" only accept values that can be 
calculate at compile time so I can use it with things like 
"static if". Is this possible?


Why do you need this? What's wrong with a normal branch in this 
case.


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/28/21 4:19 PM, rempas wrote:

Here:


```
extern (C) void main() {
   void print_num(int mul)(int num) {
     static if (is(mul == ten)) {
   printf("%d\n", num * 10);
     } else static if (is(mul == three)) {
   printf("%d\n", num * 3);
     } else {
   printf("%d\n", num);
     }
   }

   int multi = 211;
   print_num!3(10); // Ok, accept this
   print_num!multi(10); // Error, do not accept this
}
```


-Steve


Re: Is there a way to make a function parameter accept only values that can be checked at compile time?

2021-12-28 Thread Tobias Pankrath via Digitalmars-d-learn

On Tuesday, 28 December 2021 at 21:19:29 UTC, rempas wrote:
I would like to know if that's possible. Actually I would like 
to do something like the following:


```
extern (C) void main() {
  void print_num(int num, comp_time_type int mul) {
static if (is(mul == ten)) {
  printf("%d\n", num * 10);
} else static if (is(mul == three)) {
  printf("%d\n", num * 3);
} else {
  printf("%d\n", num);
}
  }

  int multi = 211;
  print_num(10, 3); // Ok, accept this
  print_num(10, multi); // Error, do not accept this
}
```

So I want to have "mul" only accept values that can be 
calculate at compile time so I can use it with things like 
"static if". Is this possible?


I think you have to make 'mul' a template parameter.