www.digitalmars.com         C & C++   DMDScript  

D - Variable numbers of function parameters?

reply =?ISO-8859-1?Q?Sigbj=F8rn_Lund_Olsen?= <sigbjorn lundolsen.net> writes:
How would I go about writing a function with a variable amount of 
parameters, a la printf, and could I use it in an interface to tell the 
derived classes that it had to implement a constructor with a variable 
amount of parameters?

Cheers,
Sigbjørn Lund Olsen
Feb 25 2004
next sibling parent Lars Ivar Igesund <larsivar igesund.net> writes:
Sigbjørn Lund Olsen wrote:

 How would I go about writing a function with a variable amount of 
 parameters, a la printf, and could I use it in an interface to tell the 
 derived classes that it had to implement a constructor with a variable 
 amount of parameters?
 
 Cheers,
 Sigbjørn Lund Olsen

I believe that to write such a function, you need to do extern (C): and then implement it as you would in C. The other stuff is probably not possible, though I don't really know. Lars Ivar Igesund
Feb 25 2004
prev sibling next sibling parent Sean Kelly <sean ffwd.cx> writes:
Sigbjørn Lund Olsen wrote:

 How would I go about writing a function with a variable amount of 
 parameters, a la printf, and could I use it in an interface to tell the 
 derived classes that it had to implement a constructor with a variable 
 amount of parameters?

D doesn't currently support defaults or the (terrifying) "..." signifier. I'm not sure there's a way to do what you're asking. Sean
Feb 25 2004
prev sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
On Wed, 25 Feb 2004 17:48:26 +0100, Sigbjørn Lund Olsen wrote:

[...]
 variable amount of parameters

dmd supports the `...' qualifier and it is used in phobos. Have a look at the source of `format' in std.string how to use it. So long.
Feb 25 2004
next sibling parent Sean Kelly <sean ffwd.cx> writes:
Manfred Nowak wrote:

 On Wed, 25 Feb 2004 17:48:26 +0100, Sigbjørn Lund Olsen wrote:
 
 [...]
 
variable amount of parameters

dmd supports the `...' qualifier and it is used in phobos.

Oops! Then I take back what I said. Sean
Feb 25 2004
prev sibling parent reply SpookyET <not4_u hotmail.com> writes:
Damn, you still have to mess with that C crappy way.

This way (C# style), it would be much better:

void main()
{
	printNumbers(1, 2, 3, 4, 5);
}

void printNumbers(params int[] list)
{
    foreach(int number; list)
    {
        puts(number);
    }
}

The compiler can create that array for you.
"params" will always have to be at the end of the parameters list, which  
is a clue for the compiler to create an array and put the the rest of the  
arguments in it.

void main()
{
	printStuff("Hello World!", 'D', 1, 2, 3, 4, 5);
}

void printStuff(char[] message, char letter, params int[] list)
{
    puts(message);
    puts(letter);
    foreach(int number; list)
    {
        puts(number);
    }
}

On Wed, 25 Feb 2004 20:01:39 +0100, Manfred Nowak <svv1999 hotmail.com>  
wrote:

 On Wed, 25 Feb 2004 17:48:26 +0100, Sigbjørn Lund Olsen wrote:

 [...]
 variable amount of parameters

dmd supports the `...' qualifier and it is used in phobos. Have a look at the source of `format' in std.string how to use it. So long.

-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Mar 01 2004
next sibling parent reply Ilya Minkov <minkov cs.tum.edu> writes:
We don't have a facility for compiling arrays at run-time. I was already =

arguing for that to be done like you propose, but it needs an array=20
compiler. Even if we don't get it for varargs functions (which i think=20
should be done), we could nontheless do:

     printNumbers([1, 2, 3, 4, 5]);

which is not as pretty in this certain case, but is useful for many=20
other things.

I was also wondering whether it is possible to syntactically unite it=20
with tuples in a sane manner. Any ideas on it?

-eye


SpookyET wrote:

 Damn, you still have to mess with that C crappy way.
=20
 This way (C# style), it would be much better:
=20
 void main()
 {
     printNumbers(1, 2, 3, 4, 5);
 }
=20
 void printNumbers(params int[] list)
 {
    foreach(int number; list)
    {
        puts(number);
    }
 }
=20
 The compiler can create that array for you.
 "params" will always have to be at the end of the parameters list,=20
 which  is a clue for the compiler to create an array and put the the=20
 rest of the  arguments in it.
=20
 void main()
 {
     printStuff("Hello World!", 'D', 1, 2, 3, 4, 5);
 }
=20
 void printStuff(char[] message, char letter, params int[] list)
 {
    puts(message);
    puts(letter);
    foreach(int number; list)
    {
        puts(number);
    }
 }
=20
 On Wed, 25 Feb 2004 20:01:39 +0100, Manfred Nowak <svv1999 hotmail.com>=

 wrote:
=20
 On Wed, 25 Feb 2004 17:48:26 +0100, Sigbj=F8rn Lund Olsen wrote:

 [...]

 variable amount of parameters

dmd supports the `...' qualifier and it is used in phobos. Have a look at the source of `format' in std.string how to use it. So long.

=20 =20 =20

Mar 01 2004
parent reply SpookyET <not4_u hotmail.com> writes:
printNumbers([1, 2, 3, 4, 5]);  Does't work

On Mon, 01 Mar 2004 22:34:34 +0100, Ilya Minkov <minkov cs.tum.edu> wrote:

 We don't have a facility for compiling arrays at run-time. I was already  
 arguing for that to be done like you propose, but it needs an array  
 compiler. Even if we don't get it for varargs functions (which i think  
 should be done), we could nontheless do:

      printNumbers([1, 2, 3, 4, 5]);

 which is not as pretty in this certain case, but is useful for many  
 other things.

 I was also wondering whether it is possible to syntactically unite it  
 with tuples in a sane manner. Any ideas on it?

 -eye


 SpookyET wrote:

 Damn, you still have to mess with that C crappy way.
  This way (C# style), it would be much better:
  void main()
 {
     printNumbers(1, 2, 3, 4, 5);
 }
  void printNumbers(params int[] list)
 {
    foreach(int number; list)
    {
        puts(number);
    }
 }
  The compiler can create that array for you.
 "params" will always have to be at the end of the parameters list,  
 which  is a clue for the compiler to create an array and put the the  
 rest of the  arguments in it.
  void main()
 {
     printStuff("Hello World!", 'D', 1, 2, 3, 4, 5);
 }
  void printStuff(char[] message, char letter, params int[] list)
 {
    puts(message);
    puts(letter);
    foreach(int number; list)
    {
        puts(number);
    }
 }
  On Wed, 25 Feb 2004 20:01:39 +0100, Manfred Nowak  
 <svv1999 hotmail.com>  wrote:

 On Wed, 25 Feb 2004 17:48:26 +0100, Sigbjørn Lund Olsen wrote:

 [...]

 variable amount of parameters

dmd supports the `...' qualifier and it is used in phobos. Have a look at the source of `format' in std.string how to use it. So long.



-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Mar 01 2004
parent reply Carlos Santander B. <Carlos_member pathlink.com> writes:
In article <opr37gm5ti1s9n15 saturn>, SpookyET says...
printNumbers([1, 2, 3, 4, 5]);  Does't work

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

No, D doesn't let you create arrays on the fly (that's the way it's said, right?). ------------------- Carlos Santander B.
Mar 01 2004
parent Derek Parnell <Derek.Parnell Psyc.ward> writes:
On Mon, 1 Mar 2004 23:45:15 +0000 (UTC) (03/02/04 10:45:15)
, Carlos Santander B. <Carlos_member pathlink.com> wrote:

 In article <opr37gm5ti1s9n15 saturn>, SpookyET says...
 printNumbers([1, 2, 3, 4, 5]);  Does't work

 --
 Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

No, D doesn't let you create arrays on the fly (that's the way it's said, right?).

<FirstReaction> How dumb is that!? </FirstReaction> <SecondReaction> See 1st reaction. </SecondReaction> Surely this is just one of those things that hasn't *yet* made it to the language. A literal array is a valid thing to do. It is used often when available. Please excuse my lack of D experience and my mentioning another language I am familiar with, but in Euphoria it could be coded thus ... procedure printNumbers(sequence list) for i = 1 to length(list) do ConsoleOut(list[i]) end for end procedure printNumbers( {1, 2, 3, 4, 5 } ) In Euphoria, a sequence is a list of zero or more 'things', referenced by a 1-based integer index. The 'things' can be any datatype, which by the way are only integers, atoms ( read: floats ), or sequences. A character string is just a sequence of integers. Euphoria handles all garbage collection. Parameters can only be passed by value (in effect). There is no pointer/reference/address-of concept.... ...ooops...but this is probably too much information, right? ;-) Sorry, got carried away. -- Derek
Mar 01 2004
prev sibling next sibling parent reply "Ben Hinkle" <bhinkle4 juno.com> writes:
"SpookyET" <not4_u hotmail.com> wrote in message
news:opr36979x51s9n15 saturn...
 Damn, you still have to mess with that C crappy way.

 This way (C# style), it would be much better:

 void main()
 {
 printNumbers(1, 2, 3, 4, 5);
 }

 void printNumbers(params int[] list)
 {
     foreach(int number; list)
     {
         puts(number);
     }
 }

A work-around for D would look something like: import std.c.stdio; extern (C) void test(int nargs,...) { // assumes the stack goes in a certain direction? int* args = cast(int*)(cast(va_list)&nargs+int.size); int[] arglist = args[0 .. nargs]; // now arglist is a "varargs" array. printf("last element is %d\n", arglist[arglist.length-1]); } int main(char[][] argv) { test(5, 1,2,3,4,5); return 0; } Not as nifty as C-sharp but still pretty usable. Also the D version doesn't allocate any memory - it is all on the stack If phobos would have some va_list sugar then the line int* args = cast(int*)(cast(va_list)&nargs+int.size); could be replaced with a call to phobos - maybe it could take care of the slicing, too.
 The compiler can create that array for you.
 "params" will always have to be at the end of the parameters list, which
 is a clue for the compiler to create an array and put the the rest of the
 arguments in it.

 void main()
 {
 printStuff("Hello World!", 'D', 1, 2, 3, 4, 5);
 }

 void printStuff(char[] message, char letter, params int[] list)
 {
     puts(message);
     puts(letter);
     foreach(int number; list)
     {
         puts(number);
     }
 }

 On Wed, 25 Feb 2004 20:01:39 +0100, Manfred Nowak <svv1999 hotmail.com>
 wrote:

 On Wed, 25 Feb 2004 17:48:26 +0100, Sigbjørn Lund Olsen wrote:

 [...]
 variable amount of parameters

dmd supports the `...' qualifier and it is used in phobos. Have a look at the source of `format' in std.string how to use it. So long.

-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

Mar 01 2004
parent "Ben Hinkle" <bhinkle4 juno.com> writes:
sorry for the self-reply, but here goes a better version:


// this part should go into phobos somewhere
private import std.c.stdio;

template va_array(T) {
      T[] va_array(uint* ptr)
      {
  T* args = cast(T*)(cast(va_list)ptr + uint.size);
  return args[0 .. *ptr];
      }
}

// this part is what user code would look like
void test(uint n,...)
{
   int[] args = va_array!(int)(&n);
   printf("last element is %d\n", args[args.length-1]);
}

class TestClass {
   void test2(uint n,...)
   {
      double[] args = va_array!(double)(&n);
      printf("last element is %f\n", args[args.length-1]);
   }
   void test3(uint n,...)
   {
      char[][] args = va_array!(char[])(&n);
      printf("last element is %.*s\n", args[args.length-1]);
   }
}

int main()
{
   test(5, 1, 2, 3, 4, 5);
   TestClass x = new TestClass();
   x.test2(5, 1.1, 2.2, 3.3, 4.4, 5.5);
   x.test3(2, "hello", "world");
   return 0;
}
Mar 01 2004
prev sibling next sibling parent reply Carlos Santander B. <Carlos_member pathlink.com> writes:
In article <opr36979x51s9n15 saturn>, SpookyET says...
Damn, you still have to mess with that C crappy way.

This way (C# style), it would be much better:

void main()
{
	printNumbers(1, 2, 3, 4, 5);
}

void printNumbers(params int[] list)
{
    foreach(int number; list)
    {
        puts(number);
    }
}

The compiler can create that array for you.
"params" will always have to be at the end of the parameters list, which  
is a clue for the compiler to create an array and put the the rest of the  
arguments in it.

void main()
{
	printStuff("Hello World!", 'D', 1, 2, 3, 4, 5);
}

void printStuff(char[] message, char letter, params int[] list)
{
    puts(message);
    puts(letter);
    foreach(int number; list)
    {
        puts(number);
    }
}

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

I think that's a good, but there's a problem: what if you want to receive parameters of any type? In C# you can do 'params object[] list', but in D you wouldn't be able, because D doesn't do boxing/unboxing like C#. It's been talked a lot, but there doesn't seem to be a sensible way to do it. ------------------- Carlos Santander B.
Mar 01 2004
parent reply Ilya Minkov <minkov cs.tum.edu> writes:
Carlos Santander B. wrote:

 I think that's a good, but there's a problem: what if you want to receive
 parameters of any type? In C# you can do 'params object[] list', but in D you
 wouldn't be able, because D doesn't do boxing/unboxing like C#.
 It's been talked a lot, but there doesn't seem to be a sensible way to do it.

I think i know how it can be implemented. But i'd say it should be left to post-release D. And yes, as to your other post, i really meant that i would like dynamic creation of arrays, but it's not there yet. And i'm not sure Walter was eager to do it. Maybe i come to hack the compiler as well, but now i really need a rest. Sorry for not keeping my promise. -eye
Mar 01 2004
parent "Ben Hinkle" <bhinkle4 juno.com> writes:
"Ilya Minkov" <minkov cs.tum.edu> wrote in message
news:c20ivv$2j5k$1 digitaldaemon.com...
| Carlos Santander B. wrote:
|
| > I think that's a good, but there's a problem: what if you want to receive
| > parameters of any type? In C# you can do 'params object[] list', but in D
you
| > wouldn't be able, because D doesn't do boxing/unboxing like C#.
| > It's been talked a lot, but there doesn't seem to be a sensible way to do
it.
|
| I think i know how it can be implemented. But i'd say it should be left
| to post-release D.
|
| And yes, as to your other post, i really meant that i would like dynamic
| creation of arrays, but it's not there yet. And i'm not sure Walter was
| eager to do it. Maybe i come to hack the compiler as well, but now i
| really need a rest. Sorry for not keeping my promise.
|
| -eye

I hope I'm not beating a dead horse with workarounds until array
literals get supported but here's yet more code for those who want
something that works today:

private import std.c.stdio;
template va_array(T)
{
   T[] va_array(uint* ptr)
   {
      T* args = cast(T*)(cast(va_list)ptr + uint.size);
      return args[0 .. *ptr];
   }
}
template new_array(T)
{
   T[] new_array(uint n,...)
   {
      return va_array!(T)(&n).dup;
   }
}

// user code
void test(int[] x)
{
   printf("last element: %d\n",x[x.length-1]);
}

int main()
{
   test(new_array!(int)(3, 1,2,3));
   return 0;
}
Mar 02 2004
prev sibling parent Matthias Becker <Matthias_member pathlink.com> writes:
Damn, you still have to mess with that C crappy way.

Right.
This way (C# style), it would be much better:

*arg*, please stop it! C# is a crapy language. I like other languages better than D, but have you ever seen me posting: In my Favorite languge this is done better. And that, too. ...
void main()
{
	printNumbers(1, 2, 3, 4, 5);
}

void printNumbers(params int[] list)
{
    foreach(int number; list)
    {
        puts(number);
    }
}

The compiler can create that array for you.

Wouldn't array literals be a much better alternative? It would be as easy, but could be used in other situations, too. And you should allways prefer the more flexible way of doing something if it isn't more complicated.
"params" will always have to be at the end of the parameters list, which  
is a clue for the compiler to create an array and put the the rest of the  
arguments in it.

With array-literals you wouldn't have this restriction. And I don't like being restricted. C# made some steps in the right directions, but never goes far enough. It offers you some helpfull things that can be used in common cases, but in not that common cases you have a big problem. D already is much better than C#.
Mar 02 2004