Thread overview
Multiple template alias parameters
May 08, 2015
Brian Schott
May 08, 2015
Rikki Cattermole
May 08, 2015
Brian Schott
May 08, 2015
Artur Skawina
May 08, 2015
Brian Schott
May 08, 2015
Biotronic
May 08, 2015
anonymous
May 09, 2015
Artur Skawina
May 08, 2015
I have some code that automatically wires up control flow based on annotations. Use of this code looks something like this:

```
import some_package.some_module;
void main(string[] args) {
   doMagicStuff!(some_package.some_module)(args);
}
```

All of this works and everything is happy (Except the implementation, which is ugly because Phobos is missing a lot of functionality, but that's not the topic I'm discussing here).

The problem occurs when I want to register multiple modules to scan for functions. The grammar does not allow this syntax:

```
template (alias Modules ...) {
...
```

Any ideas (besides "STRING MIXINS EVERYWHERE")?

May 08, 2015
On 8/05/2015 1:53 p.m., Brian Schott wrote:
> I have some code that automatically wires up control flow based on
> annotations. Use of this code looks something like this:
>
> ```
> import some_package.some_module;
> void main(string[] args) {
>     doMagicStuff!(some_package.some_module)(args);
> }
> ```
>
> All of this works and everything is happy (Except the implementation,
> which is ugly because Phobos is missing a lot of functionality, but
> that's not the topic I'm discussing here).
>
> The problem occurs when I want to register multiple modules to scan for
> functions. The grammar does not allow this syntax:
>
> ```
> template (alias Modules ...) {
> ...
> ```
>
> Any ideas (besides "STRING MIXINS EVERYWHERE")?
>

Can you not use something like this?

import std.stdio;
import std.traits;

void main() {
	func!(std.stdio, std.traits)();		
}


void func(T...)() {
	pragma(msg, T.stringof);
	pragma(msg, fullyQualifiedName!(T[0]));
	
}
May 08, 2015
On 05/08/15 03:53, Brian Schott via Digitalmars-d-learn wrote:
> The problem occurs when I want to register multiple modules to scan for functions. The grammar does not allow this syntax:
> 
> ```
> template (alias Modules ...) {
> ...
> ```

The grammar allows omitting the 'alias' keyword.

artur
May 08, 2015
On Friday, 8 May 2015 at 02:03:17 UTC, Rikki Cattermole wrote:
> Can you not use something like this?

Yes. I was getting confused by another problem that I had just worked on before this one.
May 08, 2015
On Friday, 8 May 2015 at 12:44:31 UTC, Artur Skawina wrote:
> On 05/08/15 03:53, Brian Schott via Digitalmars-d-learn wrote:
>> The problem occurs when I want to register multiple modules to scan for functions. The grammar does not allow this syntax:
>> 
>> ```
>> template (alias Modules ...) {
>> ...
>> ```
>
> The grammar allows omitting the 'alias' keyword.
>
> artur

alias parameters are different from normal template parameters. They're not necessary for this problem, but they are for others.

As an example:


void traceVar(alias var, size_t line = __LINE__, string file = __FILE__)()
{
	import std.stdio: stderr;
	stderr.writeln(file, "(", line, ") ", var.stringof, ": ", var);
}

This allows you to print a variable's name and value by only passing the variable once as a template argument. Allowing "template Tem(alias Args ...)" syntax would let me trace multiple variables at once.

If you omit "alias", "var.stringof" evaluates to "var" instead of its name in the calling context.
May 08, 2015
On Friday, 8 May 2015 at 21:56:56 UTC, Brian Schott wrote:
> Allowing "template Tem(alias Args ...)" syntax would let me trace multiple variables at once.

Actually, this already works:

void traceVars(alias T, U...)() {
    import std.stdio : writeln;
    writeln(T.stringof, ": ", T);
    static if (U.length > 0) {
        traceVars!(U);
    }
}

void main(string[] args) {
    auto argslength = args.length;
    auto args0 = args[0];

    traceVars!(args, argslength, args0);
}

Sadly, the ... syntax precludes the use of __LINE__ and __FILE__. :(
May 08, 2015
On Friday, 8 May 2015 at 22:29:28 UTC, Biotronic wrote:
> Sadly, the ... syntax precludes the use of __LINE__ and __FILE__. :(

You can put them in the runtime parameters:

----
void traceVars(alias T, U...)(size_t line = __LINE__, string file = __FILE__) {
    import std.stdio : writeln;
    writeln(file, "(", line, ") ", T.stringof, ": ", T);
    static if (U.length > 0) {
        traceVars!(U)(line, file);
    }
}
----

Or you can nest two templates:

----
template traceVars(alias T, U...) {
    void traceVars(size_t line = __LINE__, string file = __FILE__)() {
        import std.stdio : writeln;
        writeln(file, "(", line, ") ", T.stringof, ": ", T);
        static if (U.length > 0) {
            alias t = .traceVars!U;
            t!(line, file);
        }
    }
}
----
May 09, 2015
On 05/08/15 23:56, Brian Schott via Digitalmars-d-learn wrote:
> On Friday, 8 May 2015 at 12:44:31 UTC, Artur Skawina wrote:
>> On 05/08/15 03:53, Brian Schott via Digitalmars-d-learn wrote:
>>> The problem occurs when I want to register multiple modules to scan for functions. The grammar does not allow this syntax:
>>>
>>> ```
>>> template (alias Modules ...) {
>>> ...
>>> ```
>>
>> The grammar allows omitting the 'alias' keyword.
>>
>> artur
> 
> alias parameters are different from normal template parameters. They're not necessary for this problem, but they are for others.

I was trying to hint at the fact that D's template tuple parameters
already have the required magic.
Hence, the trailing '...' makes that 'alias' unnecessary.

> As an example:
> 
> 
> void traceVar(alias var, size_t line = __LINE__, string file = __FILE__)()
> {
>     import std.stdio: stderr;
>     stderr.writeln(file, "(", line, ") ", var.stringof, ": ", var);
> }
> 
> This allows you to print a variable's name and value by only passing the variable once as a template argument. Allowing "template Tem(alias Args ...)" syntax would let me trace multiple variables at once.
> 
> If you omit "alias", "var.stringof" evaluates to "var" instead of its name in the calling context.

   template traceVar(VARS...) {
      void traceVar(size_t line = __LINE__, string file = __FILE__)() {
         import std.stdio: stderr;
         foreach (I, ref var; VARS)
            stderr.writeln(file, "(", line, ") ", VARS[I].stringof, ": ", var);
      }
   }

artur