July 17, 2007
Reply to Jarrett,

> "BCS" <ao@pathlink.com> wrote in message
> news:ce0a3343bf268c99691d2e8b71a@news.digitalmars.com...
> 
>> How did you hack my system!!!! I'm sure you copied that right off my
>> hard drive }:-|
>> 
>> <g>
>> All joking aside, I keep running into that so often that I want a
>> cleaner
>> way to do it. I want the proper usage documented in the code, not the
>> comments and the asserts. I want to be able to talk about things by
>> name
>> without having to make aliases. It's a minor point but...
> The issue is that there's currently no way to specify that a template
> parameter can be 'anything'.  T means it's a type, alias T means it's
> a symbol, and <sometype> T means it's a value.  If you could specify
> that a parameter could take anything, this would be trivial.  How
> about using .. - it means it's kind of like a tuple, but shorter ;)
> 
> template Foo(A.., B...)
> {
> }
> 
> Or, take a page from Erlang:
> 
> template Foo(A | B...)
> {
> }
> 
> In this case, A can be anything, and not just a type, because it's on
> the left of a bar.  An issue with this, however, is that you can't
> have a type parameter.
> 

I like the ".." my thought was allow tuples anywhere, but if they aren't at the end, they take one and only one thing.

template Foo(A..., B...)

However it seems a bit messy with the location sensitive semantics.


July 18, 2007
Jarrett Billingsley wrote:
> "BCS" <ao@pathlink.com> wrote in message news:ce0a3343bf268c99691d2e8b71a@news.digitalmars.com...
>> How did you hack my system!!!! I'm sure you copied that right off my hard drive }:-|
>>
>> <g>
>> All joking aside, I keep running into that so often that I want a cleaner way to do it. I want the proper usage documented in the code, not the comments and the asserts. I want to be able to talk about things by name without having to make aliases. It's a minor point but...
>>
> 
> The issue is that there's currently no way to specify that a template parameter can be 'anything'.  T means it's a type, alias T means it's a symbol, and <sometype> T means it's a value.  If you could specify that a parameter could take anything, this would be trivial.  How about using .. - it means it's kind of like a tuple, but shorter ;)
> 
> template Foo(A.., B...)
> {
> 
> }
> 
> Or, take a page from Erlang:
> 
> template Foo(A | B...)
> {
> 
> }
> 
> In this case, A can be anything, and not just a type, because it's on the left of a bar.  An issue with this, however, is that you can't have a type parameter. 

Walter resoundingly rejected some other proposal that involved '..' on the grounds that '..' looks far too much like '...' to bleary eyes.  So I think .. is out.

--bb
July 18, 2007
Don Clugston wrote:
> BCS wrote:
>> |template Types(A...)
>> |{
>> |  template Values(A a)
>> |  {
>> |  }
>> |}
>> |
>> |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob;
> 
> int [] is not an allowed as a template value parameter. Only char[],
> wchar[], dchar[], integers, and floating-point types can be template
> value parameters.
> (In C++, only integers are allowed).

Not true of C++.  Pointers to objects with external linkage are also allowed (even if we assume "integers" includes booleans and values of enumeration types).

(Allowing floating point types used to be a common extension in C++ but was removed after experience with it.)

-- James
July 18, 2007
Bill Baxter wrote:
> Jarrett Billingsley wrote:
> 
>> "BCS" <ao@pathlink.com> wrote in message news:ce0a3343bf268c99691d2e8b71a@news.digitalmars.com...
>>
>>> How did you hack my system!!!! I'm sure you copied that right off my hard drive }:-|
>>>
>>> <g>
>>> All joking aside, I keep running into that so often that I want a cleaner way to do it. I want the proper usage documented in the code, not the comments and the asserts. I want to be able to talk about things by name without having to make aliases. It's a minor point but...
>>>
>>
>> The issue is that there's currently no way to specify that a template parameter can be 'anything'.  T means it's a type, alias T means it's a symbol, and <sometype> T means it's a value.  If you could specify that a parameter could take anything, this would be trivial.  How about using .. - it means it's kind of like a tuple, but shorter ;)
>>
>> template Foo(A.., B...)
>> {
>>
>> }
>>
>> Or, take a page from Erlang:
>>
>> template Foo(A | B...)
>> {
>>
>> }
>>
>> In this case, A can be anything, and not just a type, because it's on the left of a bar.  An issue with this, however, is that you can't have a type parameter. 
> 
> 
> Walter resoundingly rejected some other proposal that involved '..' on the grounds that '..' looks far too much like '...' to bleary eyes.  So I think .. is out.
> 
> --bb

How about

A[1]...  or A...[1]

This would be a tuple that must have exactly 1 item. Plainly this would also allow A[4]... , a tuple with 4 items and might also extend to A[3..5]... a tuple with 3,4 or 5 items. (or would that be 3 or 4 to match the slice semantics?) This last bit wouldn't mix with normal tuples though.
July 19, 2007
BCS wrote:
> Reply to Don,
> 
>> int [] is not an allowed as a template value parameter. Only char[],
>> wchar[], dchar[], integers, and floating-point types can be template
>> value parameters. (In C++, only integers are allowed).
>>
> 
> 
> strange, this works
> 
> |template Types(A...)
> |{
> |  template Values(B...)
> |  {
> |  }
> |}
> |
> |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob;
> 
> And while I'm thinking about it; why isn't there something like a "one space tuple"?
> 
> A few times, I have wanted a template that works just like a tuple taking template but where one or more of the spots must be filled and a keep separate from the rest.
> 
> template Foo(A, B...) {}
> 
> these should work
> 
> Foo!(1, int);
> Foo!(int, 1);
> Foo!(Foo!(int, 1));
> 
> this shouldn't
> 
> Foo!();
> 
> 
> (alias dosen't work)

Rather than proposing a bunch of new syntax, isn't the solution just to make those things work as expected?  If you want at least one thing it seems perfectly reasonable to me to do:

template Foo(A, B...) {
   alias Tuple!(A,B) ArgTuple;
   ...
}

if that doesn't work, then that's what needs to be fixed.

I don't really understand the point of wanting to be able to specify a template argument that could be *anything* -- alias, value, or symbol. Other than a big static if, I can't see how you would be able to implement any functionality when it could be any one of those things.

But I'm probably just being dense.

--bb
July 19, 2007
"Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:f7m9k9$es4$1@digitalmars.com...
> Rather than proposing a bunch of new syntax, isn't the solution just to make those things work as expected?  If you want at least one thing it seems perfectly reasonable to me to do:
>
> template Foo(A, B...) {
>    alias Tuple!(A,B) ArgTuple;
>    ...
> }

Well the issue is that an identifier as a template parameter already has a well-defined meaning - it's a type parameter.  Changing it to allow anything seems awfully scary, hence the suggestions for new syntax.


July 19, 2007
Jarrett Billingsley wrote:
> "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:f7m9k9$es4$1@digitalmars.com...
>> Rather than proposing a bunch of new syntax, isn't the solution just to make those things work as expected?  If you want at least one thing it seems perfectly reasonable to me to do:
>>
>> template Foo(A, B...) {
>>    alias Tuple!(A,B) ArgTuple;
>>    ...
>> }
> 
> Well the issue is that an identifier as a template parameter already has a well-defined meaning - it's a type parameter.  Changing it to allow anything seems awfully scary, hence the suggestions for new syntax. 


Yeh I meant for the A to be a type there.
I guess I just don't understand the use case for BCS's original example:

  template Foo(A, B...) {}

  these should work

  Foo!(1, int);
  Foo!(int, 1);
  Foo!(Foo!(int, 1));


If you don't even know what kind of entity a thing is, there's not much you can do with it.

Anyway, since it's been a basically a dialogue between you and BCS so far, something tells me you haven't hit a nerve with many folks.  My guess is that most folks aren't clear what the motivating use case is. And probably Walter isn't going to be much interested in this either without good use case examples.

--bb
July 19, 2007
James Dennett wrote:
> Don Clugston wrote:
>> BCS wrote:
>>> |template Types(A...)
>>> |{
>>> |  template Values(A a)
>>> |  {
>>> |  }
>>> |}
>>> |
>>> |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob;
>> int [] is not an allowed as a template value parameter. Only char[],
>> wchar[], dchar[], integers, and floating-point types can be template
>> value parameters.
>> (In C++, only integers are allowed).
> 
> Not true of C++.  Pointers to objects with external linkage
> are also allowed 

I would classify those as alias parameters, not value parameters. It's the name, not the value, which gets name mangled.

(even if we assume "integers" includes
> booleans and values of enumeration types).
Yes. IIRC, there's no distinction between them.

> 
> (Allowing floating point types used to be a common extension
> in C++ but was removed after experience with it.)

Yes, I think I saw it in an early version of Borland C++. But I don't see how you can do it properly without clearly specifying the FP ABI.


> 
> -- James
July 19, 2007
Bill Baxter wrote:
> Jarrett Billingsley wrote:
>> "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:f7m9k9$es4$1@digitalmars.com...
>>> Rather than proposing a bunch of new syntax, isn't the solution just to make those things work as expected?  If you want at least one thing it seems perfectly reasonable to me to do:
>>>
>>> template Foo(A, B...) {
>>>    alias Tuple!(A,B) ArgTuple;
>>>    ...
>>> }
>>
>> Well the issue is that an identifier as a template parameter already has a well-defined meaning - it's a type parameter.  Changing it to allow anything seems awfully scary, hence the suggestions for new syntax. 
> 
> 
> Yeh I meant for the A to be a type there.
> I guess I just don't understand the use case for BCS's original example:
> 
>   template Foo(A, B...) {}
> 
>   these should work
> 
>   Foo!(1, int);
>   Foo!(int, 1);
>   Foo!(Foo!(int, 1));
> 
> 
> If you don't even know what kind of entity a thing is, there's not much you can do with it.
> 
> Anyway, since it's been a basically a dialogue between you and BCS so far, something tells me you haven't hit a nerve with many folks.  My guess is that most folks aren't clear what the motivating use case is. And probably Walter isn't going to be much interested in this either without good use case examples.
> 

Actually, I only saw this thread a few days ago (because I don't read d.learn as much as the main group), and I am surprised that so few people responded. To me, this is one part of a whole lot of issues with template parameters, which I hope will sometime be solved by a big reform. Otherwise, it will remain what seems today to be a collection of kludges. As far as I'm concerned, the problems are:

1. tuple parameters allow int[] (and double[] and double[][], etc) as value parameters; template value parameters don't
2. there's no equivalent to typesafe varargs: you can't say, "give me a type tuple" or "give me a tuple of aliases" or "give me a value tuple" -- you can only say "give me a tuple" and then do static asserts. I find this quite annoying because most of the time I know exactly which I want.
3. There's no easy way to specify "give me just one value parameter of any type." The closest you can get is
    template foo(T, T S) {...}
  but the instantiation requires:
    foo!(int, 5);
4. There's no way to specify what BCS mentioned: "give me just one parameter, of any kind". I haven't needed this yet, though.
5. You can't do proper nested tuples without a going through "compile-time structs".

(when thinking about template parameters in the past, I've always found it difficult to distinguish between "type" as in int/char/etc, and the "type" of a template parameter as in value/alias/type. I think "kind" is a good word for the latter)


I don't know what other people think of these problems, but they don't seem too hard to solve (mind you, I haven't worked out the details, so I could well be wrong). I would imagine setting up some sort of inheritance of template parameter kind, so that there's a base kind, "any", from which "value", "alias" and "type" inherit, and from the "value" kind, all of the regular D types also inherit.
[Additionally, you solve problem 1 above by, well, solving it.]
July 19, 2007
Reply to Bill,


> 
> I don't really understand the point of wanting to be able to specify a
> template argument that could be *anything* -- alias, value, or symbol.
> Other than a big static if, I can't see how you would be able to
> implement any functionality when it could be any one of those things.
> 
> But I'm probably just being dense.
> 
> --bb
> 

One thing that it would be useful for would be a tuple template that does something with any tuple type

// take exactly 2 and return true if they are the same
template IsSame(A..,B..){const bool IsSame = ...}

// take 1 or more and remove all of the first from the rest
template Remove(remove.., from...)
{
 static if(from.length == 0)
 {
    alias from Remove;
 }
 else
 {
   staic if(IsSame!(remove, from[0]))
   {
      alias Remove!(remove,from[1..$]) Remove
   }
   else
   {
      alias T!(from[0], Remove!(remove,from[1..$])) Remove
   }
 }
}

this would work as:

Remove!(1,4,5,6,7,1,2,3); // gives (4,5,6,7,2,3)
Remove!(int, byte, short, int, long); // gives (byte, short, long)