Re: Making external types available to mixins

2018-11-24 Thread John Chapman via Digitalmars-d-learn

On Friday, 23 November 2018 at 21:49:55 UTC, Kagamin wrote:
Well, just have all factories in one module and import it, then 
they will be visible.


They're part of another library over which I have no control, but 
yes, I could still import them all and make life easier.



import allfactories;
auto makeWith(string className, Args…)(auto ref Args args) {
  mixin("return makeWith!(I", className, "Factory)(args);"); // 
Fowarded to implementation of makeWith below

}

Or predeclare make functions in factory modules

interface ICalendarFactory
{
  ...
}

alias makeCalendar=makeWith!ICalendarFactory;





Re: Making external types available to mixins

2018-11-23 Thread Kagamin via Digitalmars-d-learn

On Saturday, 17 November 2018 at 17:58:54 UTC, John Chapman wrote:
The following code doesn't compile because the generated type 
name needs to be available inside the mixin's scope, whereas 
it's actually in another module.


auto makeWith(string className, Args…)(auto ref Args args) {
  mixin("return makeWith!(I", className, "Factory)(args);"); // 
Fowarded to implementation of makeWith below

}

auto makeWith(T, Args…)(auto ref Args args) … // This is the 
implementation


The idea is that users could type (for example) 
makeWith!`Calendar`(…) instead of the longer 
makeWith!ICalendarFactory(…).


Well, just have all factories in one module and import it, then 
they will be visible.


import allfactories;
auto makeWith(string className, Args…)(auto ref Args args) {
  mixin("return makeWith!(I", className, "Factory)(args);"); // 
Fowarded to implementation of makeWith below

}

Or predeclare make functions in factory modules

interface ICalendarFactory
{
  ...
}

alias makeCalendar=makeWith!ICalendarFactory;


Re: Making external types available to mixins

2018-11-23 Thread John Chapman via Digitalmars-d-learn
On Thursday, 22 November 2018 at 16:27:08 UTC, Eduard Staniloiu 
wrote:

So I had a go at this and I have a working solution.
https://run.dlang.io/is/oaH6Ib

At first, I tried to do everything in the mixin, as you can see 
with the `failedAttempt` function. The idea was that this 
should have worked like `mixin(failedAttempt!"Calendar"(1, 2, 
3));`. As you can see, and the name suggests, I wasn't able to 
make it work with `args`.


The solution I have to your problem is to use a template, in 
this case the `theType` template that will expand to the fully 
qualified name. So you'd use it like

`makeWith!(theType!"Calendar")(args);`

Hope it helps!

Edi


Thanks!


Re: Making external types available to mixins

2018-11-22 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 17 November 2018 at 17:58:54 UTC, John Chapman wrote:
The following code doesn't compile because the generated type 
name needs to be available inside the mixin's scope, whereas 
it's actually in another module.


auto makeWith(string className, Args…)(auto ref Args args) {
  mixin("return makeWith!(I", className, "Factory)(args);"); // 
Fowarded to implementation of makeWith below

}

auto makeWith(T, Args…)(auto ref Args args) … // This is the 
implementation


The idea is that users could type (for example) 
makeWith!`Calendar`(…) instead of the longer 
makeWith!ICalendarFactory(…).


I tried mixing in an import statement with the help of 
std.traits.moduleName so that the I...Factory type would be 
available but again the compiler complains that it's undefined.


Has anyone had a similar need and come up with a solution?


you need to qualify the names: I use 
https://github.com/libmir/dcompute/blob/master/source/dcompute/driver/ocl/util.d#L77-L97
for this in dcompute (needs to be updated for the new style of 
mixin but you get the idea).


Re: Making external types available to mixins

2018-11-22 Thread Eduard Staniloiu via Digitalmars-d-learn

On Sunday, 18 November 2018 at 11:29:51 UTC, John Chapman wrote:
On Saturday, 17 November 2018 at 21:11:38 UTC, Adam D. Ruppe 
wrote:
On Saturday, 17 November 2018 at 17:58:54 UTC, John Chapman 
wrote:

Has anyone had a similar need and come up with a solution?


You might be able to just pass it the Calendar type, and then 
fetch its parent module and get the ICalendarFactory from 
there (assuming they are defined in the same module).


But generally speaking, passing strings to a mixin that refer 
to something in another module isn't going to work well thanks 
to scoping rules. You are better off passing a symbol of some 
sort.


So there is no actual Calendar type. There's an 
ICalendarFactory type that creates instances of ICalendar 
(these types are part of a third-party API).  "Calendar" is 
just a key users could use when calling a "makeWith" method 
that would build the ICalendar/Factory names, instantiate the 
factory, call the appropriate factory method and return the 
result. There are thousands of such object/factory pairs in the 
API. Just trying to cut out a lot of boilerplate code, but it 
doesn't seem doable this way.


Cheers,

So I had a go at this and I have a working solution.
https://run.dlang.io/is/oaH6Ib

At first, I tried to do everything in the mixin, as you can see 
with the `failedAttempt` function. The idea was that this should 
have worked like `mixin(failedAttempt!"Calendar"(1, 2, 3));`. As 
you can see, and the name suggests, I wasn't able to make it work 
with `args`.


The solution I have to your problem is to use a template, in this 
case the `theType` template that will expand to the fully 
qualified name. So you'd use it like

`makeWith!(theType!"Calendar")(args);`

Hope it helps!

Edi


Re: Making external types available to mixins

2018-11-18 Thread John Chapman via Digitalmars-d-learn
On Saturday, 17 November 2018 at 21:11:38 UTC, Adam D. Ruppe 
wrote:
On Saturday, 17 November 2018 at 17:58:54 UTC, John Chapman 
wrote:

Has anyone had a similar need and come up with a solution?


You might be able to just pass it the Calendar type, and then 
fetch its parent module and get the ICalendarFactory from there 
(assuming they are defined in the same module).


But generally speaking, passing strings to a mixin that refer 
to something in another module isn't going to work well thanks 
to scoping rules. You are better off passing a symbol of some 
sort.


So there is no actual Calendar type. There's an ICalendarFactory 
type that creates instances of ICalendar (these types are part of 
a third-party API).  "Calendar" is just a key users could use 
when calling a "makeWith" method that would build the 
ICalendar/Factory names, instantiate the factory, call the 
appropriate factory method and return the result. There are 
thousands of such object/factory pairs in the API. Just trying to 
cut out a lot of boilerplate code, but it doesn't seem doable 
this way.


Re: Making external types available to mixins

2018-11-17 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 17 November 2018 at 17:58:54 UTC, John Chapman wrote:

Has anyone had a similar need and come up with a solution?


You might be able to just pass it the Calendar type, and then 
fetch its parent module and get the ICalendarFactory from there 
(assuming they are defined in the same module).


But generally speaking, passing strings to a mixin that refer to 
something in another module isn't going to work well thanks to 
scoping rules. You are better off passing a symbol of some sort.


Re: Making external types available to mixins

2018-11-17 Thread Neia Neutuladh via Digitalmars-d-learn
On Sat, 17 Nov 2018 17:58:54 +, John Chapman wrote:
> The idea is that users could type (for example) makeWith!`Calendar`(…)
> instead of the longer makeWith!ICalendarFactory(…).

Your project might define a hundred types named ICalendarFactory; the 
compiler can't figure out which one you're talking about unless you use 
the fully qualified name.

If you require that Calendar and ICalendarFactory be defined in the same 
module, you can use Calendar's module name to look up the appropriate 
ICalendarFactory.

You can also just build a string that the calling code mixes in.


Making external types available to mixins

2018-11-17 Thread John Chapman via Digitalmars-d-learn
The following code doesn't compile because the generated type 
name needs to be available inside the mixin's scope, whereas it's 
actually in another module.


auto makeWith(string className, Args…)(auto ref Args args) {
  mixin("return makeWith!(I", className, "Factory)(args);"); // 
Fowarded to implementation of makeWith below

}

auto makeWith(T, Args…)(auto ref Args args) … // This is the 
implementation


The idea is that users could type (for example) 
makeWith!`Calendar`(…) instead of the longer 
makeWith!ICalendarFactory(…).


I tried mixing in an import statement with the help of 
std.traits.moduleName so that the I...Factory type would be 
available but again the compiler complains that it's undefined.


Has anyone had a similar need and come up with a solution?