Jump to page: 1 2
Thread overview
[Issue 1839] New: Give D a modern varargs system that allows forwarding
Feb 15, 2008
d-bugmail
Feb 15, 2008
Janice Caron
Feb 15, 2008
d-bugmail
Feb 15, 2008
d-bugmail
Feb 15, 2008
d-bugmail
Feb 15, 2008
Lars Ivar Igesund
Feb 15, 2008
d-bugmail
Feb 15, 2008
d-bugmail
Feb 15, 2008
d-bugmail
Feb 15, 2008
d-bugmail
Feb 15, 2008
d-bugmail
Feb 15, 2008
d-bugmail
Feb 15, 2008
Lars Ivar Igesund
Feb 15, 2008
d-bugmail
Feb 15, 2008
d-bugmail
Feb 15, 2008
d-bugmail
February 15, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839

           Summary: Give D a modern varargs system that allows forwarding
           Product: D
           Version: 2.010
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: wbaxter@gmail.com


Given function

void A(...) {
 ...
}

It should be possible to write a function wrapsA of this sort:

void wrapsA(...) {
    pre_call();
    A(...); // or whatever syntax you want for forwarding the varargs.
    post_call();
}

That D --  a supposedly modern, easy-to-use languages -- can't do this conceptually simple thing is sad.

The whole point of procedural programming is that code is encapsulated into reusable blocks.  Not being able to forward varargs means that a big chunk of that reusability is lost any time you write a varargs function.

The workaround is to write every varargs function in two flavors, one thats got (...) args, and one that's got (_argptr,_arguments) args.  But if the solution is so mechanical and straightforward then why can't the compiler at just do that for us?  I'm not saying that's the right way to implement vararg forwarding, but barring a more elegant solution, that sounds like at least a plausible solution.


-- 

February 15, 2008
On 15/02/2008, d-bugmail@puremagic.com <d-bugmail@puremagic.com> wrote:
>  That D --  a supposedly modern, easy-to-use languages -- can't do this
>  conceptually simple thing is sad.

Will this not work?

    import std.traits;

    ReturnType!(f) wraps(alias f)(ParameterTypeTuple!(f) t)
    {
        pre_call();
        ReturnType!(f) x = f(t);
        post_call();
        return x;
    }

    wrap!(A)(params);
February 15, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839





------- Comment #2 from wbaxter@gmail.com  2008-02-15 01:56 -------
Sometimes you can't / don't want to use a template.

If templates were an answer then we wouldn't need the regular vararg functions to begin with.


-- 

February 15, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839





------- Comment #3 from wbaxter@gmail.com  2008-02-15 01:58 -------
...and what is the parameter type tuple of a varargs function?

I suspect that probably doesn't work actually.


-- 

February 15, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839


andrei@metalanguage.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID




------- Comment #4 from andrei@metalanguage.com  2008-02-15 02:36 -------
"..."-style varargs predate template varargs and have a number of disadvantages compared to them, so it is likely they will get deprecated in favor of templates and macros.


-- 

February 15, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839





------- Comment #5 from wbaxter@gmail.com  2008-02-15 02:39 -------
If (...) functions go away, then yes, this bug report becomes pointless.  The template versions of forwarding will do the trick.

But how do I create a delegate that takes an arbitrary list of arbitrary arguments using templates?


-- 

February 15, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839





------- Comment #6 from andrei@metalanguage.com  2008-02-15 02:47 -------
(In reply to comment #5)
> If (...) functions go away, then yes, this bug report becomes pointless.  The template versions of forwarding will do the trick.
> 
> But how do I create a delegate that takes an arbitrary list of arbitrary arguments using templates?
> 

import std.stdio;

void before() {}
void after() {}

void forward(F, T...)(F fun, T args)
{
    before();
    scope(exit) after();
    fun(args);
}

void main()
{
    forward((int a) { writeln(a + 40); }, 2);
}


-- 

February 15, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839





------- Comment #7 from wbaxter@gmail.com  2008-02-15 02:58 -------
I mean this:
----
void delegate(...) callback = &fn;

...

callback("hi", 10, "mom");
----

Does your snippet of code show how to do that?  If so, I'm not seeing the connection, so please explain again.


-- 

February 15, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839





------- Comment #8 from andrei@metalanguage.com  2008-02-15 03:35 -------
I misunderstood your initial code sample. In fact that's a simpler problem:

import std.stdio;

void before() {}
void after() {}

void fn(...)
{
    foreach (i; 0 .. _arguments.length)
    {
        _arguments[i].print;
    }
    if (_arguments[0] == typeid(int))
    {
        int j = *cast(int *)_argptr;
        writeln(j);
    }
}

void wrapsFn(T...)(T args)
{
    before();
    scope(exit) after();
    fn(args);
}

void main()
{
    wrapsFn(2, 42, "a");
}


-- 

February 15, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839





------- Comment #9 from aarti@interia.pl  2008-02-15 04:16 -------
Isn't it that variable arguments templates have its own problems also?

Executable size will increase very quickly for different types/combinations of parameters. AFAIK it will happen especially when template body will be very big. Sure you can split big template into smaller, but it means also that size of program will heavily depend on coding style of programmer. Or is it possible to optimize such a big template automagically?

But I think that, if variable argument templates are not able to be instant replacement (considering e.g. size of executable), variable arguments functions should stay...

When they would stay a few simple fixes would probably enhance current situation in order of magnitude.

1. Defining struct, which will keep typeinfo pointer and data pointer
   e.g. struct Arg {TypeInfo type; void* ptr;}
2. Then variable argument functions could be declared like other type safe
variadic argument functions in D:
void func(Arg[] param...) {}

...and the problem with passing arguments would be solved... (also ugly local
variables (=hacks): _argptr, _arguments could disappear).


-- 

« First   ‹ Prev
1 2