November 26, 2012
> However, going with that, the supplementary question is, how do I then
> discover if bar[0] is a symbol or not? I can't see any traits to test for
> builtin types...

You could use the fact that alias parameters can not be builtin types, like this:

template TestSymbol(alias a){}

 __traits(compiles, TestSymbol!(bar[0]))
November 26, 2012
> Ummm, immediate problem. That interferes with my argument list, inhibits
> consecutive parameters. You'll notice my template had 'A' on the end... it
> would make for a horrible API if the second arg were to come first in this
> case... is that the only option?

You could just take all parameters as a tuple, and them constrain them usin "if", like that:

template bar(foo...) if(foo.length == 2 && is(foo[1]))
{
}
November 26, 2012
On 26 November 2012 19:28, jerro <a@a.com> wrote:

> However, going with that, the supplementary question is, how do I then
>> discover if bar[0] is a symbol or not? I can't see any traits to test for builtin types...
>>
>
> You could use the fact that alias parameters can not be builtin types, like this:
>
> template TestSymbol(alias a){}
>
>  __traits(compiles, TestSymbol!(bar[0]))
>

>_< .. I feel like crying every time 'compiles' comes up.


November 26, 2012
On Monday, 26 November 2012 at 16:37:08 UTC, Manu wrote:
> template isThing( alias symbol, A )
> {
>   enum isThing = false;
> }
>
> This template works in most contexts:
>
> int x;
> struct S {}
>
> pragma(msg, isThing!x);
> pragma(msg, isThing!S);
>
> But this fails:
> pragma(msg, isThing!int);
>
> Why does it fail on a basic type (int), but not a user defined type (S)?
> How can I fix the template declaration to not error in that case?
> I tried:
>
> template isThing( alias symbol, A )
> {
>   enum isThing = false;
> }
> template isThing( T, A )
> {
>   enum isThing = false;
> }
>
> Hoping the T version would catch the int, but this leads to different
> errors "matches more than one template declaration".

That is annoying. There *must* be a kind of single unconstrained template parameter accepting anything that can be an element of a "compile time" tuple. In other words, this must work for any arguments without hassle:

template Foo(alias Head, Tail...)
{
    alias TypeTuple!(Head, Tail) Foo;
}

As others said, you can workaround the deficiency with an if-constraint, which is unsightly. FWIW, I have all my codebase littered with "if (A.length == 1)" rubbish.

November 26, 2012
On Monday, 26 November 2012 at 18:20:39 UTC, Max Samukha wrote:
> That is annoying. There *must* be a kind of single unconstrained template parameter accepting anything that can be an element of a "compile time" tuple. In other words, this must work for any arguments without hassle:
>
> template Foo(alias Head, Tail...)
> {
>     alias TypeTuple!(Head, Tail) Foo;
> }
>
> As others said, you can workaround the deficiency with an if-constraint, which is unsightly. FWIW, I have all my codebase littered with "if (A.length == 1)" rubbish.

I agree, and if I remember previous discussions on the subject correctly, it seems like only Walter is in favor of upholding the current restrictions of "alias" parameters to symbols. I simply do not see a point in pushing compiler implementation details on the user like that – for the programmer, a type is a type is a type…

Walter, do you have an example of a situation where the alias parameter restriction would be beneficial?  (for the D code involved, I don't mean the few lines of code avoided in the compiler)

David
November 26, 2012
On Monday, 26 November 2012 at 17:18:28 UTC, Manu wrote:
> the supplementary question is, how do I then
> discover if bar[0] is a symbol or not? I can't see any traits to test for
> builtin types...

Depends on your definition of symbol, but if you mean symbol as in "an alias parameter accepts it", the obvious solution is:

---
template isSymbol(alias S) {
  enum isSymbol = true;
}

template isSymbol(S) {
  enum isSymbol = false;
}
---

David
November 26, 2012
On Monday, 26 November 2012 at 18:52:25 UTC, David Nadlinger wrote:
>
> I agree, and if I remember previous discussions on the subject correctly, it seems like only Walter is in favor of upholding the current restrictions of "alias" parameters to symbols.
>
> David

The problem lies within how the compiler is engineered. Basic built-in types should be a part of symbol table and inserted into it at the compiler startup. That means that any mentioning of built-in types in the parser should be removed and any differences between user defined symbols and basic types should be as small as possible. That will remove many special cases from the compiler as well as automatically resolve the alias problem. As far as I understand this is how basic types are implemented in the Haskell compiler.

Cheers

Eldar
November 26, 2012
On Monday, 26 November 2012 at 19:17:30 UTC, Eldar Insafutdinov wrote:
> On Monday, 26 November 2012 at 18:52:25 UTC, David Nadlinger wrote:
>>
>> I agree, and if I remember previous discussions on the subject correctly, it seems like only Walter is in favor of upholding the current restrictions of "alias" parameters to symbols.
>>
>> David
>
> The problem lies within how the compiler is engineered. […]

I'm aware of this – that's why I wrote »I don't mean the few lines of code avoided in the
compiler« in the piece of my post you silently dropped from your quote. ;)

David
November 26, 2012
On Monday, 26 November 2012 at 19:17:30 UTC, Eldar Insafutdinov wrote:
>
> The problem lies within how the compiler is engineered. Basic built-in types should be a part of symbol table and inserted into it at the compiler startup. That means that any mentioning of built-in types in the parser should be removed and any differences between user defined symbols and basic types should be as small as possible. That will remove many special cases from the compiler as well as automatically resolve the alias problem. As far as I understand this is how basic types are implemented in the Haskell compiler.
>
> Cheers
>
> Eldar

Although I realize now that this will not make alias accept derived types like arrays, pointers etc. But regardless, distinction between built-in and user defined types should be very little, even in the compiler internals. In the end this is the whole point of OOP which allows for the user to make the types which are just as good as internal ones.
November 26, 2012
On 11/26/2012 07:52 PM, David Nadlinger wrote:
> On Monday, 26 November 2012 at 18:20:39 UTC, Max Samukha wrote:
>> That is annoying. There *must* be a kind of single unconstrained
>> template parameter accepting anything that can be an element of a
>> "compile time" tuple. In other words, this must work for any arguments
>> without hassle:
>>
>> template Foo(alias Head, Tail...)
>> {
>>     alias TypeTuple!(Head, Tail) Foo;
>> }
>>
>> As others said, you can workaround the deficiency with an
>> if-constraint, which is unsightly. FWIW, I have all my codebase
>> littered with "if (A.length == 1)" rubbish.
>
> I agree, and if I remember previous discussions on the subject
> correctly, it seems like only Walter is in favor of upholding the
> current restrictions of "alias" parameters to symbols. I simply do not
> see a point in pushing compiler implementation details on the user like
> that – for the programmer, a type is a type is a type…
>
> Walter, do you have an example of a situation where the alias parameter
> restriction would be beneficial?  (for the D code involved, I don't mean
> the few lines of code avoided in the compiler)
>
> David

There are none. In case that behaviour is wanted, a template constraint does the job.

http://forum.dlang.org/thread/k7uc5p$2giu$1@digitalmars.com?page=3#post-k815mi:2410hh:242:40digitalmars.com

http://d.puremagic.com/issues/show_bug.cgi?id=9029