www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2599] New: Two variadic parameters should be accepted

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2599

           Summary: Two variadic parameters should be accepted
           Product: D
           Version: unspecified
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: andrei metalanguage.com


The following code is not accepted:

void f(T1..., T2...)(T2 args)
{
    ...
}

However, it is unambiguous that T1 are supposed to be passed explicitly,
whereas T2 bind to the arguments. Currently there is a workaround:

template f(T1...)
{
    alias fImpl!(T1).f f;
}

template fImpl(T1...)
{
    void f(T2...)(T2 args) { ... }
}

The workaround complicates code needlessly and introduces extraneous symbols.


-- 
Jan 21 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2599


smjg iname.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com




------- Comment #1 from smjg iname.com  2009-01-24 07:08 -------
How would you use such a thing?

The trouble is that F!(int, char[], Object) in itself is ambiguous - does T1
bind to int and T2 to (char[], Object), or T1 to (int, char[]) and T2 to
Object?  Even one to the empty tuple and the the other to the whole thing? 
F!(int, char[], Object) would effectively have to be an internal, intermediate
template with the point of division as a parameter.

If you try to call the whole thing using IFTI, it's still ambiguous - what will
T1 bind to?

Maybe it could be made to work, if the compiler can be made to try to match
templates before expanding symbolic tuples under suitable conditions.


-- 
Jan 24 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2599





------- Comment #2 from andrei metalanguage.com  2009-01-24 08:45 -------
(In reply to comment #1)
 How would you use such a thing?
 
 The trouble is that F!(int, char[], Object) in itself is ambiguous - does T1
 bind to int and T2 to (char[], Object), or T1 to (int, char[]) and T2 to
 Object?  Even one to the empty tuple and the the other to the whole thing? 
 F!(int, char[], Object) would effectively have to be an internal, intermediate
 template with the point of division as a parameter.
 
 If you try to call the whole thing using IFTI, it's still ambiguous - what will
 T1 bind to?
 
 Maybe it could be made to work, if the compiler can be made to try to match
 templates before expanding symbolic tuples under suitable conditions.
 

When instantiated explicitly, all explicit arguments are eaten by T1. This is the purpose of the pattern: pass some explicit arguments, then deduce some more implicitly. Currently this is possible, but only with one ellipsis. --
Jan 24 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2599





------- Comment #3 from smjg iname.com  2009-01-25 08:54 -------
 When instantiated explicitly, all explicit arguments are eaten by 
 T1.  This is the purpose of the pattern: pass some explicit 
 arguments, then deduce some more implicitly.

In the current template system, a template is instantiated either implicitly or explicitly - no in-between. At least, AIUI, the only exception is when one template argument is deduced from another, as in template temp(T : U[], U) { const string temp = "array of " ~ U.stringof; } pragma(msg, temp!(int[])); To allow part-explicit, part-implicit template instantiations like you're asking for would be in itself a change in the language that must come first.
 Currently this is possible, but only with one ellipsis.

I'm not sure what you mean by this.... BTW your workaround can be written more simply: template f(T1...) { void f(T2...)(T2 args) { ... } } --
Jan 25 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2599





------- Comment #4 from andrei metalanguage.com  2009-01-25 09:09 -------
(In reply to comment #3)
 When instantiated explicitly, all explicit arguments are eaten by 
 T1.  This is the purpose of the pattern: pass some explicit 
 arguments, then deduce some more implicitly.

In the current template system, a template is instantiated either implicitly or explicitly - no in-between.

Try this at home: void fun(T1, T2)(T2 x) { } void main() { fun!(int)("a"); }
 To allow part-explicit, part-implicit template instantiations like you're
 asking for would be in itself a change in the language that must come first.

Already has (incidentally at my request.) It's used in much of std.algorithm.
 Currently this is possible, but only with one ellipsis.

I'm not sure what you mean by this....

This works: void fun(T1, T2, T3...)(T2 x, T3 xs) { } void main() { fun!(int)("a"); } This doesn't, which is another bug: void fun(T1, T2...)(T2 xs) { } void main() { fun!(int)("a"); }
 BTW your workaround can be written more simply:
 
     template f(T1...) {
         void f(T2...)(T2 args) { ... }
     }

Thanks! --
Jan 25 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2599





------- Comment #5 from smjg iname.com  2009-01-25 09:37 -------
(In reply to comment #4)
 Try this at home:
 
 void fun(T1, T2)(T2 x)
 {
 }
 
 void main()
 {
     fun!(int)("a");
 }

But where's it documented? Are you sure it isn't a bug that DMD accepts it? --
Jan 25 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2599





------- Comment #6 from andrei metalanguage.com  2009-01-25 09:46 -------
(In reply to comment #5)
 (In reply to comment #4)
 Try this at home:
 
 void fun(T1, T2)(T2 x)
 {
 }
 
 void main()
 {
     fun!(int)("a");
 }

But where's it documented? Are you sure it isn't a bug that DMD accepts it?

Not sure if Walter documented it. But I'm sure it's deliberately in there because I asked for the feature and Walter took the time to implement it. As far as I remember the feature was introduced in 2.015. --
Jan 25 2009