Re: Request for a more powerful template specialization feature

2017-07-17 Thread jmh530 via Digitalmars-d

On Monday, 17 July 2017 at 12:29:41 UTC, jmh530 wrote:


Forgive me, but what about anySatisfy
https://dlang.org/library/std/meta/any_satisfy.html


Oh sorry, I see that's a little different.


Re: Request for a more powerful template specialization feature

2017-07-17 Thread jmh530 via Digitalmars-d
On Friday, 14 July 2017 at 19:49:05 UTC, Andrei Alexandrescu 
wrote:


An effective way of improving the state of affairs would be to 
create a PR that makes the constraint easier to read and write, 
e.g.:


among!(R, double, int) && among!(W, string, char, dchar)

In fact it's surprising it hasn't been proposed yet.

Andrei


Forgive me, but what about anySatisfy
https://dlang.org/library/std/meta/any_satisfy.html


Re: Request for a more powerful template specialization feature

2017-07-15 Thread data pulverizer via Digitalmars-d

On Saturday, 15 July 2017 at 10:34:13 UTC, Enamex wrote:


But specializations are quite different from constraints, no? 
Constraints wouldn't help when the template name is overloaded 
and passes the constraint checks of several different template 
implementations; specializations narrow things down for 
overload resolution.


Unless I'm misunderstanding the OP or everyone else in the 
thread somehow :/


That's exactly right, you've probably put it better than I have! 
Specializations are quite different from constraints and I have 
found as you said that specializations are a great way to narrow 
things down for overload resolution. I use them to dispatch 
methods and they are the easiest way to specify a known set of 
kinds on a method set. When you narrow to your specialization set 
like that it will always work in the same way - no rouge types 
will mess things up.


Re: Request for a more powerful template specialization feature

2017-07-15 Thread Enamex via Digitalmars-d
On Friday, 14 July 2017 at 19:49:05 UTC, Andrei Alexandrescu 
wrote:

On 7/14/17 2:19 PM, data pulverizer wrote:
template Construct(R: Union{double, int}, W: Union{string, 
char, dchar})


template Construct(R, W)
if ((is(R == double) || is(R == int))
&& (is(W == string) || is(W == char) || is(W == dchar))

It would be good to get comments and suggestions before I 
write a DIP.


An effective way of improving the state of affairs would be to 
create a PR that makes the constraint easier to read and write, 
e.g.:


among!(R, double, int) && among!(W, string, char, dchar)

In fact it's surprising it hasn't been proposed yet.

Andrei


But specializations are quite different from constraints, no? 
Constraints wouldn't help when the template name is overloaded 
and passes the constraint checks of several different template 
implementations; specializations narrow things down for overload 
resolution.


Unless I'm misunderstanding the OP or everyone else in the thread 
somehow :/


Re: Request for a more powerful template specialization feature

2017-07-14 Thread data pulverizer via Digitalmars-d

On Friday, 14 July 2017 at 23:04:48 UTC, Stefan Koch wrote:
One important characteristic about constraints, is that they 
are not bound to types.

Also they can from conjunctions and disjunctions.
Combined with ctfe they are very flexible and powerful.

I do not know how you would do the same with specializations.
Then again being unfamiliar with template-specializations I 
might be overlooking something.


True ... it doesn't have to be specializations or constraints, as 
you have said constraints are important for conjunctions and 
disjunctions. I should not have said "why are constraints better 
than specializations". However when you are dealing with a know 
finite set of know types or constructs - which I do frequently, 
it is useful to be able to be able to specify the exact behaviour 
for individuals and different groups clearly and succinctly. For 
instance when writing mathematical algorithms that should apply 
differently to different constructs, its much easier to say "do 
this for that specific construct" and "do something else for some 
group" and so on without having to repeat negating cases.


A practical case might be dealing with two library "kinds" each 
having around 8 possible type specifications where some 
associated methods are related. Sometimes methods will be the 
same for combinations of types both within each kind and across 
both kind combinations. Specializations that allow multiple 
values are really good for these cases.


I currently  use string mixins to code-gen my template 
specializations - its a good-enough but visually inelegant 
solution.




Re: Request for a more powerful template specialization feature

2017-07-14 Thread Stefan Koch via Digitalmars-d

On Friday, 14 July 2017 at 22:49:18 UTC, data pulverizer wrote:

On Friday, 14 July 2017 at 22:25:15 UTC, data pulverizer wrote:
I am aware that this suggestion touches the language and the 
compiler - and may significant implications. I would like to 
know whether this could be done without too much effort and 
whether it would break anything else?


If you are writing lots of overloaded templates, constraints 
can have unintended behaviour because you end up telling the 
compiler what not to do rather than what to do. The above 
Unions are clear and simple, easy to use and should result in 
cleaner more robust code.


In addition with template specializations you get constraints 
for free. If I implement template overloads which are all 
specializations, the compiler gives me a very informative error 
if I step outside the pre-defined set of implementations. 
That's just brilliant - exactly what you want! I immediately 
know when I see that error what the issue is. Am I being naive? 
Why are constraints better?


One important characteristic about constraints, is that they are 
not bound to types.

Also they can from conjunctions and disjunctions.
Combined with ctfe they are very flexible and powerful.

I do not know how you would do the same with specializations.
Then again being unfamiliar with template-specializations I might 
be overlooking something.


Re: Request for a more powerful template specialization feature

2017-07-14 Thread data pulverizer via Digitalmars-d

On Friday, 14 July 2017 at 22:25:15 UTC, data pulverizer wrote:
I am aware that this suggestion touches the language and the 
compiler - and may significant implications. I would like to 
know whether this could be done without too much effort and 
whether it would break anything else?


If you are writing lots of overloaded templates, constraints 
can have unintended behaviour because you end up telling the 
compiler what not to do rather than what to do. The above 
Unions are clear and simple, easy to use and should result in 
cleaner more robust code.


In addition with template specializations you get constraints for 
free. If I implement template overloads which are all 
specializations, the compiler gives me a very informative error 
if I step outside the pre-defined set of implementations. That's 
just brilliant - exactly what you want! I immediately know when I 
see that error what the issue is. Am I being naive? Why are 
constraints better?


Re: Request for a more powerful template specialization feature

2017-07-14 Thread data pulverizer via Digitalmars-d

On Friday, 14 July 2017 at 18:19:03 UTC, data pulverizer wrote:

Dear all,

Template specializations are a great feature in D. They allow 
the programmer to create template specializations but they can 
also be a powerful way of constraining templates by 
implementing only the specializations that you need. In 
contrast template constraints can quickly become very complex 
for the programmer to write and reason about.


Template specializations should be extended to allow multiple 
lists of types to be implemented together. For example this ...


template Construct(R: Union{double, int}, W: Union{string, 
char, dchar})

{
auto Construct(R, W)(R r, W w)
{

}
}

The same definition would be allowed for all 6 combinations of 
{double, int} and {string, char, dchar} (and no more! Unless 
specified otherwise and/or more generally). This would remove 
the need to manually write these for all combinations or resort 
to constraints.


In addition for some use cases it is a nicer way of doing 
unions than using the current union keyword. Union{double, int} 
could be a compile-time construct indicating that the type can 
be either an actual double or int. It can replace the use of 
union in cases where you want a substitution of either double 
or int for this Union rather than a union type. In addition, 
variants return variants rather than "properly" typed data.


It would be good to get comments and suggestions before I write 
a DIP.


Thank you in advance.


I am aware that this suggestion touches the language and the 
compiler - and may significant implications. I would like to know 
whether this could be done without too much effort and whether it 
would break anything else?


If you are writing lots of overloaded templates, constraints can 
have unintended behaviour because you end up telling the compiler 
what not to do rather than what to do. The above Unions are clear 
and simple, easy to use and should result in cleaner more robust 
code.




Re: Request for a more powerful template specialization feature

2017-07-14 Thread Jonathan M Davis via Digitalmars-d
On Friday, July 14, 2017 4:45:10 PM MDT Andrei Alexandrescu via Digitalmars-
d wrote:
> On 07/14/2017 04:29 PM, Jonathan M Davis via Digitalmars-d wrote:
> > I'd guess that you'd use staticIndexOf an check for
> > -1 to implement it
>
> Given that constraints are user-facing, having a forwarding one-liner
> may be justifiable. -- Andrei

Possibly. It's hard to know sometimes when a one line wrapper is a big
enough boost to usability to standardize. I could see this being such a
case.

staticIndexOf is a bit unwieldy, and I've rarely used it, but when I have,
I think that I've always used it to check whether somehing is present rather
than getting an actual index.

Another tough example would be takeWhile/dropWhile. We already of until and
find, which do the same things respectively but with the opposite predicate
such that they're arguably too simple to be worth adding, but at the same
time, if you have to negate your predicates often enough, having takeWhile
and dropWhile would be a definite boon (also, for many folks, takeWhile and
dropWhile are obvious in a way that until or find might not be - especially
until). Timon was complaining bitterly the other day about the lack of
takeWhile:

https://issues.dlang.org/show_bug.cgi?id=4535

IIRC, I tried to add those several years ago, but you vetoed them on the
grounds that simply negating the predicate was trvial, which is certainly
true, albeit less user-friendly. I don't know what the correct answer is
though. Sometimes, it's clear that adding a one-liner is a pointless
wrapper, whereas in other cases, it seems like a definite usabiliy
improvement.

- Jonathan M Davis



Re: Request for a more powerful template specialization feature

2017-07-14 Thread Andrei Alexandrescu via Digitalmars-d

On 07/14/2017 04:29 PM, Jonathan M Davis via Digitalmars-d wrote:

I'd guess that you'd use staticIndexOf an check for
-1 to implement it


Given that constraints are user-facing, having a forwarding one-liner 
may be justifiable. -- Andrei


Re: Request for a more powerful template specialization feature

2017-07-14 Thread Jonathan M Davis via Digitalmars-d
On Friday, July 14, 2017 3:49:05 PM MDT Andrei Alexandrescu via Digitalmars-
d wrote:
> On 7/14/17 2:19 PM, data pulverizer wrote:
> > template Construct(R: Union{double, int}, W: Union{string, char, dchar})
>
> template Construct(R, W)
> if ((is(R == double) || is(R == int))
>  && (is(W == string) || is(W == char) || is(W == dchar))

Yeah, I tend to forget that template specialization even exists in D, and I
_really_ hate the fact that : in template specializations doesn't mean what
it means in is expressions (equality instead of implicit conversion). So, I
wish that we didn't even have template specializations, but presumably, it's
not worth the breakage to remove them. The one thing that they do have going
for them over template constraints though is that if you overload with
template constraints, you tend to have to duplicate the constraint with the
reverse condition, which you don't have to do with template specializations.
But smart use of static ifs inside of templated functions can mitigate that
problem, and ultimately, I think that template specialization is a redundant
feature.

> > It would be good to get comments and suggestions before I write a DIP.
>
> An effective way of improving the state of affairs would be to create a
> PR that makes the constraint easier to read and write, e.g.:
>
> among!(R, double, int) && among!(W, string, char, dchar)
>
> In fact it's surprising it hasn't been proposed yet.

On seeing this thread, that's the first thing I thought of as well, and I
assumed that it already existed but didn't take the time to track it down.
Off the top of my head, I'd guess that you'd use staticIndexOf an check for
-1 to implement it, which should be pretty straight forward, albeit slightly
more verbose. Thinking on it now, I think that that's what I've done in the
past.

- Jonathan M Davis



Re: Request for a more powerful template specialization feature

2017-07-14 Thread Andrei Alexandrescu via Digitalmars-d

On 7/14/17 2:19 PM, data pulverizer wrote:

template Construct(R: Union{double, int}, W: Union{string, char, dchar})


template Construct(R, W)
if ((is(R == double) || is(R == int))
&& (is(W == string) || is(W == char) || is(W == dchar))


It would be good to get comments and suggestions before I write a DIP.


An effective way of improving the state of affairs would be to create a 
PR that makes the constraint easier to read and write, e.g.:


among!(R, double, int) && among!(W, string, char, dchar)

In fact it's surprising it hasn't been proposed yet.

Andrei


Request for a more powerful template specialization feature

2017-07-14 Thread data pulverizer via Digitalmars-d

Dear all,

Template specializations are a great feature in D. They allow the 
programmer to create template specializations but they can also 
be a powerful way of constraining templates by implementing only 
the specializations that you need. In contrast template 
constraints can quickly become very complex for the programmer to 
write and reason about.


Template specializations should be extended to allow multiple 
lists of types to be implemented together. For example this ...


template Construct(R: Union{double, int}, W: Union{string, char, 
dchar})

{
auto Construct(R, W)(R r, W w)
{

}
}

The same definition would be allowed for all 6 combinations of 
{double, int} and {string, char, dchar} (and no more! Unless 
specified otherwise and/or more generally). This would remove the 
need to manually write these for all combinations or resort to 
constraints.


In addition for some use cases it is a nicer way of doing unions 
than using the current union keyword. Union{double, int} could be 
a compile-time construct indicating that the type can be either 
an actual double or int. It can replace the use of union in cases 
where you want a substitution of either double or int for this 
Union rather than a union type. In addition, variants return 
variants rather than "properly" typed data.


It would be good to get comments and suggestions before I write a 
DIP.


Thank you in advance.