digitalmars.D - Idea: extend typesafe variadic functions
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Mar 31 2007
- Daniel Keep <daniel.keep.lists gmail.com> Mar 31 2007
- Davidl <Davidl 126.com> Mar 31 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Apr 01 2007
- Davidl <Davidl 126.com> Mar 31 2007
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
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
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
"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
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









Davidl <Davidl 126.com> 