July 16, 2009
> "Walter Bright" <newshound1@digitalmars.com> wrote in message
>> Yes. Constraints determine the list of candidate template declarations, but do not participate in the partial ordering of candidates to determine the 'best' match.

Nick Sabalausky wrote:
> Pardon my ignorance, but...umm...what?

Example:

class C {}

void foo(T)() if(is(T : Object)) {}
void foo(T)() if(is(T : C)) {}

void bar(T : Object)() {}
void bar(T : C)() {}

void main() {
  foo!(C)(); // error: ambiguous, (both are candidate, no ordering)
  bar!(C)(); // ok, (both are candidate, second bar more specialized)
}

July 16, 2009
Christian Kamm wrote:
>> Christian Kamm wrote:
>>> Is there a difference between
>>> template Foo(T : U) {} and
>>> template Foo(T) if(is(T : U)) {} ?
>>>
> 
> Walter Bright wrote:
>> Yes. Constraints determine the list of candidate template declarations,
>> but do not participate in the partial ordering of candidates to
>> determine the 'best' match.
> 
> Thanks for the explanation!
> 
> I expect the reason is that for constrained templates it is impossible to determine whether all valid template arguments for one would lead to a valid instantiation of another?
> 
> 

That's a good technical reason, but I also felt that the current way just made intuitive sense.
July 16, 2009
"Christian Kamm" <kamm-incasoftware@removethis.de> wrote in message news:h3mh71$185a$2@digitalmars.com...
>> "Walter Bright" <newshound1@digitalmars.com> wrote in message
>>> Yes. Constraints determine the list of candidate template declarations,
>>> but do not participate in the partial ordering of candidates to
>>> determine
>>> the 'best' match.
>
> Nick Sabalausky wrote:
>> Pardon my ignorance, but...umm...what?
>
> Example:
>
> class C {}
>
> void foo(T)() if(is(T : Object)) {}
> void foo(T)() if(is(T : C)) {}
>
> void bar(T : Object)() {}
> void bar(T : C)() {}
>
> void main() {
>  foo!(C)(); // error: ambiguous, (both are candidate, no ordering)
>  bar!(C)(); // ok, (both are candidate, second bar more specialized)
> }
>

Well then it seems like the constraints version is both less useful and more verbose. Hmm, but I guess it does allow "match/not-match" to be determined by arbitrary compile-time expressions. Is there another benefit to the constraints that I'm missing?


July 16, 2009
Walter Bright wrote:
> Christian Kamm wrote:
>>> Christian Kamm wrote:
>>>> Is there a difference between
>>>> template Foo(T : U) {} and
>>>> template Foo(T) if(is(T : U)) {} ?
>>>>
>>
>> Walter Bright wrote:
>>> Yes. Constraints determine the list of candidate template declarations,
>>> but do not participate in the partial ordering of candidates to
>>> determine the 'best' match.
>>
>> Thanks for the explanation!
>>
>> I expect the reason is that for constrained templates it is impossible to determine whether all valid template arguments for one would lead to a valid instantiation of another?
>>
>>
> 
> That's a good technical reason, but I also felt that the current way just made intuitive sense.

The current Template specialization implementation is doing a best fit search anyway, so why constraints are not able to use the same mechanism. ?

So, instead of IFTI we should have EFTI*, driven by constraints.
*The name is rather confusing so "fuzzy templates" are probably better.

bearophile brings in several times Scala/OCAML like pattern matching. Why not using that for constraints ?

IMO the current D constraints implementation is nice and easy, but I thing there is much more hidden power in that idea.

Thanks for ignoring my ignorance..
July 16, 2009
Reply to Nick,

> Hmm, but I guess it does allow "match/not-match" to
> be determined by arbitrary compile-time expressions. Is there another
> benefit to the constraints that I'm missing?
> 

Not that I know of (but that says very little :). It might be a good rule of thumb to never directly use the simple is(T:U) in a template constraint.


July 16, 2009
BLS wrote:
> The current Template specialization implementation is doing a best fit search anyway, so why constraints are not able to use the same mechanism. ?

The template specialization method is based on types - but there's no way to look inside those types and specialize based on properties of those types. That's where constraints come in.

Constraints use a completely different matching method than the type parameters do. It makes intuitive sense to logically separate them, rather than to mix them up.


> bearophile brings in several times Scala/OCAML like pattern matching. Why not using that for constraints ?

I have no idea how that works, though Bartosz has been looking into it.
July 16, 2009
On Thu, Jul 16, 2009 at 4:03 PM, Walter Bright<newshound1@digitalmars.com> wrote:
> BLS wrote:
>>
>> The current Template specialization implementation is doing a best fit search anyway, so why constraints are not able to use the same mechanism. ?
>
> The template specialization method is based on types - but there's no way to look inside those types and specialize based on properties of those types. That's where constraints come in.
>
> Constraints use a completely different matching method than the type parameters do. It makes intuitive sense to logically separate them, rather than to mix them up.

Please, the last thing we need is to have *two* systems of template specialization, one with best matching and one without.

I was thinking it'd be more intuitive if constraints - which are more general - would be used to implement specialization.  That is,

template X(T: A, U: B)

would basically be syntactic sugar for

template X(T) if(is(T: A) && is(U: B))

Then you have only a single system of specialization and constraining to worry about.  How would "best matching" work?  The compiler could definitely be smart enough to pick apart the logical expression in the constraint, I suppose, or constraints could be written as "if(c1, c2, c3)" or something of the like.

Let's try to *simplify* metaprogramming and make things *orthogonal* instead of tacking on features with no regard to the existing ones.
July 16, 2009
Jarrett Billingsley pisze:
> Please, the last thing we need is to have *two* systems of template
> specialization, one with best matching and one without.
> 
> I was thinking it'd be more intuitive if constraints - which are more
> general - would be used to implement specialization.  That is,
> 
> template X(T: A, U: B)
> 
> would basically be syntactic sugar for
> 
> template X(T) if(is(T: A) && is(U: B))
> 
> Then you have only a single system of specialization and constraining
> to worry about.  How would "best matching" work?  The compiler could
> definitely be smart enough to pick apart the logical expression in the
> constraint, I suppose, or constraints could be written as "if(c1, c2,
> c3)" or something of the like.
> 
> Let's try to *simplify* metaprogramming and make things *orthogonal*
> instead of tacking on features with no regard to the existing ones.

Well, that's exactly what I proposed about one year ago:

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=77654

My proposal would make meta programing in D much more intuitive (because of using rules - not bunch of corner cases as it is today). Unfortunately almost no one from NG commented on that...

BR
Marcin Kuszczak
(aarti_pl)
July 16, 2009
Reply to Jarrett,

> I was thinking it'd be more intuitive if constraints - which are more
> general - would be used to implement specialization.  That is,
> 
> template X(T: A, U: B)
> 
> would basically be syntactic sugar for
> 
> template X(T) if(is(T: A) && is(U: B))
> 
> Then you have only a single system of specialization and constraining
> to worry about.  How would "best matching" work?  The compiler could
> definitely be smart enough to pick apart the logical expression in the
> constraint,

My thought on this is discard non `is(T:U)` terms and expand the expressions into a set of simple AND expressions:

- discard any template options where the expression fails
- replace all sub trees other than AND, OR and `is(T:U)` nodes with their evaluated value.
- expand to disjunctive normal form (http://en.wikipedia.org/wiki/Disjunctive_normal_form)
- discard false disjuncts
- discard negated terms
- treat each disjunct or each template options as it's own specialization option and apply the current partial ordering rules.


July 16, 2009
Jarrett Billingsley wrote:
> Let's try to *simplify* metaprogramming and make things *orthogonal*
> instead of tacking on features with no regard to the existing ones.

Type matching cannot do what expression matching can do. You'd need a totally new syntax anyway to bring expression matching into the template type parameter list.