www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Mixin helper help

reply John Chapman <john.chapman live.com> writes:
I'm obviously doing something wrong, but don't quite understand.

```d
mixin template helper() {
   mixin("writeln(12);");
}

struct Foo {
   void opDispatch(string name)() {
     import std.stdio;
     mixin helper!();
     //mixin("writeln(12);");
   }
}

void main() {
   Foo.init.opDispatch!"bar"();
}
```

The compiler emits these errors about the mixin ("writeln(12);"):
unexpected `(` in declarator
basic type expected, not `12`
found `12` when expecting `)`
no identifier for declarator `writeln(_error_)`
semicolon expected following function declaration
declaration expected, not `)`

Why does the commented code work but the mixin not? Thanks for 
any pointers.
Jan 12 2023
next sibling parent Hipreme <msnmancini hotmail.com> writes:
On Thursday, 12 January 2023 at 08:03:34 UTC, John Chapman wrote:
 I'm obviously doing something wrong, but don't quite understand.

 ```d
 mixin template helper() {
   mixin("writeln(12);");
 }

 struct Foo {
   void opDispatch(string name)() {
     import std.stdio;
     mixin helper!();
     //mixin("writeln(12);");
   }
 }

 void main() {
   Foo.init.opDispatch!"bar"();
 }
 ```

 The compiler emits these errors about the mixin 
 ("writeln(12);"):
 unexpected `(` in declarator
 basic type expected, not `12`
 found `12` when expecting `)`
 no identifier for declarator `writeln(_error_)`
 semicolon expected following function declaration
 declaration expected, not `)`

 Why does the commented code work but the mixin not? Thanks for 
 any pointers.
`mixin template` cannot be used like that. The only statement it accepts are declaration statements: Look at https://dlang.org/spec/module.html#MixinDeclaration It says it must compile to a valid DeclDef, which means you can't put code like that. Mixin templates are used only for declaring new variables, types and functions, it can't simply put call statements like that. You could do this by simply calling a function such as: ```d void helper() { writeln(12); } ``` I think you'll need to comment more on your problem if you wish specialized help
Jan 12 2023
prev sibling next sibling parent reply bauss <jacobbauss gmail.com> writes:
On Thursday, 12 January 2023 at 08:03:34 UTC, John Chapman wrote:
 I'm obviously doing something wrong, but don't quite understand.

 ```d
 mixin template helper() {
   mixin("writeln(12);");
 }

 struct Foo {
   void opDispatch(string name)() {
     import std.stdio;
     mixin helper!();
     //mixin("writeln(12);");
   }
 }

 void main() {
   Foo.init.opDispatch!"bar"();
 }
 ```

 The compiler emits these errors about the mixin 
 ("writeln(12);"):
 unexpected `(` in declarator
 basic type expected, not `12`
 found `12` when expecting `)`
 no identifier for declarator `writeln(_error_)`
 semicolon expected following function declaration
 declaration expected, not `)`

 Why does the commented code work but the mixin not? Thanks for 
 any pointers.
Mixin templates cannot have statements directly, so you need two changes for your code to work: 1. Change your mixin template to something like this: ```d mixin template helper() { // we place the statements in this function instead void helper() { mixin("writeln(12);"); } } ``` 2. Change the place where you instantiate to this: ```d struct Foo { void opDispatch(string name)() { import std.stdio; mixin helper!(); helper(); // calling the function in the mixin template } } ```
Jan 13 2023
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 1/13/23 00:48, bauss wrote:

 1. Change your mixin template to something like this:
There was a technique as a workaround for this template mixin limitation but I can't find it right now.
 2. Change the place where you instantiate to this:
I think the workaround I am trying to remember would not require any change for the users. Ok, it was something like this: mixin template myStatement() { auto doIt() { import std.stdio : writeln; writeln("hi"); return 0; } auto ignoreThis = doIt(); } void main() { mixin myStatement!(); mixin myStatement!(); } Ali
Jan 13 2023
parent reply bauss <jacobbauss gmail.com> writes:
On Friday, 13 January 2023 at 16:54:34 UTC, Ali Çehreli wrote:
 On 1/13/23 00:48, bauss wrote:

 1. Change your mixin template to something like this:
There was a technique as a workaround for this template mixin limitation but I can't find it right now.
 2. Change the place where you instantiate to this:
I think the workaround I am trying to remember would not require any change for the users. Ok, it was something like this: mixin template myStatement() { auto doIt() { import std.stdio : writeln; writeln("hi"); return 0; } auto ignoreThis = doIt(); } void main() { mixin myStatement!(); mixin myStatement!(); } Ali
That's a good one!
Jan 13 2023
next sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 14 January 2023 at 02:51:56 UTC, bauss wrote:
 Ali
That's a good one!
also very very good, it's clever! SDB 79
Jan 14 2023
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 1/13/23 18:51, bauss wrote:

 That's a good one!
It looks like you liked it four years ago as well. :) I found where I remembered it from: https://forum.dlang.org/post/pvdoq2$1e7t$3 digitalmars.com Ali
Jan 16 2023
parent bauss <jacobbauss gmail.com> writes:
On Monday, 16 January 2023 at 08:17:24 UTC, Ali Çehreli wrote:
 On 1/13/23 18:51, bauss wrote:

 That's a good one!
It looks like you liked it four years ago as well. :) I found where I remembered it from: https://forum.dlang.org/post/pvdoq2$1e7t$3 digitalmars.com Ali
Looks like my memory isn't as good, as I had totally forgotten about it, but perhaps because I haven't gotten to use it :)
Jan 16 2023
prev sibling next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Thursday, 12 January 2023 at 08:03:34 UTC, John Chapman wrote:
 Why does the commented code work but the mixin not? Thanks for 
 any pointers.
Why not directly use the mixin template for opDispatch()? ```d mixin template helper() { void opDispatch(string name)() { import std.stdio; writeln(12); } } struct Foo { mixin helper; // ... } void main() { Foo.init.opDispatch!"bar"(); } ``` SDB 79
Jan 13 2023
parent reply John Chapman <john.chapman live.com> writes:
On Friday, 13 January 2023 at 14:32:44 UTC, Salih Dincer wrote:
 Why not directly use the mixin template for opDispatch()?
My opDispatch generates code based on the arguments passed, interpolating variable names and functions based on the type. I wanted to remove the double braces in my static foreach (needed as I declared some aliases inside but since it creates a scope those new variables can't be referred to outside of it). I saw Adam's post here http://dpldocs.info/this-week-in-d/Blog.Posted_2022_12_26.html showing use of a "helper" template, and I was trying to adapt it. I've since just dropped the double braces and removed the aliases. It's not as clean but works.
Jan 14 2023
parent Adam D Ruppe <destructionator gmail.com> writes:
On Saturday, 14 January 2023 at 18:57:21 UTC, John Chapman wrote:
 I wanted to remove the double braces in my static foreach 
 (needed as I declared some aliases inside but since it creates 
 a scope those new variables can't be referred to outside of it).
Inside a function, you can often just use plain foreach instead of static foreach and simplify things. But it depends on the whole context. Where the helper thing helps a lot is outside functions, where normal foreach and double brace are both prohibited.
Jan 14 2023
prev sibling parent reply TheZipCreator <thezipcreator protonmail.com> writes:
On Thursday, 12 January 2023 at 08:03:34 UTC, John Chapman wrote:
 I'm obviously doing something wrong, but don't quite understand.

 ```d
 mixin template helper() {
   mixin("writeln(12);");
 }

 struct Foo {
   void opDispatch(string name)() {
     import std.stdio;
     mixin helper!();
     //mixin("writeln(12);");
   }
 }

 void main() {
   Foo.init.opDispatch!"bar"();
 }
 ```

 The compiler emits these errors about the mixin 
 ("writeln(12);"):
 unexpected `(` in declarator
 basic type expected, not `12`
 found `12` when expecting `)`
 no identifier for declarator `writeln(_error_)`
 semicolon expected following function declaration
 declaration expected, not `)`

 Why does the commented code work but the mixin not? Thanks for 
 any pointers.
This is not the purpose mixin templates are meant to serve. They're for copying declarations into scopes (and as such only support declarations in them). Instead, I think what you want is ```d template helper() { const char[] helper = `writeln(12);`; } struct Foo { void opDispatch(string name)() { import std.stdio; mixin(helper!()); } } void main() { Foo.init.opDispatch!"bar"(); } ```
Jan 14 2023
parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 14 January 2023 at 23:07:13 UTC, TheZipCreator wrote:
 This is not the purpose mixin templates are meant to serve. 
 They're for copying declarations into scopes (and as such only 
 support declarations in them). Instead, I think what you want is
I'm trying to understand you. But I regret to say that I do not agree with you. You are a programmer like me, so you don't like this usage? ```d template MyContainer(string varS = "") { struct Var { import std.variant; private Variant[string] values; alias values this; property { Variant opDispatch(string name)() const { return values[name]; } void opDispatch(string name, T)(T val) { values[name] = val; } } } static if(varS.length > 0) { import std.format; mixin(varS.format!"Var %s;"); } else Var data; } void main() { //otherTest("test ok");/* mixin MyContainer!"date"; enum Tarih { AY = 1, YIL = 2023 } date.month = cast(ubyte)Tarih.AY; date.month.write("/"); assert(date["month"] != Tarih.AY); // because : assert(date["month"].type == typeid(ubyte)); date.year = cast(short)Tarih.YIL; date.year.writeln(" in Turkish format"); assert(date["year"] != Tarih.YIL); // because : assert(date["year"].type == typeid(short)); writefln("Date: %s/%s", date.year, date.month);//*/ } /* Prints: 1/2023 in Turkish format Date: 2023/1 //*/ import std.stdio; void otherTest(string str) { mixin MyContainer; data.test = str; data.test.writeln; } ``` I'm 44 and maybe an old-fashioned person who likes macros. But mixins are all kinds of beautiful yaw 😀 Because they can be used as easily as importing. Moreover, they can be personalized. SDB 79
Jan 14 2023