digitalmars.D.learn - double -> double[]... | feature or bug?
- Andrej Mitrovic (8/8) Dec 22 2010 DMD 2.051 with -unittest:
- Jonathan M Davis (6/18) Dec 22 2010 What's the confusion? You gave it a double. That matches the variadic ve...
- Andrej Mitrovic (4/25) Dec 22 2010 I thought the variadic version would only take this type:
- Steven Schveighoffer (10/14) Dec 22 2010 No, that's not it.
- Andrej Mitrovic (3/19) Dec 22 2010 Oooh. That cought me off guard, sorry.
- Christopher Nicholson-Sauls (14/18) Dec 22 2010 I'll concede that the syntax can be odd at first, but it also enables
- spir (13/35) Dec 23 2010 While I understand some may consider this a nice feature, for me this is...
- bearophile (4/5) Dec 23 2010 The main problem here is that I have never felt the need of that feature...
- Andrej Mitrovic (13/23) Dec 23 2010 You should probably ask in d-general. It looks like a dangerous
- Don (2/10) Dec 23 2010 I'm almost certain that the behaviour is not intentional.
- Steven Schveighoffer (12/26) Dec 23 2010 From http://www.digitalmars.com/d/2.0/function.html :
- spir (12/16) Dec 23 2010 d =20
- Steven Schveighoffer (35/47) Dec 23 2010 To drive the point home, we can examine the problem that typesafe variad...
- bearophile (4/5) Dec 24 2010 Added as issue 5368.
DMD 2.051 with -unittest: import std.algorithm, std.range, std.stdio : writeln; void main() {} void average(double[]) { writeln("non-variadic"); } void average(double[]...) { writeln("variadic"); } unittest { average(1.5); // writes "variadic" }
Dec 22 2010
On Wednesday, December 22, 2010 12:05:18 Andrej Mitrovic wrote:DMD 2.051 with -unittest: import std.algorithm, std.range, std.stdio : writeln; void main() {} void average(double[]) { writeln("non-variadic"); } void average(double[]...) { writeln("variadic"); } unittest { average(1.5); // writes "variadic" }What's the confusion? You gave it a double. That matches the variadic version, no tthe array version. If you gave it an array of doubles, then it would match the array version. That seems entirely straightforward. What's surprising about it? - Jonathan M Davis
Dec 22 2010
I thought the variadic version would only take this type: average([1.5], [2.5]); So a variable number of *array* of doubles, not a variable number of doubles. On 12/22/10, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Wednesday, December 22, 2010 12:05:18 Andrej Mitrovic wrote:DMD 2.051 with -unittest: import std.algorithm, std.range, std.stdio : writeln; void main() {} void average(double[]) { writeln("non-variadic"); } void average(double[]...) { writeln("variadic"); } unittest { average(1.5); // writes "variadic" }What's the confusion? You gave it a double. That matches the variadic version, no tthe array version. If you gave it an array of doubles, then it would match the array version. That seems entirely straightforward. What's surprising about it? - Jonathan M Davis
Dec 22 2010
On Wed, 22 Dec 2010 15:46:01 -0500, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:I thought the variadic version would only take this type: average([1.5], [2.5]); So a variable number of *array* of doubles, not a variable number of doubles.No, that's not it. T[] arg... is a typesafe variadic argument of type T. The docs describe it here: http://www.digitalmars.com/d/2.0/function.html (search for typesafe) Hopefully that helps? If you were looking for something to accept your above args, it would be: double[][] arg... -Steve
Dec 22 2010
Oooh. That cought me off guard, sorry. Thanks Steve. On 12/22/10, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Wed, 22 Dec 2010 15:46:01 -0500, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:I thought the variadic version would only take this type: average([1.5], [2.5]); So a variable number of *array* of doubles, not a variable number of doubles.No, that's not it. T[] arg... is a typesafe variadic argument of type T. The docs describe it here: http://www.digitalmars.com/d/2.0/function.html (search for typesafe) Hopefully that helps? If you were looking for something to accept your above args, it would be: double[][] arg... -Steve
Dec 22 2010
On 12/22/10 15:06, Andrej Mitrovic wrote:Oooh. That cought me off guard, sorry. Thanks Steve.I'll concede that the syntax can be odd at first, but it also enables some interesting things. For example, this works: class Foo { this (int i, double f) { /*...*/ } /*...*/ } void someFunc ( Foo foo ... ) { /*...*/ } someFunc( 5, 3.14 ); Basically, given a class (and I think struct's work as well) as the variadic type, it will accept either an instance of said class, or any combination of values which can be mapped to a constructor of that class. It can be convenient sometimes. -- Chris N-S
Dec 22 2010
On Thu, 23 Dec 2010 00:34:41 -0600 Christopher Nicholson-Sauls <ibisbasenji gmail.com> wrote:On 12/22/10 15:06, Andrej Mitrovic wrote:While I understand some may consider this a nice feature, for me this is an= enormous bug. A great way toward code obfuscation. I like D among other re= asons because it's rather clear compared to other languages of the family. = There should be no automagic constructor call (at least in this case, when = the type is not even mentionned on the caller side). This may even lead to very naughty bugs. And what if Foo has subtypes, and = the one actually invoked is the one intended by the user? Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.comOooh. That cought me off guard, sorry. =20 Thanks Steve. =20=20 I'll concede that the syntax can be odd at first, but it also enables some interesting things. For example, this works: =20 class Foo { this (int i, double f) { /*...*/ } /*...*/ } =20 void someFunc ( Foo foo ... ) { /*...*/ } =20 someFunc( 5, 3.14 ); =20 Basically, given a class (and I think struct's work as well) as the variadic type, it will accept either an instance of said class, or any combination of values which can be mapped to a constructor of that class. It can be convenient sometimes.
Dec 23 2010
spir:While I understand some may consider this a nice feature, for me this is an enormous bug. A great way toward code obfuscation. I like D among other reasons because it's rather clear compared to other languages of the family.The main problem here is that I have never felt the need of that feature, so for me it's useless. Has Walter added it after a good number of people have asked for this feature? Has any one here needed it? Bye, bearophile
Dec 23 2010
On 12/23/10, bearophile <bearophileHUGS lycos.com> wrote:spir:You should probably ask in d-general. It looks like a dangerous feature to have. If you have that function laying in another imported module you might not even realize that you're constructing an object. Consider this: void test(int x, int y, string z); // your module which you accidentally forgot to import void test(int x, Foo f ...); // some other module that *is* imported test(1, 4, "def"); // calling site that constructs a Foo object Maybe it takes more typing, but I prefer this: test(1, new Foo(4, "def")); It's explicit and you can reason about it without having to inspect other modules.While I understand some may consider this a nice feature, for me this is an enormous bug. A great way toward code obfuscation. I like D among other reasons because it's rather clear compared to other languages of the family.The main problem here is that I have never felt the need of that feature, so for me it's useless. Has Walter added it after a good number of people have asked for this feature? Has any one here needed it? Bye, bearophile
Dec 23 2010
bearophile wrote:spir:I'm almost certain that the behaviour is not intentional.While I understand some may consider this a nice feature, for me this is an enormous bug. A great way toward code obfuscation. I like D among other reasons because it's rather clear compared to other languages of the family.The main problem here is that I have never felt the need of that feature, so for me it's useless. Has Walter added it after a good number of people have asked for this feature? Has any one here needed it? Bye, bearophile
Dec 23 2010
On Thu, 23 Dec 2010 12:34:45 -0500, Don <nospam nospam.com> wrote:bearophile wrote:From http://www.digitalmars.com/d/2.0/function.html : "Typesafe variadic functions are used when the variable argument portion of the arguments are used to construct an array >>>> or class object <<<<." (emphasis added) And it goes on to show a similar example as to what has been discussed here. I think it's intentional, and I agree that I've never used or thought "gee, I wish D did this". I wouldn't be sorry to see it go. In fact, I'd advocate for getting rid of it. It creates a hidden allocation, which I'm very much against. -Stevespir:I'm almost certain that the behaviour is not intentional.While I understand some may consider this a nice feature, for me this is an enormous bug. A great way toward code obfuscation. I like D among other reasons because it's rather clear compared to other languages of the family.The main problem here is that I have never felt the need of that feature, so for me it's useless. Has Walter added it after a good number of people have asked for this feature? Has any one here needed it? Bye, bearophile
Dec 23 2010
On Thu, 23 Dec 2010 13:38:30 -0500 "Steven Schveighoffer" <schveiguy yahoo.com> wrote:I think it's intentional, and I agree that I've never used or thought =20 "gee, I wish D did this". I wouldn't be sorry to see it go. In fact, I'=d =20advocate for getting rid of it. It creates a hidden allocation, which I'=m =20very much against.Agreed. Not only hidden allocation, but the "feature" may be unintentionall= y used, leading to hard-to-find bugs. There should never by (user) type ins= tanciation without explicite mention of the type (if only on the left side = of an assignment). Surprise --> bugs. Denis - -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Dec 23 2010
On Thu, 23 Dec 2010 14:51:02 -0500, spir <denis.spir gmail.com> wrote:On Thu, 23 Dec 2010 13:38:30 -0500 "Steven Schveighoffer" <schveiguy yahoo.com> wrote:To drive the point home, we can examine the problem that typesafe variadic args solves. Take an array example. If we didn't have typesafe variadic args for arrays, this code: void foo(int[] args...); foo(1, 2, 3); would become: void foo(int[] args); int[3] x; x[0] = 1; x[1] = 2; x[2] = 3; foo(x[]); Not so nice. Almost the same issue for a typesafe variadic with fixed-sized arrays. Now, let's look at the same thing for a class: class C { this(int i, string s); } void foo(C arg...); foo(1, "hi"); And the code without typesafe variadics: void foo(C arg); foo(new C(1, "hi")); Not a lot different, we have just basically shown that you are doing an allocation (which is a good thing to show). Going even further, we can even do this: void foo(int i, string s) { foo(new C(i, s)); } And then we get *exactly* the same api. This feature brings absolutely nothing to the table IMO. -SteveI think it's intentional, and I agree that I've never used or thought "gee, I wish D did this". I wouldn't be sorry to see it go. In fact, I'd advocate for getting rid of it. It creates a hidden allocation, which I'm very much against.Agreed. Not only hidden allocation, but the "feature" may be unintentionally used, leading to hard-to-find bugs. There should never by (user) type instanciation without explicite mention of the type (if only on the left side of an assignment). Surprise --> bugs.
Dec 23 2010
Steven Schveighoffer:This feature brings absolutely nothing to the table IMO.Added as issue 5368. Bye, bearophile
Dec 24 2010