Jump to page: 1 2
Thread overview
variadic function: passing args
Jul 04, 2006
icee
Jul 04, 2006
Walter Bright
Jul 05, 2006
icee
Jul 06, 2006
David L. Davis
Jul 07, 2006
Georg Wrede
Jul 06, 2006
Georg Wrede
Jul 06, 2006
Ivan Senji
Jul 06, 2006
pragma
Jul 06, 2006
Kirk McDonald
Jul 07, 2006
Georg Wrede
July 04, 2006
is there a way to pass the ... args from one variadic function to another variadic function?

consider such case:
void vf1(int a, ...) {

vf2(...);
}
void vf2(...) {
}

can vf2 take _arguments and _argptr from vf1?


July 04, 2006
icee wrote:
> is there a way to pass the ... args from one variadic function to another
> variadic function?
> 
> consider such case:
> void vf1(int a, ...) {
> 
> vf2(...);
> }
> void vf2(...) {
> }
> 
> can vf2 take _arguments and _argptr from vf1?

No, it works a lot like printf/vprintf. Check out the source to std.format for how to do it.
July 04, 2006
icee wrote:
> is there a way to pass the ... args from one variadic function to another
> variadic function?
> 
> consider such case:
> void vf1(int a, ...) {
> 
> vf2(...);
> }
> void vf2(...) {
> }
> 
> can vf2 take _arguments and _argptr from vf1?
> 
> 

Simply way to do it, is to write vf2 twice, once as a variadic wrapper, and once taking a vararg pair.  In other words:

# import std .stdarg ;
#
# void vf2 (...) { vf2(_arguments, _argptr); }
#
# void vf2 (TypeInfo[] _arguments, va_list _argptr) {
#   /* real work */
# }

Sad to say, this is one time when I do start to miss a preprocessor just a little.  It'd be somewhat nice to be able to do:

########## module altvararg ;
# import std .stdarg ;
#
# #define ALT_VARIADIC(FNAME) \
#   void FNAME (...) { FNAME(_arguments, _argptr; } \
#   void FNAME (TypeInfo[] _arguments, va_list _argptr)
#

########## module foo ;
# import altvararg ;
#
# ALT_VARIADIC(vf2) {
#   /* real work */
# }

Maybe if we /did/ have a way it would be better.  Maybe something like:
# vf2(_arguments ... _argptr);

Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such.  Not sure if it'd be the best syntax, but its the simplest thing that comes to mind.

-- Chris Nicholson-Sauls
July 05, 2006
In article <e8db27$1hu9$2@digitaldaemon.com>, Walter Bright says...
>
>icee wrote:
>> is there a way to pass the ... args from one variadic function to another variadic function?
>> 
>> consider such case:
>> void vf1(int a, ...) {
>> 
>> vf2(...);
>> }
>> void vf2(...) {
>> }
>> 
>> can vf2 take _arguments and _argptr from vf1?
>
>No, it works a lot like printf/vprintf. Check out the source to std.format for how to do it.


----------------------
Yes, it works if we explicitly pass _arguments and _argptr to a overloaded ones, but it would be sweet if the compiler can do a magic for me, by some special syntax. And even more sometime we have no control on the src which provides the vf2.

we can do this for a type safe variadic function in D(or C#?):
void vf1(int a, Object[] args...){
vf2(args);
}

and in Python by pack/unpack:
def vf1(a, *args, **kw):
vf2(*arg, **kw)
return

----------------------


In article <e8dc2l$1jta$1@digitaldaemon.com>, Chris Nicholson-Sauls says...
>
>Maybe if we /did/ have a way it would be better.  Maybe something like: # vf2(_arguments ... _argptr);
>
>Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such.  Not sure if it'd be the best syntax, but its the simplest thing that comes to mind.
>
>-- Chris Nicholson-Sauls

----------------------------
maybe just vf2(...); is OK??? if this tell the compiler wrap the _arguments _argptr pair of vf1 into the vf2 and call it???


and maybe i'm asking for too much:)


July 06, 2006
icee wrote:
> In article <e8db27$1hu9$2@digitaldaemon.com>, Walter Bright says...
> 
>>icee wrote:
>>
>>>is there a way to pass the ... args from one variadic function to another
>>>variadic function?
>>>
>>>consider such case:
>>>void vf1(int a, ...) {
>>>
>>>vf2(...);
>>>}
>>>void vf2(...) {
>>>}
>>>
>>>can vf2 take _arguments and _argptr from vf1?
>>
>>No, it works a lot like printf/vprintf. Check out the source to std.format for how to do it.
> 
> 
> 
> ----------------------
> Yes, it works if we explicitly pass _arguments and _argptr to a overloaded ones,
> but it would be sweet if the compiler can do a magic for me, by some special
> syntax. And even more sometime we have no control on the src which provides the
> vf2.
> 
> we can do this for a type safe variadic function in D(or C#?):
> void vf1(int a, Object[] args...){
> vf2(args);
> }
> 
> and in Python by pack/unpack:
> def vf1(a, *args, **kw):
> vf2(*arg, **kw)
> return
> 
> ----------------------
> 
> 
> In article <e8dc2l$1jta$1@digitaldaemon.com>, Chris Nicholson-Sauls says...
> 
>>Maybe if we /did/ have a way it would be better.  Maybe something like:
>># vf2(_arguments ... _argptr);
>>
>>Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such.  Not sure if it'd be the best syntax, but its the simplest thing that comes to mind.
>>
>>-- Chris Nicholson-Sauls
> 
> 
> ----------------------------
> maybe just vf2(...); is OK??? if this tell the compiler wrap the _arguments
> _argptr pair of vf1 into the vf2 and call it???
> 
> 
> and maybe i'm asking for too much:)
> 
> 

Well sure, but I thought it might be nice if one could, for example, pop the first couple of values off before passing it.  Or maybe be able to build one's varargs from scratch or other such odd thing.  No I haven't done anything like that in the past... but it could only be because I wasn't /able/ to do such a thing.  :)

-- Chris Nicholson-Sauls
July 06, 2006
In article <e8i4kn$133i$1@digitaldaemon.com>, Chris Nicholson-Sauls says...
>
>icee wrote:
>> In article <e8db27$1hu9$2@digitaldaemon.com>, Walter Bright says...
>> 
>>>icee wrote:
>>>
>>>>is there a way to pass the ... args from one variadic function to another variadic function?
>>>>
>>>>consider such case:
>>>>void vf1(int a, ...) {
>>>>
>>>>vf2(...);
>>>>}
>>>>void vf2(...) {
>>>>}
>>>>
>>>>can vf2 take _arguments and _argptr from vf1?
>>>
>>>No, it works a lot like printf/vprintf. Check out the source to std.format for how to do it.
>> 
>> 
>> 
>> ----------------------
>> Yes, it works if we explicitly pass _arguments and _argptr to a overloaded ones, but it would be sweet if the compiler can do a magic for me, by some special syntax. And even more sometime we have no control on the src which provides the vf2.
>> 
>> we can do this for a type safe variadic function in D(or C#?):
>> void vf1(int a, Object[] args...){
>> vf2(args);
>> }
>> 
>> and in Python by pack/unpack:
>> def vf1(a, *args, **kw):
>> vf2(*arg, **kw)
>> return
>> 
>> ----------------------
>> 
>> 
>> In article <e8dc2l$1jta$1@digitaldaemon.com>, Chris Nicholson-Sauls says...
>> 
>>>Maybe if we /did/ have a way it would be better.  Maybe something like: # vf2(_arguments ... _argptr);
>>>
>>>Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such.  Not sure if it'd be the best syntax, but its the simplest thing that comes to mind.
>>>
>>>-- Chris Nicholson-Sauls
>> 
>> 
>> ----------------------------
>> maybe just vf2(...); is OK??? if this tell the compiler wrap the _arguments _argptr pair of vf1 into the vf2 and call it???
>> 
>> 
>> and maybe i'm asking for too much:)
>> 
>> 
>
>Well sure, but I thought it might be nice if one could, for example, pop the first couple of values off before passing it.  Or maybe be able to build one's varargs from scratch or other such odd thing.  No I haven't done anything like that in the past... but it could only be because I wasn't /able/ to do such a thing.  :)
>
>-- Chris Nicholson-Sauls

Chris,

You could check out my Diva Class project at:

http://spottedtiger.tripod.com/D_Language/D_Diva_Project_XP.html

Short description:
-----------------

Diva (Dynamically Interconnected Variable Arguments) - Diva.d v0.38 WIP Allows the ability to "get" and "set" data, plus alter D's variadic arguments function parameter layout with methods like "prepend, append, insert, splice, and remove.

Class implicitly converts stored values of non-exact types whenever possible,
allowing for a polymorphic-like value passing to variables, otherwise it returns
a default value, avoiding errors if all possible. The Diva Class is more focused
toward flexablity (using automatic value conversion) than on
opitmal (speed) peformance (operating on only exact/near-exact types i.e.
std.boxer).

David L.

-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
-------------------------------------------------------------------

http://spottedtiger.tripod.com/D_Language/D_Main_XP.html
July 06, 2006
Chris Nicholson-Sauls wrote:
> icee wrote:
> 
>> is there a way to pass the ... args from one variadic function to another
>> variadic function?
>>
>> consider such case:
>> void vf1(int a, ...) {
>>
>> vf2(...);
>> }
>> void vf2(...) {
>> }
>>
>> can vf2 take _arguments and _argptr from vf1?
>>
>>
> 
> Simply way to do it, is to write vf2 twice, once as a variadic wrapper, and once taking a vararg pair.  In other words:
> 
> # import std .stdarg ;
> #
> # void vf2 (...) { vf2(_arguments, _argptr); }
> #
> # void vf2 (TypeInfo[] _arguments, va_list _argptr) {
> #   /* real work */
> # }
> 
> Sad to say, this is one time when I do start to miss a preprocessor just a little.  It'd be somewhat nice to be able to do:
> 
> ########## module altvararg ;
> # import std .stdarg ;
> #
> # #define ALT_VARIADIC(FNAME) \
> #   void FNAME (...) { FNAME(_arguments, _argptr; } \
> #   void FNAME (TypeInfo[] _arguments, va_list _argptr)
> #
> 
> ########## module foo ;
> # import altvararg ;
> #
> # ALT_VARIADIC(vf2) {
> #   /* real work */
> # }
> 
> Maybe if we /did/ have a way it would be better.  Maybe something like:
> # vf2(_arguments ... _argptr);
> 
> Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such.  Not sure if it'd be the best syntax, but its the simplest thing that comes to mind.

Suppose we had a new keyword, variadic. Then the compiler could internally accomplish what you propose, by just rewriting, and no complicated changes are needed!

void variadic foo(...)
{
    // real work
}

Of course, here the "..." is redundant. So maybe the syntax could be even more simple:

void foo(...) {
    // real work
}

So, in essence, the compiler constructs two functions (instead of one):

whateverReturnType foo(...) {
    // real work
}

gets rewritten as:

whateverReturnType foo(...) { foo(_arguments, _argptr; }
whateverReturnType foo(TypeInfo[] _arguments, va_list _argptr)
{
    // real work
}

Now, another change is of course handy here, and that is, if a function gets invoked like

blah = foo(...);

then it will be rewritten as:

blah = foo(_arguments, _argptr);

which should be no big deal to implement, right? Major syntactic sugar, I admit, but then again, the whole ... busines is just that. (Or else we would just pass Object[] type variables, right?)

----

This makes one actually wish for some sugar for manipulation of runtime-generated argument lists! (Lisp, watch out, we're coming!)
July 06, 2006
Georg Wrede wrote:
> Chris Nicholson-Sauls wrote:
>> icee wrote:
>>
>>> is there a way to pass the ... args from one variadic function to
>>> another
>>> variadic function?
>>>
>>> consider such case:
>>> void vf1(int a, ...) {
>>>
>>> vf2(...);
>>> }
>>> void vf2(...) {
>>> }
>>>
>>> can vf2 take _arguments and _argptr from vf1?
>>>
>>>
>>
>> Simply way to do it, is to write vf2 twice, once as a variadic wrapper, and once taking a vararg pair.  In other words:
>>
>> # import std .stdarg ;
>> #
>> # void vf2 (...) { vf2(_arguments, _argptr); }
>> #
>> # void vf2 (TypeInfo[] _arguments, va_list _argptr) {
>> #   /* real work */
>> # }
>>
>> Sad to say, this is one time when I do start to miss a preprocessor just a little.  It'd be somewhat nice to be able to do:
>>
>> ########## module altvararg ;
>> # import std .stdarg ;
>> #
>> # #define ALT_VARIADIC(FNAME) \
>> #   void FNAME (...) { FNAME(_arguments, _argptr; } \
>> #   void FNAME (TypeInfo[] _arguments, va_list _argptr)
>> #
>>
>> ########## module foo ;
>> # import altvararg ;
>> #
>> # ALT_VARIADIC(vf2) {
>> #   /* real work */
>> # }
>>
>> Maybe if we /did/ have a way it would be better.  Maybe something like: # vf2(_arguments ... _argptr);
>>
>> Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such.  Not sure if it'd be the best syntax, but its the simplest thing that comes to mind.
> 
> Suppose we had a new keyword, variadic. Then the compiler could internally accomplish what you propose, by just rewriting, and no complicated changes are needed!
> 
> void variadic foo(...)
> {
>     // real work
> }
> 
> Of course, here the "..." is redundant. So maybe the syntax could be even more simple:
> 
> void foo(...) {
>     // real work
> }
> 
> So, in essence, the compiler constructs two functions (instead of one):
> 
> whateverReturnType foo(...) {
>     // real work
> }
> 
> gets rewritten as:
> 
> whateverReturnType foo(...) { foo(_arguments, _argptr; }
> whateverReturnType foo(TypeInfo[] _arguments, va_list _argptr)
> {
>     // real work
> }
> 
> Now, another change is of course handy here, and that is, if a function gets invoked like
> 
> blah = foo(...);
> 
> then it will be rewritten as:
> 
> blah = foo(_arguments, _argptr);

Nice idea, IMO the compiler should do this for us, but it would be even nicer if we could do something like:

blah = foo(...[0..5]); //Pass to foo only the first five arguments
July 06, 2006
In article <e8jemv$2pfh$1@digitaldaemon.com>, Ivan Senji says...
>
>Nice idea, IMO the compiler should do this for us, but it would be even nicer if we could do something like:
>
>blah = foo(...[0..5]); //Pass to foo only the first five arguments

I agree, although I don't like the idea of using "..." explicitly as an identifier.  I'd rather see a variation of the "named vararg" syntax like so:

void foo(args ...){
writefln("hello world",args);
}

The only problem with the above case is: what type does 'args' actually have (or in Ivan's example, what type does '...' have)?

It could be considered an error to use the "vararg expression" in any context other than as a function argument or parameter, but I can't help but think that it would open up a whole world of expressions if it were a proper type unto itself.

- EricAnderton at yahoo
July 06, 2006
pragma wrote:
> In article <e8jemv$2pfh$1@digitaldaemon.com>, Ivan Senji says...
> 
>>Nice idea, IMO the compiler should do this for us, but it would be even
>>nicer if we could do something like:
>>
>>blah = foo(...[0..5]); //Pass to foo only the first five arguments
> 
> 
> I agree, although I don't like the idea of using "..." explicitly as an
> identifier.  I'd rather see a variation of the "named vararg" syntax like so:
> 
> void foo(args ...){
> writefln("hello world",args);
> }
> 
> The only problem with the above case is: what type does 'args' actually have (or
> in Ivan's example, what type does '...' have)?  
> 
> It could be considered an error to use the "vararg expression" in any context
> other than as a function argument or parameter, but I can't help but think that
> it would open up a whole world of expressions if it were a proper type unto
> itself.
> 
> - EricAnderton at yahoo

Well, the answer is obvious: It is a tuple. We are essentially discussing the equivalent of this Python code:

def func(*args): # packs function arguments into a tuple
    print args

def main():
    a = ("blah", 50, 200.35) # creates a tuple
    func(1, 2, 3, "apple", 5.0) # call the function with normal args
    func(*a) # "unpack" the tuple, call the func with it

>>> main()
(1, 2, 3, "apple", 5.0)
("blah", 50, 200.35)

Though I'm not sure going quite as far as Python does with tuples is what we'd want for D. However, a proper built-in tuple type would be /damnably/ useful.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://dsource.org/projects/pyd/wiki
« First   ‹ Prev
1 2