www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Idea: extend typesafe variadic functions

reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
One of the "cool features you probably didn't know about" with typesafe 
variadic functions is that you can make a variadic class parameter which 
will be constructed with the parameters to the function, like so:

class A
{
    this(int x, float y){}
}

void func(A a...)
{

}

...

func(3, 4.5);

This will implicitly call the constructor for A when you call func() and 
will forward those parameters to the class constructor.

What would be really cool is to have this happen for an array of classes or 
structs as well:

class A
{
    this(int x) {}
    this(float x) {}
    this(char[] s) {}
}

void func(A[] args...)
{

}

...

func(1, 2.3, "hi");

Right now, it says "cannot implicitly convert 1 to A" or something, but with 
this new feature, this would construct three instances of A, one using the 
int constructor, one using the float, and one using the string.  Of course, 
for sanity's sake, it would only try to construct As using single-parameter 
constructors.

This would work similarly for structs:

struct S
{
    static S opCall(T)(T value)
    {
        S s;
        return s;
    }
}

void func(S[] args...)
{

}

...

func(1, 2.3, "hi");

(See if you can figure out why I think this would be cool.. ;) ) 
Mar 31 2007
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Jarrett Billingsley wrote:
 One of the "cool features you probably didn't know about" with typesafe 
 variadic functions is that you can make a variadic class parameter which 
 will be constructed with the parameters to the function, like so:
 
 class A
 {
     this(int x, float y){}
 }
 
 void func(A a...)
 {
 
 }
 
 ....
 
 func(3, 4.5);
 
 This will implicitly call the constructor for A when you call func() and 
 will forward those parameters to the class constructor.
*Boggle* When did *that* happen?!
 What would be really cool is to have this happen for an array of classes or 
 structs as well:
 
 class A
 {
     this(int x) {}
     this(float x) {}
     this(char[] s) {}
 }
 
 void func(A[] args...)
 {
 
 }
 
 ....
 
 func(1, 2.3, "hi");
 
 Right now, it says "cannot implicitly convert 1 to A" or something, but with 
 this new feature, this would construct three instances of A, one using the 
 int constructor, one using the float, and one using the string.  Of course, 
 for sanity's sake, it would only try to construct As using single-parameter 
 constructors.
 
 This would work similarly for structs:
 
 struct S
 {
     static S opCall(T)(T value)
     {
         S s;
         return s;
     }
 }
 
 void func(S[] args...)
 {
 
 }
 
 ....
 
 func(1, 2.3, "hi");
 
 (See if you can figure out why I think this would be cool.. ;) ) 
I'm afraid I can't :( I imagine that there's probably some very nice things you could do with this, but I can't see why you couldn't do it already: void funcT(Ts...)(Ts args) { A[] as; as.length = args.length; foreach( i, arg ; args ) as[i] = new A(arg); func(as); } Getting this to work with overloads would be... interesting, but certainly doable. Heck, you could probably turn the above into a generic templated "array-of-T" initializer. On a side note, am I the only one who is *really* uncomfortable with the fact that the first example works at all? :S -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Mar 31 2007
next sibling parent Davidl <Davidl 126.com> writes:
I haven't noticed what u have said. great point. the implementation of  
func(A[] ...) would need some templates, if not we would come to the  
problem of what tango comes to.
Mar 31 2007
prev sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message 
news:eundlt$sl7$1 digitalmars.com...
 I'm afraid I can't :(

 I imagine that there's probably some very nice things you could do with
 this, but I can't see why you couldn't do it already:

 void funcT(Ts...)(Ts args)
 {
    A[] as;
    as.length = args.length;
    foreach( i, arg ; args )
        as[i] = new A(arg);

    func(as);
 }
You got it! See, if we could do this, this would allow these kind of functions to be non-templated, meaning far less code bloat, the ability to overload, and the ability to override in classes, but with almost the same amount of expressiveness. People writing scripting language binding libraries might find it _very_ useful..
 Getting this to work with overloads would be... interesting, but
 certainly doable.  Heck, you could probably turn the above into a
 generic templated "array-of-T" initializer.
I was thinking about that. But then you've still got the code bloat issues..
 On a side note, am I the only one who is *really* uncomfortable with the
 fact that the first example works at all?  :S
I think it's pretty cool, though I can see why you're kind of wary of it. Most of the rest of the language doesn't use implicit conversions.
Apr 01 2007
prev sibling parent Davidl <Davidl 126.com> writes:
since the feature is somewhat vialoating the type safe checking, i think  
restriction
may be required in case of misusing of this feature like:
1. class must have more than 1 ctor, and they must all accept only 1  
argument
2. the func using class A as the variadic arg must only envolve the use of  
A, no other type could be accepted as other args
3. a hint when calling the func might be appreciated?
4. maybe the class ctor must be declare of this type like :
class A
{
	super this (int x)
         {}
}

And in my opinion, it's a great solution to the tango IO calling  
evaluation problem , and i think it's quite useful for mangle to provide  
user a great experience of calling Stdout. Coz i dislike the  
("adkfj").(343).("akdsfj") too much :(
And I hope Kris, Lars, Sean could forgive me of that ;)

 One of the "cool features you probably didn't know about" with typesafe
 variadic functions is that you can make a variadic class parameter which
 will be constructed with the parameters to the function, like so:

 class A
 {
     this(int x, float y){}
 }

 void func(A a...)
 {

 }

 ...

 func(3, 4.5);

 This will implicitly call the constructor for A when you call func() and
 will forward those parameters to the class constructor.

 What would be really cool is to have this happen for an array of classes  
 or
 structs as well:

 class A
 {
     this(int x) {}
     this(float x) {}
     this(char[] s) {}
 }

 void func(A[] args...)
 {

 }

 ...

 func(1, 2.3, "hi");

 Right now, it says "cannot implicitly convert 1 to A" or something, but  
 with
 this new feature, this would construct three instances of A, one using  
 the
 int constructor, one using the float, and one using the string.  Of  
 course,
 for sanity's sake, it would only try to construct As using  
 single-parameter
 constructors.

 This would work similarly for structs:

 struct S
 {
     static S opCall(T)(T value)
     {
         S s;
         return s;
     }
 }

 void func(S[] args...)
 {

 }

 ...

 func(1, 2.3, "hi");

 (See if you can figure out why I think this would be cool.. ;) )
Mar 31 2007