www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - mixin under -betterC

reply DLearner <bmqazwsx123 gmail.com> writes:
Code below is intended to test simple mixin with lambda function 
under -betterC.
Works with full-D, but fails with 'needs GC' errors under 
-betterC.

Why is this so, bearing in mind the concatenations are executed at
compile, not run, time?
```
// Test harness

    extern(C) void main() {
       import core.stdc.stdio : printf;
       import testmod;

       bool FirstVarGreater;
       int Var_A = 4;
       int Var_B = 3;


       FirstVarGreater = mixin(mxnTest("Var_A", "Var_B"));
       if (FirstVarGreater) {
             printf("First Var is Greater\n");
       } else {
             printf("First Var is not Greater\n");
       }
    }


// testmod

string mxnTest(string strVar1, string strVar2) {
    return `(int Var1, int Var2) {
       if (Var1 > Var2) {
          return true;
       } else {
          return false;
       }
    }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`;
}
```
Nov 23 2023
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:
 Code below is intended to test simple mixin with lambda 
 function under -betterC.
 Works with full-D, but fails with 'needs GC' errors under 
 -betterC.

 Why is this so, bearing in mind the concatenations are executed 
 at
 compile, not run, time?
This is a known limitation: https://issues.dlang.org/show_bug.cgi?id=23637 The easiest way to work around it is to change `mxnTest` from a function to a templated manifest constant: ```d enum mxnTest(string strVar1, string strVar2) = `(int Var1, int Var2) { if (Var1 > Var2) { return true; } else { return false; } }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`; ``` Keep in mind that you will also have to change the call site to pass `"Var_A"` and `"Var_B"` as template arguments: ```d // Note the ! in front of the argument list FirstVarGreater = mixin(mxnTest!("Var_A", "Var_B")); ```
Nov 23 2023
parent DLearner <bmqazwsx123 gmail.com> writes:
On Thursday, 23 November 2023 at 17:02:58 UTC, Paul Backus wrote:
[...]
 This is a known limitation: 
 https://issues.dlang.org/show_bug.cgi?id=23637
[...] Sorry to come back to this, but the reference above suggests _not_ a bug in the compiler. If not a bug in the compiler, please, what is going on? I repeat that the only possible trigger I see for the GC are the ~ that happen at compile, not run, time.
Nov 26 2023
prev sibling next sibling parent reply Julian Fondren <julian.fondren gmail.com> writes:
On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:
 Why is this so, bearing in mind the concatenations are executed 
 at
 compile, not run, time?
If you compile without -betterC, it'll work, but if you examine the result you'll find that the mxnTest function is still compiled into the result. D makes it so convenient to use functions at compile-time that there's no clear distinction for functions that should only exist at compile-time. Make mxnTest a template: ```d string mxnTest()(string strVar1, string strVar2) { ^^ ```
Nov 23 2023
parent reply DLearner <bmqazwsx123 gmail.com> writes:
On Thursday, 23 November 2023 at 17:03:29 UTC, Julian Fondren 
wrote:
 On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:
 Why is this so, bearing in mind the concatenations are 
 executed at
 compile, not run, time?
If you compile without -betterC, it'll work, but if you examine the result you'll find that the mxnTest function is still compiled into the result. D makes it so convenient to use functions at compile-time that there's no clear distinction for functions that should only exist at compile-time. Make mxnTest a template: ```d string mxnTest()(string strVar1, string strVar2) { ^^ ```
I tried what you suggested, and with no other changes it compiled and ran correctly. Thanks! I just find it surprising that your suggestion worked, but the (slightly simpler) earlier version did not.
Nov 23 2023
parent reply Julian Fondren <julian.fondren gmail.com> writes:
On Thursday, 23 November 2023 at 17:46:55 UTC, DLearner wrote:
 I just find it surprising that your suggestion worked, but the 
 (slightly simpler) earlier version did not.
The `enum` answer? That also works, but you have to make a change at the callsite as well, to `mixin(mxnTest!("Var_A", "Var_B"));` - passing the strings as template rather than functional arguments.
Nov 23 2023
parent DLearner <bmqazwsx123 gmail.com> writes:
On Thursday, 23 November 2023 at 18:54:09 UTC, Julian Fondren 
wrote:
[...]
 The `enum` answer?
[...] No, the 'template' answer. To me, if the 'template' suggestion worked (as it did), then my simple mixin (as in my original post) should also work.
Nov 23 2023
prev sibling next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:
 string mxnTest(string strVar1, string strVar2) {
    return `(int Var1, int Var2) {
       if (Var1 > Var2) {
          return true;
       } else {
          return false;
       }
    }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`;
 }
 ```
This function exists at runtime. Another module could, in theory, import it and call it. A shared library could, in theory, export it. You used it at compile time, but the function is available for other users too. betterC doesn't know the difference between theory and practice.
Nov 26 2023
parent DLearner <bmqazwsx123 gmail.com> writes:
On Sunday, 26 November 2023 at 15:35:39 UTC, Adam D Ruppe wrote:
 On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:
 string mxnTest(string strVar1, string strVar2) {
    return `(int Var1, int Var2) {
       if (Var1 > Var2) {
          return true;
       } else {
          return false;
       }
    }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`;
 }
 ```
This function exists at runtime. Another module could, in theory, import it and call it. A shared library could, in theory, export it. You used it at compile time, but the function is available for other users too. betterC doesn't know the difference between theory and practice.
From your comments and others on this thread: ``` // Test harness extern(C) void main() { import core.stdc.stdio : printf; import testmod; bool FirstVarGreater; int Var_A = 6; int Var_B = 5; FirstVarGreater = mixin(mxnTest("Var_A", "Var_B")); if (FirstVarGreater) { printf("First Var is Greater\n"); } else { printf("First Var is not Greater\n"); } } // testmod string mxnTest(string strVar1, string strVar2) { if (__ctfe) { return `(int Var1, int Var2) { if (Var1 > Var2) { return true; } else { return false; } }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`; } else { return ``; } } ``` Works, avoid templates + -betterC compliant, but to me clumsy.
Dec 09 2023
prev sibling parent Basile B. <b2.temp gmx.com> writes:
On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:
 Code below is intended to test simple mixin with lambda 
 function under -betterC.
 Works with full-D, but fails with 'needs GC' errors under 
 -betterC.

 Why is this so, bearing in mind the concatenations are executed 
 at
 compile, not run, time?
 ```
 // Test harness

    extern(C) void main() {
       import core.stdc.stdio : printf;
       import testmod;

       bool FirstVarGreater;
       int Var_A = 4;
       int Var_B = 3;


       FirstVarGreater = mixin(mxnTest("Var_A", "Var_B"));
       if (FirstVarGreater) {
             printf("First Var is Greater\n");
       } else {
             printf("First Var is not Greater\n");
       }
    }


 // testmod

 string mxnTest(string strVar1, string strVar2) {
    return `(int Var1, int Var2) {
       if (Var1 > Var2) {
          return true;
       } else {
          return false;
       }
    }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`;
 }
 ```
You've been explained the reason why that does not work, note however that it's not hopeless see - https://forum.dlang.org/thread/ahqnylrdftmmvtyvompr forum.dlang.org - https://github.com/dlang/dmd/pull/15636 unfortunately the PR is stalled since two months.
Nov 26 2023