Re: Scope of Mixins

2021-08-26 Thread Adam D Ruppe via Digitalmars-d-learn

On Thursday, 26 August 2021 at 19:31:54 UTC, DLearner wrote:

   if (typeof(v).stringof == "int" ) {


Tip: you can instead of string of do

if (is(typeof(v) == int))


That is operator lets you compare types directly.

(stringof is something you will almost never use as you learn 
more of the language)


Re: Scope of Mixins

2021-08-26 Thread DLearner via Digitalmars-d-learn

On Thursday, 26 August 2021 at 16:28:22 UTC, Adam D Ruppe wrote:

On Thursday, 26 August 2021 at 16:16:55 UTC, DLearner wrote:

Please confirm that mixins of format:


You really shouldn't use string mixins like this at all. If you 
want to work with a variable, pass the variable itself as an 
argument to the function and use it with regular code instead 
of passing names as strings.


void do_something(alias v)() {
   // use v like a normal variable
}

int a;
do_someting!a; // pass the variable a as an alias so you can 
use it inside


Thank you for your suggestion.
For the record, the code below behaves as expected.
```
void main() {

   int  VarInt;
   int* VarIntPtr;
   double VarDbl;

   do_something!VarInt;
   do_something!VarIntPtr;
   do_something!VarDbl;
}

void do_something(alias v)() {

   import std.stdio;

   if (typeof(v).stringof == "int" ) {

  writeln("int var detected");
   } else if (typeof(v).stringof == "int*") {

  writeln("int* var detected");
   } else {

  writeln("Unrecognised type");
   }
}
```


Re: Scope of Mixins

2021-08-26 Thread Adam D Ruppe via Digitalmars-d-learn

On Thursday, 26 August 2021 at 18:07:48 UTC, Ali Çehreli wrote:
In some cases it's more useful to have a 'static if' inside a 
single function template instead of two separate function 
templates.


In most cases that's better. A template constraint is really a 
way to say "this template cannot accept this". When you use it to 
overload, the conditions get ugly fast since you need to make 
sure they're all mutually exclusive and the error messages get 
wrong since the compiler isn't sure if the thing can or can't be 
accepted.


What you generally want to do here is if the call - from the 
user's perspective - should work, make sure it gets through the 
constraint. Then do the details of branches inside.


Re: Scope of Mixins

2021-08-26 Thread Ali Çehreli via Digitalmars-d-learn

On 8/26/21 10:45 AM, Adam D Ruppe wrote:

On Thursday, 26 August 2021 at 17:39:16 UTC, Ali Çehreli wrote:
String mixins are appealing because they can inject code like C macros 
do. It's not trivially possible to do the same with template mixins.


Template mixins are great, but obviously totally inappropriate here. I'm 
just talking about using a normal function, possibly with an alias 
argument, instead of any kind of mixin.


Too often D programmers reach for fancy code generation when a simpler 
function is a better fit.


Agreed. Something like the following for the OP:

import std.traits : isPointer;

auto valueFrom(T)(T var)
if (isPointer!(typeof(var))) {
  return *var;
}

auto valueFrom(T)(T var)
if (!isPointer!(typeof(var))) {
  return var;
}

void main() {
  int x;
  int i = 42;
  x = valueFrom(i);

  int * p = 
  x = valueFrom(p);
}

In some cases it's more useful to have a 'static if' inside a single 
function template instead of two separate function templates.


Ali



Re: Scope of Mixins

2021-08-26 Thread Adam D Ruppe via Digitalmars-d-learn

On Thursday, 26 August 2021 at 17:39:16 UTC, Ali Çehreli wrote:
String mixins are appealing because they can inject code like C 
macros do. It's not trivially possible to do the same with 
template mixins.


Template mixins are great, but obviously totally inappropriate 
here. I'm just talking about using a normal function, possibly 
with an alias argument, instead of any kind of mixin.


Too often D programmers reach for fancy code generation when a 
simpler function is a better fit.


Re: Scope of Mixins

2021-08-26 Thread Ali Çehreli via Digitalmars-d-learn

On 8/26/21 10:06 AM, Adam D Ruppe wrote:

On Thursday, 26 August 2021 at 17:01:06 UTC, DLearner wrote:
The object was to take a variable, and do alternative things with it 
depending on (say) whether it was an 'int' or an 'int*'.


That's *very* easy to do with the alias. You can just check `typeof(v)` 
in there.


String mixins are appealing because they can inject code like C macros 
do. It's not trivially possible to do the same with template mixins.


import std.traits : isPointer;
import std.stdio : writeln;

mixin template valueFrom(alias var)
if (isPointer!(typeof(var))) {
  writeln("Dereferencing a pointer");  // ERROR
  x = *var;
}

mixin template valueFrom(alias var)
if (!isPointer!(typeof(var))) {
  writeln("Using a scalar");   // ERROR
  x = var;
}

void main() {
  int x;
  int i = 42;
  mixin valueFrom!i;

  int * p = 
  mixin valueFrom!p;
}

Yes, there are tricks one can play or change the design but when it 
comes to "injecting code", template mixins are not as convenient as 
string mixins.


Ali


Re: Scope of Mixins

2021-08-26 Thread Adam D Ruppe via Digitalmars-d-learn

On Thursday, 26 August 2021 at 17:01:06 UTC, DLearner wrote:
The object was to take a variable, and do alternative things 
with it depending on (say) whether it was an 'int' or an 'int*'.


That's *very* easy to do with the alias. You can just check 
`typeof(v)` in there.


Re: Scope of Mixins

2021-08-26 Thread DLearner via Digitalmars-d-learn

On Thursday, 26 August 2021 at 16:28:22 UTC, Adam D Ruppe wrote:

On Thursday, 26 August 2021 at 16:16:55 UTC, DLearner wrote:

Please confirm that mixins of format:


You really shouldn't use string mixins like this at all. If you 
want to work with a variable, pass the variable itself as an 
argument to the function and use it with regular code instead 
of passing names as strings.


void do_something(alias v)() {
   // use v like a normal variable
}

int a;
do_someting!a; // pass the variable a as an alias so you can 
use it inside


The object was to take a variable, and do alternative things with 
it depending on (say) whether it was an 'int' or an 'int*'.
Since entirely possible (indeed likely) that operations on 'int' 
invalid or meaningless with 'int*', to me seemed better to find a 
way that at _compile-time_ detected the difference, and only 
generated code valid for the type used.


Originally, there were mixins that only coped with each type.
These work, but a chore to update mixin name as variable type 
changed.
So idea is just one mixin which can compile-time detect variable 
type

and generate appropriate code.
Got it to work, except for this scoping issue...



Re: Scope of Mixins

2021-08-26 Thread Adam D Ruppe via Digitalmars-d-learn

On Thursday, 26 August 2021 at 16:16:55 UTC, DLearner wrote:

Please confirm that mixins of format:


You really shouldn't use string mixins like this at all. If you 
want to work with a variable, pass the variable itself as an 
argument to the function and use it with regular code instead of 
passing names as strings.


void do_something(alias v)() {
   // use v like a normal variable
}

int a;
do_someting!a; // pass the variable a as an alias so you can use 
it inside




Re: Scope of Mixins

2021-08-26 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 26 August 2021 at 16:16:55 UTC, DLearner wrote:

Please confirm that mixins of format:
```
string mxn1(string VarName) {
...
}
```
Invoked like:
```
mixin(mxn1("Var1"));
```

Have a wider scope than mixins like:
```
string mxn2(string VarName)() {
   ...
}
```
Invoked like:
```
mixin(mxn2!"Var2");
```


If the strings produced by `mxn1("Var1")` and `mxn2!"Var2"` are 
the same, mixing them in will have the same result. `mixin()` 
does not care where the string you pass to it comes from.


I tried direct replacement of former by the latter, could not 
get clean compile until definition moved into same module.


Something you are doing in the body of the functions is causing 
this, but because you have not included function bodies in your 
post, I cannot tell you what.


Scope of Mixins

2021-08-26 Thread DLearner via Digitalmars-d-learn

Please confirm that mixins of format:
```
string mxn1(string VarName) {
...
}
```
Invoked like:
```
mixin(mxn1("Var1"));
```

Have a wider scope than mixins like:
```
string mxn2(string VarName)() {
   ...
}
```
Invoked like:
```
mixin(mxn2!"Var2");
```

I tried direct replacement of former by the latter, could not get 
clean compile until definition moved into same module.



Best regards