digitalmars.D.learn - Scope of Mixins
- DLearner (23/23) Aug 26 2021 Please confirm that mixins of format:
- Paul Backus (7/29) Aug 26 2021 If the strings produced by `mxn1("Var1")` and `mxn2!"Var2"` are
- Adam D Ruppe (11/12) Aug 26 2021 You really shouldn't use string mixins like this at all. If you
- DLearner (14/26) Aug 26 2021 The object was to take a variable, and do alternative things with
- Adam D Ruppe (3/5) Aug 26 2021 That's *very* easy to do with the alias. You can just check
- =?UTF-8?Q?Ali_=c3=87ehreli?= (26/32) Aug 26 2021 String mixins are appealing because they can inject code like C macros
- Adam D Ruppe (6/9) Aug 26 2021 Template mixins are great, but obviously totally inappropriate
- =?UTF-8?Q?Ali_=c3=87ehreli?= (23/33) Aug 26 2021 m=20
- Adam D Ruppe (10/13) Aug 26 2021 In most cases that's better. A template constraint is really a
- DLearner (23/35) Aug 26 2021 Thank you for your suggestion.
- Adam D Ruppe (6/7) Aug 26 2021 Tip: you can instead of string of do
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
Aug 26 2021
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.
Aug 26 2021
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
Aug 26 2021
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: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...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
Aug 26 2021
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.
Aug 26 2021
On 8/26/21 10:06 AM, Adam D Ruppe wrote:On Thursday, 26 August 2021 at 17:01:06 UTC, DLearner 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. 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 = &i; 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. AliThe 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.
Aug 26 2021
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.
Aug 26 2021
On 8/26/21 10:45 AM, Adam D Ruppe wrote:On Thursday, 26 August 2021 at 17:39:16 UTC, Ali =C3=87ehreli wrote:=20String mixins are appealing because they can inject code like C macros=m=20do. It's not trivially possible to do the same with template mixins.=20 Template mixins are great, but obviously totally inappropriate here. I'=just talking about using a normal function, possibly with an alias=20 argument, instead of any kind of mixin. =20 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 =3D 42; x =3D valueFrom(i); int * p =3D &i; x =3D valueFrom(p); } In some cases it's more useful to have a 'static if' inside a single=20 function template instead of two separate function templates. Ali
Aug 26 2021
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.
Aug 26 2021
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: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"); } } ```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
Aug 26 2021
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)
Aug 26 2021