Thread overview
Re: allSatisfy could use some constraints
Sep 22, 2011
Jonathan M Davis
Sep 22, 2011
Jonathan M Davis
Sep 23, 2011
Andrej Mitrovic
Sep 23, 2011
Jonathan M Davis
September 22, 2011
On Thursday, September 22, 2011 15:36 Andrej Mitrovic wrote:
> import std.string;
> import std.traits;
> import std.typetuple;
> 
> void main()
> {
> if (allSatisfy!(isNumeric, int, short))
> {
> }
> }
> 
> D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\typetuple.d(576): Error: template instance F is not a template declaration, it is a overloadset
> 
> This took a good while to figure out what went wrong. std.traits defines isNumeric, but std.string defines it too. allSatisfy takes an alias type parameter with no constraints, so maybe some constraints could be added so it doesn't get instantiated with regular functions but only template functions?

Well, the simple solution is to just pass it std.traits.isNumeric. As annoying as it may be at times, conflicting functions is something that can happen in D and has been planned for, so there are simple ways around the problem. However, if you're absolutely certain that it doesn't make sense for allSatisfy to work with a function as opposed to an eponymous template (and I'm not at all certain that that's true), then you can open an enhancement request.

- Jonathan M Davis
September 22, 2011
On Thursday, September 22, 2011 16:45 Jonathan M Davis wrote:
> On Thursday, September 22, 2011 15:36 Andrej Mitrovic wrote:
> > import std.string;
> > import std.traits;
> > import std.typetuple;
> > 
> > void main()
> > {
> > if (allSatisfy!(isNumeric, int, short))
> > {
> > }
> > }
> > 
> > D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\typetuple.d(576): Error: template instance F is not a template declaration, it is a overloadset
> > 
> > This took a good while to figure out what went wrong. std.traits defines isNumeric, but std.string defines it too. allSatisfy takes an alias type parameter with no constraints, so maybe some constraints could be added so it doesn't get instantiated with regular functions but only template functions?
> 
> Well, the simple solution is to just pass it std.traits.isNumeric. As annoying as it may be at times, conflicting functions is something that can happen in D and has been planned for, so there are simple ways around the problem. However, if you're absolutely certain that it doesn't make sense for allSatisfy to work with a function as opposed to an eponymous template (and I'm not at all certain that that's true), then you can open an enhancement request.

Though given that allSatisfy!(isNumeric, int, short) will work with std.traits.isNumeric and not std.string.isNumeric, I suspect that a template constraint could be added which would fix the problem simply by checking whether the compilation succeeds or not with the given arguments. And that would be a better solution regardless of whether any normal functions should work with allSatisfy or not.

- Jonathan M Davis
September 23, 2011
On 9/23/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> Though given that allSatisfy!(isNumeric, int, short) will work with std.traits.isNumeric and not std.string.isNumeric, I suspect that a template constraint could be added which would fix the problem simply by checking whether the compilation succeeds or not with the given arguments.

I'm not sure if allSatisfy was meant to be used with regular functions, it's used with templates and types (hence it's in typetuple). I think an alternative "all" template for runtime arguments was already proposed.

My problem is not the name clashes but the fact that the error message is in the body of the  allSatisfy template, and this is exactly where constraints come in handy. It took me a while before I figured out that std.string had the same function name, but I'm using an alias now to remedy this.
September 23, 2011
On Thursday, September 22, 2011 17:03 Andrej Mitrovic wrote:
> On 9/23/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > Though given that allSatisfy!(isNumeric, int, short) will work with std.traits.isNumeric and not std.string.isNumeric, I suspect that a template constraint could be added which would fix the problem simply by checking whether the compilation succeeds or not with the given arguments.
> 
> I'm not sure if allSatisfy was meant to be used with regular functions, it's used with templates and types (hence it's in typetuple). I think an alternative "all" template for runtime arguments was already proposed.

Yeah, but functions can be used in template constraints and the like too, so it may be valid. I don't know. I'd have to look at it in more detail.

> My problem is not the name clashes but the fact that the error message is in the body of the allSatisfy template, and this is exactly where constraints come in handy. It took me a while before I figured out that std.string had the same function name, but I'm using an alias now to remedy this.

Yeah. In general, templates really should have template constraints on them (_especially_ public ones), and there are several in Phobos which forward to other templates that don't have template constraints on them when they should. And it appears that allSatisfy is one of them.

- Jonathan M Davis