digitalmars.D - mixin module template -> undefined identifier
- Robert Schadek (30/30) Oct 03 2013 I have some found some irregular behavior when using mixins with
- David Nadlinger (19/29) Oct 03 2013 Yes, this is indeed very much by design – A does not import B, so
- Robert Schadek (8/20) Oct 03 2013 Yes, it does not exists in the module but func is a template and I was
- David Nadlinger (13/25) Oct 03 2013 No. D doesn't have something like C++'s ADL where the template
- Robert Schadek (2/6) Oct 04 2013 I will try to find a way around.
- Dicebot (7/7) Oct 04 2013 By spec name resolution for templates happens in declaration
- Kenji Hara (10/32) Oct 03 2013 so
- Dicebot (3/3) Oct 04 2013 P.S. I have tried contacting you in context of std.logger, is
- Robert Schadek (2/5) Oct 04 2013 Yes it is, strange. Try the one I use here.
I have some found some irregular behavior when using mixins with template and modules. If a aggregation is defined in the same module it is found. If the aggregation is defined in another module it fails. And I wonder if this is be design. For comparison see the code below. // file: moduleA.d module A; public int func(T)() { return mixin(T.stringof ~ ".fun()"); } struct Bar { static int fun() { return 2; } } unittest { static assert(func!Bar() == 2); } // file: moduleB.d import A; struct Foo { static int fun() { return 1; } } void main() { assert(func!Foo() == 1); } dmd moduleA.d moduleB.d -ofmix -unittest moduleA.d(4): Error: undefined identifier Foo moduleB.d(10): Error: template instance A.func!(Foo) error instantiating
Oct 03 2013
On Thursday, 3 October 2013 at 17:52:13 UTC, Robert Schadek wrote:// file: moduleA.d module A; public int func(T)() { return mixin(T.stringof ~ ".fun()"); } […] dmd moduleA.d moduleB.d -ofmix -unittest moduleA.d(4): Error: undefined identifier Foo moduleB.d(10): Error: template instance A.func!(Foo) error instantiatingYes, this is indeed very much by design – A does not import B, so there is no reason why the name "Foo" should exist in A. To access the template parameter, just use it directly in the mixin (as in »mixin("T.fun()")«). I'm aware that the situation where you actually stumbled over this is probably a bit more complex, but in my experience an equivalent rewrite can almost always be performed quite easily once you have wrapped your head around the concept. Oh, and for those of you keeping track, this is another example supporting my stance that using "stringof" for code generation is (almost) always a bad idea. The fact that experienced D coders seem to run into this trap quite frequently, judging from the fact that is by far not the first NG thread on this topic, seems to suggest that we should address this with a big red warning in the documentation, probably where string mixins are discussed. (The recently merged pull request warning about .stringof use is a first step, albeit it does so for a different reason.) David
Oct 03 2013
On 10/03/2013 08:10 PM, David Nadlinger wrote:On Thursday, 3 October 2013 at 17:52:13 UTC, Robert Schadek wrote:Yes, it does not exists in the module but func is a template and I was under the impression symbols would be seen when instantiated. I mean the error starts with A.func!(Foo) error instantiating.dmd moduleA.d moduleB.d -ofmix -unittest moduleA.d(4): Error: undefined identifier Foo moduleB.d(10): Error: template instance A.func!(Foo) error instantiatingYes, this is indeed very much by design – A does not import B, so there is no reason why the name "Foo" should exist in A.To access the template parameter, just use it directly in the mixin (as in »mixin("T.fun()")«). I'm aware that the situation where you actually stumbled over this is probably a bit more complex, but in my experience an equivalent rewrite can almost always be performed quite easily once you have wrapped your head around the concept.Not as easy to fix this as I have a library that generates me sqlite code at compile time which I than mixin to have as good as handwritten code. I just found it odd that it works if I instantiate the template from the same module.
Oct 03 2013
On Thursday, 3 October 2013 at 18:39:48 UTC, Robert Schadek wrote:Yes, it does not exists in the module but func is a template and I was under the impression symbols would be seen when instantiated.No. D doesn't have something like C++'s ADL where the template arguments lead to additional names being introduced into the scope of the template body. This is by design.I mean the error starts with A.func!(Foo) error instantiating.Sorry, I don't quite get what you mean here. The error is just a follow-up to the previous one, as the inability to look up Foo caused an error while instantiating that template.Not as easy to fix this as I have a library that generates me sqlite code at compile time which I than mixin to have as good as handwritten code. I just found it odd that it works if I instantiate the template from the same module.Maybe you can elaborate a bit on how the problem occurs in that context? As I said, I've found that usually it is possible to come up with a design at least as pretty (or even prettier) but doesn't rely on stringof trickery if one just stares at the problem long enough. ;) David
Oct 03 2013
On 10/04/2013 04:36 AM, David Nadlinger wrote:Maybe you can elaborate a bit on how the problem occurs in that context? As I said, I've found that usually it is possible to come up with a design at least as pretty (or even prettier) but doesn't rely on stringof trickery if one just stares at the problem long enough. ;)I will try to find a way around.
Oct 04 2013
By spec name resolution for templates happens in declaration scope. Mixin templates are only exception. If referencing symbol from other module during code gen is a unavoidable necessity, you should use instrospection on `T` and add its module into code gen as template-local import (something like https://github.com/rejectedsoftware/vibe.d/blob/master/source/vibe/http/restutil.d#L341)
Oct 04 2013
2013/10/4 Robert Schadek <realburner gmx.de>On 10/03/2013 08:10 PM, David Nadlinger wrote:ngOn Thursday, 3 October 2013 at 17:52:13 UTC, Robert Schadek wrote:dmd moduleA.d moduleB.d -ofmix -unittest moduleA.d(4): Error: undefined identifier Foo moduleB.d(10): Error: template instance A.func!(Foo) error instantiati=soYes, this is indeed very much by design =E2=80=93 A does not import B, =e youthere is no reason why the name "Foo" should exist in A.Yes, it does not exists in the module but func is a template and I was under the impression symbols would be seen when instantiated. I mean the error starts with A.func!(Foo) error instantiating.To access the template parameter, just use it directly in the mixin (as in =C2=BBmixin("T.fun()")=C2=AB). I'm aware that the situation wher=Using built-in 'stringof' property for code generation won't work in general. Instead: public int func(T)() { return mixin("T" ~ ".fun()"); } Kenji Haraactually stumbled over this is probably a bit more complex, but in my experience an equivalent rewrite can almost always be performed quite easily once you have wrapped your head around the concept.Not as easy to fix this as I have a library that generates me sqlite code at compile time which I than mixin to have as good as handwritten code. I just found it odd that it works if I instantiate the template from the same module.
Oct 03 2013
P.S. I have tried contacting you in context of std.logger, is mail address mentioned on github valid one? If not, please ping me via public.dicebot.lv
Oct 04 2013
On 10/04/2013 09:07 AM, Dicebot wrote:P.S. I have tried contacting you in context of std.logger, is mail address mentioned on github valid one? If not, please ping me via public.dicebot.lvYes it is, strange. Try the one I use here.
Oct 04 2013