digitalmars.D - What is the stance on partial initializers when declaring multiple
- Andrej Mitrovic (15/15) Jul 20 2011 I ran into this simple C declaration:
- Jacob Carlborg (5/10) Jul 21 2011 How about you create a new type, that can be implicitly converted to
- Andrej Mitrovic (3/5) Jul 21 2011 Ha, never thought about that! When I think about it, most of the time
- Trass3r (3/8) Jul 22 2011 me too!
- Jonathan M Davis (7/18) Jul 22 2011 Well, the idea with default initializers is that they're as close as pos...
- Andrej Mitrovic (12/14) Jul 22 2011 Maybe if you're coming from C or C++ you're used to having to manually
- Nick Sabalausky (18/33) Jul 21 2011 It's an interesting point.
- Andrej Mitrovic (10/10) Jul 21 2011 Well I don't know about special syntaxes.
- Simen Kjaeraas (9/19) Jul 21 2011 I like this. It might not be a common bug, and D has reasonable enough
- bearophile (4/7) Jul 21 2011 I'd like some syntax sugar for tuples in D (especially for their unpacki...
- Simen Kjaeraas (13/20) Jul 21 2011 It is highly unlikely that D will ever adopt that syntax for tuples,
- Andrei Alexandrescu (4/21) Jul 21 2011 Here's a crazy idea:
- Simen Kjaeraas (5/28) Jul 21 2011 Ooh, shiny. I bet I could implement that in the language as-is.
- Jonathan M Davis (19/43) Jul 21 2011 Is this particular case, a built-in syntax buys you nothing, as you
- Simen Kjaeraas (33/65) Jul 21 2011 Ten minutes of hacking later:
- bearophile (6/10) Jul 21 2011 See my other answer. Beside being long and ugly, it doesn't define the t...
- Simen Kjaeraas (52/68) Jul 21 2011 Yeah, I can absolutely see that there are places where this could not
- Jacob Carlborg (5/13) Jul 22 2011 Now that is a syntax I would like to see in D. This would be even better...
- Jacob Carlborg (4/28) Jul 22 2011 That would be really nice.
- Timon Gehr (6/9) Jul 22 2011 Actually -> is not built-in, but in the library too.
- Andrei Alexandrescu (8/74) Jul 21 2011 A similar method was proposed by a Phobos contributor (Shoo I think?) at...
- Andrei Alexandrescu (6/37) Jul 21 2011 scatter(tuple(5, 2.2), i, f);
- kenji hara (7/55) Jul 22 2011 I have posted a pull request for expanding alias this tuples somewhere.
- Andrei Alexandrescu (21/29) Jul 22 2011 Great! I made a comment on
- bearophile (15/36) Jul 22 2011 I have partially lost my grasp on this thread, but this seems what I was...
- Andrei Alexandrescu (5/10) Jul 22 2011 This is a bit risky as foreach (x, name; somepairs) would mean something...
- bearophile (17/23) Jul 22 2011 That's unfortunate.
- kenji hara (11/54) Jul 22 2011 In current D, following code is valid.
- bearophile (39/50) Jul 21 2011 I was the one to suggest this syntax. Andrei told me this is named banan...
- kenji hara (38/88) Jul 22 2011 I have posted a pull request for library tuple (=3D alias this tuple)
- Jacob Carlborg (7/35) Jul 22 2011 Cool. But it's quite inconsistent that assignment requires "seq" and
- kenji hara (6/10) Jul 22 2011 Yes it is inconsistent, but I think it is not big problem.
- Jacob Carlborg (4/15) Jul 22 2011 Ok, I see.
- Jonathan M Davis (19/37) Jul 23 2011 The values which were chosen for default initialization were specificall...
I ran into this simple C declaration: float float_x, float_y, float_xb, float_yb; These need to be explicitly initialized in D, otherwise you either get crashes or you won't get anything but a blank screen (with regards to rendering with OpenGL). Almost instinctively I went for: float float_x, float_y, float_xb, float_yb = 0.0; But that's incorrect, only float_yb is zero-initialized, the others are initialized to NaN (well I predicted that but I was kinda hoping D would be cool and use a common initializer). What I'm asking is, are partial initializers useful for people? I'm not suggesting any changes, but just starting a discussion. It does look like this could maybe introduce bugs. I think someone might have mentioned this topic before, but I don't recall. Here's to a healthy discussion..
Jul 20 2011
On 2011-07-21 08:52, Andrej Mitrovic wrote:I ran into this simple C declaration: float float_x, float_y, float_xb, float_yb; These need to be explicitly initialized in D, otherwise you either get crashes or you won't get anything but a blank screen (with regards to rendering with OpenGL).How about you create a new type, that can be implicitly converted to float and is initialized to 0.0. -- /Jacob Carlborg
Jul 21 2011
On 7/21/11, Jacob Carlborg <doob me.com> wrote:How about you create a new type, that can be implicitly converted to float and is initialized to 0.0.Ha, never thought about that! When I think about it, most of the time I want my floats to be 0-initialized.
Jul 21 2011
Am 21.07.2011, 21:55 Uhr, schrieb Andrej Mitrovic <andrej.mitrovich gmail.com>:On 7/21/11, Jacob Carlborg <doob me.com> wrote:me too!How about you create a new type, that can be implicitly converted to float and is initialized to 0.0.Ha, never thought about that! When I think about it, most of the time I want my floats to be 0-initialized.
Jul 22 2011
On Friday 22 July 2011 15:40:00 Trass3r wrote:Am 21.07.2011, 21:55 Uhr, schrieb Andrej Mitrovic <andrej.mitrovich gmail.com>:Well, the idea with default initializers is that they're as close as possible to an invalid value (hence NaN for floats) so that it becomes apparent faster if you screwed up and didn't initialize them before using them. So, that's why floats aren't 0 by default. Integral values wouldn't be 0 either if the integral types had something akin to NaN. - Jonathan M DavisOn 7/21/11, Jacob Carlborg <doob me.com> wrote:me too!How about you create a new type, that can be implicitly converted to float and is initialized to 0.0.Ha, never thought about that! When I think about it, most of the time I want my floats to be 0-initialized.
Jul 22 2011
On 7/22/11, Jonathan M Davis <jmdavisProg gmx.com> wrote:Integral values wouldn't be 0 either if the integral types had something akin to NaN.Maybe if you're coming from C or C++ you're used to having to manually initialize everything. I personally don't think the issue is about putting a variable in a known invalid state, but just about putting it in a known state to begin with. And you don't get either of those in C and C++. I think 0 for integrals as a default is a great feature. It is a *known* feature, and it's pretty much what I want in 99% of my code. I only ever have to manually specify initializers in very few places for integrals, which saves me a lot of time. Remember, D cares about usability as much as it cares about memory safety. 0 for integrals is a time-saving feature.
Jul 22 2011
"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message news:mailman.1826.1311231133.14074.digitalmars-d puremagic.com...I ran into this simple C declaration: float float_x, float_y, float_xb, float_yb; These need to be explicitly initialized in D, otherwise you either get crashes or you won't get anything but a blank screen (with regards to rendering with OpenGL). Almost instinctively I went for: float float_x, float_y, float_xb, float_yb = 0.0; But that's incorrect, only float_yb is zero-initialized, the others are initialized to NaN (well I predicted that but I was kinda hoping D would be cool and use a common initializer). What I'm asking is, are partial initializers useful for people? I'm not suggesting any changes, but just starting a discussion. It does look like this could maybe introduce bugs. I think someone might have mentioned this topic before, but I don't recall. Here's to a healthy discussion..It's an interesting point. I find that I rarely declare more than one variable in a single statement. But if I were to do so, then most likely they would be such similar variables that I likely would want them inited to the same value. Can't think of a good syntax for it though. "float a, b, c = 0.0;" definitely makes it look like you're only trying init 'c'. But this is an interesting inconsistency between assignments and initializations. I mean, it's trivial to *assign* multiple variables to the same value: a = b = c = 0.0; *Normally* the only syntactical difference between assignment and initialization is whether or not "x=y;" is preceeded by a type. But with multiple assignments as above, there's no initialization equivalent to that. Crazy, nutty, wacky idea... float (a, b, c) = 0.0; ...?
Jul 21 2011
Well I don't know about special syntaxes. What I might have overheard was that if you do initialize in the declaration, the compiler might request that you specify initializers for all the variables. In other words: float x, y, z = 0.0; // error float x = 0.0, y = 0.0, z = 0.0; // ok But I don't know, this could be waay too intrusive from a low-level language. I think I saw someone mention they would like partial initializers to go away. I'm so-so with the idea, it could be too much trouble for any gain.
Jul 21 2011
On Thu, 21 Jul 2011 23:34:59 +0200, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Well I don't know about special syntaxes. What I might have overheard was that if you do initialize in the declaration, the compiler might request that you specify initializers for all the variables. In other words: float x, y, z = 0.0; // error float x = 0.0, y = 0.0, z = 0.0; // ok But I don't know, this could be waay too intrusive from a low-level language. I think I saw someone mention they would like partial initializers to go away. I'm so-so with the idea, it could be too much trouble for any gain.I like this. It might not be a common bug, and D has reasonable enough defaults that it's not unlikely you will notice the problem soon, but it has a very simple workaround (declare variables on more than one line) and gives a very clear indication of what might be wrong. Votes++; -- Simen
Jul 21 2011
Nick Sabalausky:Crazy, nutty, wacky idea... float (a, b, c) = 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea. Bye, bearophile
Jul 21 2011
On Thu, 21 Jul 2011 23:40:08 +0200, bearophile <bearophileHUGS lycos.com> wrote:Nick Sabalausky:It is highly unlikely that D will ever adopt that syntax for tuples, due to the previously much-discussed comma operator (which, while uncommon, is useful at times). I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo = (| 1.2, "Eh, whut?" |); (do note that I enjoy a wide variety of toppings on my burgers :p) Even if the comma operator were removed and that syntax used for tuples, Nick's suggested syntax would not cause ambiguities. -- SimenCrazy, nutty, wacky idea... float (a, b, c) = 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea.
Jul 21 2011
On 7/21/11 6:44 PM, Simen Kjaeraas wrote:On Thu, 21 Jul 2011 23:40:08 +0200, bearophile <bearophileHUGS lycos.com> wrote:Here's a crazy idea: auto foo = tuple(1.2, "Eh, whut?"); AndreiNick Sabalausky:It is highly unlikely that D will ever adopt that syntax for tuples, due to the previously much-discussed comma operator (which, while uncommon, is useful at times). I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo = (| 1.2, "Eh, whut?" |);Crazy, nutty, wacky idea... float (a, b, c) = 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea.
Jul 21 2011
On Fri, 22 Jul 2011 01:54:23 +0200, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 7/21/11 6:44 PM, Simen Kjaeraas wrote:Ooh, shiny. I bet I could implement that in the language as-is. -- SimenOn Thu, 21 Jul 2011 23:40:08 +0200, bearophile <bearophileHUGS lycos.com> wrote:Here's a crazy idea: auto foo = tuple(1.2, "Eh, whut?");Nick Sabalausky:It is highly unlikely that D will ever adopt that syntax for tuples, due to the previously much-discussed comma operator (which, while uncommon, is useful at times). I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo = (| 1.2, "Eh, whut?" |);Crazy, nutty, wacky idea... float (a, b, c) = 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea.
Jul 21 2011
On 2011-07-21 16:54, Andrei Alexandrescu wrote:On 7/21/11 6:44 PM, Simen Kjaeraas wrote:Is this particular case, a built-in syntax buys you nothing, as you demonstrate. I think that the case that Bearophile is always looking for is something like this: int i; float f; (i, f) = tuple(5, 2.2); though that's more useful when the function is something fancier than tuple which just so happens to return a tuple (as opposed to being specifically designed just for creating them). How useful that really is ultimately, I don't know, but it certainly adds something which you can't do without changes to the language itself. Aside from assigning the pieces of a returned tuple to existing local variables like that, I'm not aware of any real gain from adding tuples directly to the language. Our template solution works quite well overall. And whether assigning to existing local variables like above actually makes adding tuples to the language itself worth it is certainly up for debate. But I believe that that's the use case that Bearophile is particularly interested in. - Jonathan M DavisOn Thu, 21 Jul 2011 23:40:08 +0200, bearophile <bearophileHUGS lycos.com> wrote:Here's a crazy idea: auto foo = tuple(1.2, "Eh, whut?");Nick Sabalausky:It is highly unlikely that D will ever adopt that syntax for tuples, due to the previously much-discussed comma operator (which, while uncommon, is useful at times). I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo = (| 1.2, "Eh, whut?" |);Crazy, nutty, wacky idea... float (a, b, c) = 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea.
Jul 21 2011
On Fri, 22 Jul 2011 02:06:48 +0200, Jonathan M Davis <jmdavisProg gmx.com> wrote:On 2011-07-21 16:54, Andrei Alexandrescu wrote:Ten minutes of hacking later: /////////////////////////////////////// import std.typecons; import std.typetuple; template getType( alias A ) { alias typeof( A ) getType; } template getType( T ) { alias T getType; } property auto unpack( T... )( Tuple!( staticMap!( getType, T ) ) args ) { foreach ( i, e; T ) { T[i] = args.field[i]; } } unittest { int n; string s; unpack!(n,s) = tuple(4, "O HAI"); assert(n == 4); assert(s == "O HAI"); } //////////////////////////////////////////// Please note that this is not heavily tested, and will likely fail under some (read: many) circumstances. Adding some more magic, one could probably do things like: int n; unpack!(UNUSED, n, UNUSED) = tuple("foo", 4, "bar"); -- SimenOn 7/21/11 6:44 PM, Simen Kjaeraas wrote:Is this particular case, a built-in syntax buys you nothing, as you demonstrate. I think that the case that Bearophile is always looking for is something like this: int i; float f; (i, f) = tuple(5, 2.2);On Thu, 21 Jul 2011 23:40:08 +0200, bearophile <bearophileHUGS lycos.com> wrote:Here's a crazy idea: auto foo = tuple(1.2, "Eh, whut?");Nick Sabalausky:It is highly unlikely that D will ever adopt that syntax for tuples, due to the previously much-discussed comma operator (which, while uncommon, is useful at times). I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo = (| 1.2, "Eh, whut?" |);Crazy, nutty, wacky idea... float (a, b, c) = 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea.
Jul 21 2011
Simen Kjaeraas:int n; string s; unpack!(n,s) = tuple(4, "O HAI");See my other answer. Beside being long and ugly, it doesn't define the types too. And you can't use it in foreach. In my opinion a tuple syntax is more important than having built-in associative arrays. This means I'd like to remove D built-in associative arrays and replace them with built-in tuples. Tuples are more commonly useful than associative arrays, and in D there are enough ways to design a good enough library-defined AA. The only problem are AA literals, but a bit of sugar can solve this problem too. In Scala associative arrays look good enough and they are fully in the library. There is just a -> built-in syntax to define 2-tuples, used to create AA literals. Bye, bearophile
Jul 21 2011
On Fri, 22 Jul 2011 02:50:52 +0200, bearophile <bearophileHUGS lycos.com> wrote:Simen Kjaeraas:Yeah, I can absolutely see that there are places where this could not reasonably be used. Initializing const and immutable data definitely is one. And being able to use it in a foreach would be very nice. Something that might take us part of the way, at least, would be for alias this to support typetuples. Thus: struct Tuple(T...) { T fields; alias fields this; } void foo(int n, string s) {} foo(tuple(3, "bar")); would work. Foreach would direcly benefit from this: foreach (x, y; zip([1,2,3], "abc")) {} // Look ma! No bananas!int n; string s; unpack!(n,s) = tuple(4, "O HAI");See my other answer. Beside being long and ugly, it doesn't define the types too. And you can't use it in foreach.In my opinion a tuple syntax is more important than having built-in associative arrays. This means I'd like to remove D built-in associative arrays and replace them with built-in tuples. Tuples are more commonly useful than associative arrays, and in D there are enough ways to design a good enough library-defined AA. The only problem are AA literals, but a bit of sugar can solve this problem too. In Scala associative arrays look good enough and they are fully in the library. There is just a -> built-in syntax to define 2-tuples, used to create AA literals.this could work today, given a proper constructor: int[string] foo = [ tuple("a", 1), tuple("b", 19), tuple("c", -3), ]; or: auto foo = AA([ tuple("a", 1), tuple("b", 19), tuple("c", -3), ]); Or, if we go bananas: int[string] foo = [ (|"a", 1|), (|"b", 19|), (|"c", -3|), ]; I agree that a shorter syntax for 2-tuples could be beneficial, and certainly may make more people use it (also, the -> arrow is not taken yet): auto foo = AA([ "a" -> 1, "b" -> 19, "c" -> -3, ]); As for actual typing, 5 characters are saved per line for the tersest version, and only 3 with bananas. Not enough that I'm convinced by that argument alone, but the more natural feel of the -> syntax has me intrigued. (these numbers would also be somewhat different if I weren't nazi about my spaces) This is not just about what can be done, but also how to make users actually use the features. I believe, but do not know, that many users would feel more comfortable with the latter syntax than the one saying tuple all the time. -- Simen
Jul 21 2011
On 2011-07-22 03:29, Simen Kjaeraas wrote:I agree that a shorter syntax for 2-tuples could be beneficial, and certainly may make more people use it (also, the -> arrow is not taken yet): auto foo = AA([ "a" -> 1, "b" -> 19, "c" -> -3, ]);Now that is a syntax I would like to see in D. This would be even better: auto foo = "a" -> 1, "b" -> 19, "c" -> -3; -- /Jacob Carlborg
Jul 22 2011
On 2011-07-22 03:29, Simen Kjaeraas wrote:On Fri, 22 Jul 2011 02:50:52 +0200, bearophile <bearophileHUGS lycos.com> wrote:That would be really nice. -- /Jacob CarlborgSimen Kjaeraas:Yeah, I can absolutely see that there are places where this could not reasonably be used. Initializing const and immutable data definitely is one. And being able to use it in a foreach would be very nice. Something that might take us part of the way, at least, would be for alias this to support typetuples. Thus: struct Tuple(T...) { T fields; alias fields this; } void foo(int n, string s) {} foo(tuple(3, "bar")); would work. Foreach would direcly benefit from this: foreach (x, y; zip([1,2,3], "abc")) {} // Look ma! No bananas!int n; string s; unpack!(n,s) = tuple(4, "O HAI");See my other answer. Beside being long and ugly, it doesn't define the types too. And you can't use it in foreach.
Jul 22 2011
bearophile wrote:In Scala associative arrays look good enough and they are fully in the library. There is just a -> built-in syntax to define 2-tuples, used to create AA literals.Actually -> is not built-in, but in the library too. As a consequence, -> has the same precedence as + and -. 1*1 -> 2*2 works, but 1+1 -> (2+2) requires parentheses. Cheers, -Timon
Jul 22 2011
On 7/21/11 7:27 PM, Simen Kjaeraas wrote:On Fri, 22 Jul 2011 02:06:48 +0200, Jonathan M Davis <jmdavisProg gmx.com> wrote:A similar method was proposed by a Phobos contributor (Shoo I think?) at a point under a different name. I rejected it because it was difficult to make safe (it saved the addresses of its arguments). Yours is safe though, but doesn't allow expressions e.g. unpack!(a[0], a[1]) = tuple(1, 1); It's an interesting idea though. AndreiOn 2011-07-21 16:54, Andrei Alexandrescu wrote:Ten minutes of hacking later: /////////////////////////////////////// import std.typecons; import std.typetuple; template getType( alias A ) { alias typeof( A ) getType; } template getType( T ) { alias T getType; } property auto unpack( T... )( Tuple!( staticMap!( getType, T ) ) args ) { foreach ( i, e; T ) { T[i] = args.field[i]; } } unittest { int n; string s; unpack!(n,s) = tuple(4, "O HAI"); assert(n == 4); assert(s == "O HAI"); } //////////////////////////////////////////// Please note that this is not heavily tested, and will likely fail under some (read: many) circumstances. Adding some more magic, one could probably do things like: int n; unpack!(UNUSED, n, UNUSED) = tuple("foo", 4, "bar");On 7/21/11 6:44 PM, Simen Kjaeraas wrote:Is this particular case, a built-in syntax buys you nothing, as you demonstrate. I think that the case that Bearophile is always looking for is something like this: int i; float f; (i, f) = tuple(5, 2.2);On Thu, 21 Jul 2011 23:40:08 +0200, bearophile <bearophileHUGS lycos.com> wrote:Here's a crazy idea: auto foo = tuple(1.2, "Eh, whut?");Nick Sabalausky:It is highly unlikely that D will ever adopt that syntax for tuples, due to the previously much-discussed comma operator (which, while uncommon, is useful at times). I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo = (| 1.2, "Eh, whut?" |);Crazy, nutty, wacky idea... float (a, b, c) = 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea.
Jul 21 2011
On 7/21/11 7:06 PM, Jonathan M Davis wrote:On 2011-07-21 16:54, Andrei Alexandrescu wrote:scatter(tuple(5, 2.2), i, f); The more difficult construct is: auto (i, f) = tuple(5, 2.2); Walter and I discussed a language change to allow that. AndreiOn 7/21/11 6:44 PM, Simen Kjaeraas wrote:Is this particular case, a built-in syntax buys you nothing, as you demonstrate. I think that the case that Bearophile is always looking for is something like this: int i; float f; (i, f) = tuple(5, 2.2);On Thu, 21 Jul 2011 23:40:08 +0200, bearophile <bearophileHUGS lycos.com> wrote:Here's a crazy idea: auto foo = tuple(1.2, "Eh, whut?");Nick Sabalausky:It is highly unlikely that D will ever adopt that syntax for tuples, due to the previously much-discussed comma operator (which, while uncommon, is useful at times). I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo = (| 1.2, "Eh, whut?" |);Crazy, nutty, wacky idea... float (a, b, c) = 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea.
Jul 21 2011
2011/7/22 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:On 7/21/11 7:06 PM, Jonathan M Davis wrote:I have posted a pull request for expanding alias this tuples somewhere. https://github.com/D-Programming-Language/dmd/pull/74 I think that this patch will make conversion seamlessly from built-in tuple to library tuple.On 2011-07-21 16:54, Andrei Alexandrescu wrote:scatter(tuple(5, 2.2), i, f); The more difficult construct is: auto (i, f) =3D tuple(5, 2.2); Walter and I discussed a language change to allow that. AndreiOn 7/21/11 6:44 PM, Simen Kjaeraas wrote:Is this particular case, a built-in syntax buys you nothing, as you demonstrate. I think that the case that Bearophile is always looking for is something like this: int i; float f; (i, f) =3D tuple(5, 2.2);On Thu, 21 Jul 2011 23:40:08 +0200, bearophile <bearophileHUGS lycos.com> =A0wrote:Here's a crazy idea: auto foo =3D tuple(1.2, "Eh, whut?");Nick Sabalausky:It is highly unlikely that D will ever adopt that syntax for tuples, due to the previously much-discussed comma operator (which, while uncommon, is useful at times). I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo =3D (| 1.2, "Eh, whut?" |);Crazy, nutty, wacky idea... float (a, b, c) =3D 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea.auto (i, f) =3D tuple(5, 2.2); Walter and I discussed a language change to allow that.I'd like to make patch supporting it. Kenji Hara
Jul 22 2011
On 7/22/11 4:43 AM, kenji hara wrote:2011/7/22 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>: I have posted a pull request for expanding alias this tuples somewhere. https://github.com/D-Programming-Language/dmd/pull/74Great! I made a comment on http://d.puremagic.com/issues/show_bug.cgi?id=2779, please let me know if you agree. Fixing http://d.puremagic.com/issues/show_bug.cgi?id=2781 seems fine as there's no ambiguity there.I think that this patch will make conversion seamlessly from built-in tuple to library tuple.Sounds great. The way Walter and I wanted to spec that would be as a simple syntactic rewrite. This construct: auto (a1, a2, ..., aN) = x; is expanded mechanically to: static assert(x.length == N, "Too many elements in definition"); auto a1 = x[0]; auto a2 = x[1]; ... auto aN = x[N-1]; This ensures that the feature works with statically-sized arrays and std.Tuple, but also with other types that define the required operations. There's no special casing of library artifacts. If x is an expression, it must be evaluated only once. Let's discuss things here and hear from Walter before you embark on doing this. Andreiauto (i, f) = tuple(5, 2.2); Walter and I discussed a language change to allow that.I'd like to make patch supporting it.
Jul 22 2011
Andrei:Sounds great. The way Walter and I wanted to spec that would be as a simple syntactic rewrite. This construct: auto (a1, a2, ..., aN) = x; is expanded mechanically to: static assert(x.length == N, "Too many elements in definition"); auto a1 = x[0]; auto a2 = x[1]; ... auto aN = x[N-1]; This ensures that the feature works with statically-sized arrays and std.Tuple, but also with other types that define the required operations. There's no special casing of library artifacts. If x is an expression, it must be evaluated only once. Let's discuss things here and hear from Walter before you embark on doing this.I have partially lost my grasp on this thread, but this seems what I was asking for. Plus making the syntax work for fixed sized arrays too (and similar user defined types) is good. I sometimes use 2-array or 3-array to return data by value when they are of the same type. Two questions: is typed unpacking too supported? (int a1, float a2, auto a3) = sometuple; Is unpaking inside foreach too supposed to work? This is quite useful: auto somepairs = [tuple(1, "foo"), tuple(10, "bar")]; foreach ((x, name); somepairs) {} ----------- In Haskell you are allowed to call a function with a tuple, and give a local name to the tuple items: somefunction (item1, item2) and to optionally give a name to the whole tuple too: somefunction tuplename (item1, item2) This is sometimes handy, but I think it's currently overkill in D (and it's an additive change). Bye, bearophile
Jul 22 2011
On 7/22/11 12:32 PM, bearophile wrote:Two questions: is typed unpacking too supported? (int a1, float a2, auto a3) = sometuple;The particular rule I suggested does not allow that.Is unpaking inside foreach too supposed to work? This is quite useful: auto somepairs = [tuple(1, "foo"), tuple(10, "bar")]; foreach ((x, name); somepairs) {}This is a bit risky as foreach (x, name; somepairs) would mean something completely different. Andrei
Jul 22 2011
Andrei:That's unfortunate. foreach(index,item;somearray) was a handy shortcut designed not thinking enough about its wider consequences :-( In Python iterables yield one item, and you are allowed to unpack items if they are composed by more than one item, and to use enumerate() to yield on (index,item) 2-tuples. Removing the optional index from iterating on both arrays and associative arrays (so you need to use something like enumerate() if you want array indexes too, and a AA.byPairs() method if you want key-value 2-tuples of AAs) probably isn't an option because it breaks too much D code. This looks a bit less bug-prone: foreach (tuple(x, name); somepairs) {} ------------------ A third place where tuple unpacking is handy is in switch statements. Supporting switching on structs allows to switch on tuples too. If you allow tuple unpacking syntax here too, you get a poor's man pattern matching, that despite being simple is probably useful. switch (sometuple) { case (0, y): ... case (x, 0): ... case (x, y): ... // no default needed, this catches all other cases } (Note: both AA.byPairs() and switch on structs are useful even if they don't get any special support for tuples.) Bye, bearophileIs unpaking inside foreach too supposed to work? This is quite useful: auto somepairs = [tuple(1, "foo"), tuple(10, "bar")]; foreach ((x, name); somepairs) {}This is a bit risky as foreach (x, name; somepairs) would mean something completely different.
Jul 22 2011
In current D, following code is valid. import std.typetuple : seq = TypeTuple; void main() { int x, y; seq!(x, y) = seq!(1, 2); // assign assert(x == 1); assert(y == 2); } Kenji Hara 2011/7/22 Jonathan M Davis <jmdavisProg gmx.com>:On 2011-07-21 16:54, Andrei Alexandrescu wrote:On 7/21/11 6:44 PM, Simen Kjaeraas wrote:Is this particular case, a built-in syntax buys you nothing, as you demonstrate. I think that the case that Bearophile is always looking for is something like this: int i; float f; (i, f) = tuple(5, 2.2); though that's more useful when the function is something fancier than tuple which just so happens to return a tuple (as opposed to being specifically designed just for creating them). How useful that really is ultimately, I don't know, but it certainly adds something which you can't do without changes to the language itself. Aside from assigning the pieces of a returned tuple to existing local variables like that, I'm not aware of any real gain from adding tuples directly to the language. Our template solution works quite well overall. And whether assigning to existing local variables like above actually makes adding tuples to the language itself worth it is certainly up for debate. But I believe that that's the use case that Bearophile is particularly interested in. - Jonathan M DavisOn Thu, 21 Jul 2011 23:40:08 +0200, bearophile <bearophileHUGS lycos.com> wrote:Here's a crazy idea: auto foo = tuple(1.2, "Eh, whut?");Nick Sabalausky:It is highly unlikely that D will ever adopt that syntax for tuples, due to the previously much-discussed comma operator (which, while uncommon, is useful at times). I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo = (| 1.2, "Eh, whut?" |);Crazy, nutty, wacky idea... float (a, b, c) = 0.0;I'd like some syntax sugar for tuples in D (especially for their unpacking), that syntax goes against one of the most natural ways to define tuples. So it's not a good idea.
Jul 22 2011
Simen Kjaeraas:I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo = (| 1.2, "Eh, whut?" |);I was the one to suggest this syntax. Andrei told me this is named banana syntax. There are also alternatives: (| auto f, auto s |) foo = (| 1.2, "Eh, whut?" |); auto (| f, s |) foo = (| 1.2, "Eh, whut?" |);Even if the comma operator were removed and that syntax used for tuples, Nick's suggested syntax would not cause ambiguities.I like the banana syntax, but I think some people don't like it. So as second choice there is a Python-style tuple syntax. ----------------- Andrei:Here's a crazy idea: auto foo = tuple(1.2, "Eh, whut?");This was in my original answer:(especially for their unpacking),<The main point of having some tuple syntax sugar is to allow a good enough unpacking. Currently it's not good enough for a language as D that wants to be functional too. Functional languages use tuples often. If you are also able to improve the literals too, then it's even better. A return tuple is better than ref/out arguments, as used in C/C++ languages. It's simpler to read because it's easy to see it's the result of a function. Even Go language, that is otherwise quite minimal, has multiple return values. An example usage: http://rosettacode.org/wiki/Sokoban#D The C++0x version: vector<vector<char>> temp, cur = get<0>(open.front()); string cSol = get<1>(open.front()); int x = get<2>(open.front()); int y = get<3>(open.front()); open.pop(); D2 versione with Tuple: auto item = open.pop(); CTable cur = item[0]; string cSol = item[1]; const int x = item[2]; const int y = item[3]; Python version: cur, csol, x, y = open.popleft() One possible D syntax: const (|cur, cSol, x, y|) = open.pop(); Some tuple unpacking syntax in D is useful in D. There are other useful purposes, like unpacking in foreach: foreach ((|x, y|); zip([1, 2, 3], "abc") {} Python3 shows more syntax, to unpack only the first items of a tuple, but this is less important than a basic unpacking syntax: foo(): return 1, 2, 3, 4 a, b, *somemore = foo() Bye, bearophile
Jul 21 2011
I have posted a pull request for library tuple (=3D alias this tuple) unpacking somewhere: https://github.com/D-Programming-Language/dmd/pull/74 (Test code) https://github.com/D-Programming-Language/dmd/pull/74/files#L7R= 130 This patch allows unpacking tuple following places: - Non-template function arguments - Template function arguments - StructLiteral arguments - Initializer - foreach aggregate - foreach range.front And I think make enhancement patch allowing tuple declaration like follows: auto (i, s) =3D tuple(1, "str"); TypeTuple!(string, int[]) (s, arr) =3D TypeTuple!("str", [1, 2]); Syntax: ("auto" | TupleTypeName) "(" Identifier ["," Identifier ...] ")" "=3D" Initializer ";" Tuple assignment is already supported in current D like follows: import std.typetuple : seq =3D TypeTuple; void main() { int x, y; seq!(x, y) =3D seq!(1, 2); // aassign assert(x =3D=3D 1); assert(y =3D=3D 2); } I think more language support for tuple assignment is not need. Kenji Hara 2011/7/22 bearophile <bearophileHUGS lycos.com>:Simen Kjaeraas:syntax.I believe the syntax that came out on top in earlier discussions was the upended hamburger bun, or banana syntax: (| float f, string s |) foo =3D (| 1.2, "Eh, whut?" |);I was the one to suggest this syntax. Andrei told me this is named banana=There are also alternatives: (| auto f, auto s |) foo =3D (| 1.2, "Eh, whut?" |); auto (| f, s |) foo =3D (| 1.2, "Eh, whut?" |);cond choice there is a Python-style tuple syntax.Even if the comma operator were removed and that syntax used for tuples, Nick's suggested syntax would not cause ambiguities.I like the banana syntax, but I think some people don't like it. So as se=----------------- Andrei:h unpacking. Currently it's not good enough for a language as D that wants = to be functional too. Functional languages use tuples often.Here's a crazy idea: auto foo =3D tuple(1.2, "Eh, whut?");This was in my original answer:(especially for their unpacking),<The main point of having some tuple syntax sugar is to allow a good enoug=If you are also able to improve the literals too, then it's even better. A return tuple is better than ref/out arguments, as used in C/C++ languag=es. It's simpler to read because it's easy to see it's the result of a func= tion. Even Go language, that is otherwise quite minimal, has multiple retur= n values.An example usage: http://rosettacode.org/wiki/Sokoban#D The C++0x version: vector<vector<char>> temp, cur =3D get<0>(open.front()); string cSol =3D get<1>(open.front()); int x =3D get<2>(open.front()); int y =3D get<3>(open.front()); open.pop(); D2 versione with Tuple: auto item =3D open.pop(); CTable cur =3D item[0]; string cSol =3D item[1]; const int x =3D item[2]; const int y =3D item[3]; Python version: cur, csol, x, y =3D open.popleft() One possible D syntax: const (|cur, cSol, x, y|) =3D open.pop(); Some tuple unpacking syntax in D is useful in D. There are other useful purposes, like unpacking in foreach: foreach ((|x, y|); zip([1, 2, 3], "abc") {} Python3 shows more syntax, to unpack only the first items of a tuple, but=this is less important than a basic unpacking syntax:foo(): =A0 =A0return 1, 2, 3, 4 a, b, *somemore =3D foo() Bye, bearophile
Jul 22 2011
On 2011-07-22 11:56, kenji hara wrote:I have posted a pull request for library tuple (= alias this tuple) unpacking somewhere: https://github.com/D-Programming-Language/dmd/pull/74 (Test code) https://github.com/D-Programming-Language/dmd/pull/74/files#L7R130 This patch allows unpacking tuple following places: - Non-template function arguments - Template function arguments - StructLiteral arguments - Initializer - foreach aggregate - foreach range.front And I think make enhancement patch allowing tuple declaration like follows: auto (i, s) = tuple(1, "str"); TypeTuple!(string, int[]) (s, arr) = TypeTuple!("str", [1, 2]); Syntax: ("auto" | TupleTypeName) "(" Identifier ["," Identifier ...] ")" "=" Initializer ";" Tuple assignment is already supported in current D like follows: import std.typetuple : seq = TypeTuple; void main() { int x, y; seq!(x, y) = seq!(1, 2); // aassign assert(x == 1); assert(y == 2); } I think more language support for tuple assignment is not need. Kenji HaraCool. But it's quite inconsistent that assignment requires "seq" and declaration doesn't. (x, y) = seq!(1, 2); Would it be possible to allow the above syntax? -- /Jacob Carlborg
Jul 22 2011
2011/7/22 Jacob Carlborg <doob me.com>:Cool. But it's quite inconsistent that assignment requires "seq" and declaration doesn't.Yes it is inconsistent, but I think it is not big problem. Because assignment for reusing variables is not good way. It is not 'functional', need 'side-effect', so(x, y) = seq!(1, 2); Would it be possible to allow the above syntax?it seems to me that supporting above syntax is not worth changing grammar cost. Kenji Hara
Jul 22 2011
On 2011-07-22 15:37, kenji hara wrote:2011/7/22 Jacob Carlborg<doob me.com>:Ok, I see. -- /Jacob CarlborgCool. But it's quite inconsistent that assignment requires "seq" and declaration doesn't.Yes it is inconsistent, but I think it is not big problem. Because assignment for reusing variables is not good way. It is not 'functional', need 'side-effect', so(x, y) = seq!(1, 2); Would it be possible to allow the above syntax?it seems to me that supporting above syntax is not worth changing grammar cost. Kenji Hara
Jul 22 2011
On Saturday 23 July 2011 07:16:07 Andrej Mitrovic wrote:On 7/22/11, Jonathan M Davis <jmdavisProg gmx.com> wrote:The values which were chosen for default initialization were specifically chose because they were the closest to an error value that each type has. In the case of integral values, there was no value which was really an error value, so 0 was chosen. Whether you rely on that or consider it good practice to always explicitly initialize variables is up to you. But it's was never really the point to avoid having to initialize variables. The point was to avoid undefined state and to make it as clear as possible what went wrong when you forgot to initialize a variable by making the default value as close to an error value as possible. So, it's perfectly legitimate to rely on the fact that integral values default to 0 and not bother to ever initialize the directly, but avoiding having to directly initialize the variable wasn't really the reason for that language design decision. Regardless, the fact that floating point values _can_ have an error value - NaN - means that you're never going to see 0 become the default value for floating point values even if most people typically initialized their floats to 0 (that and the fact that changing it at this point would break a lot of code). - Jonathan M DavisIntegral values wouldn't be 0 either if the integral types had something akin to NaN.Maybe if you're coming from C or C++ you're used to having to manually initialize everything. I personally don't think the issue is about putting a variable in a known invalid state, but just about putting it in a known state to begin with. And you don't get either of those in C and C++. I think 0 for integrals as a default is a great feature. It is a *known* feature, and it's pretty much what I want in 99% of my code. I only ever have to manually specify initializers in very few places for integrals, which saves me a lot of time. Remember, D cares about usability as much as it cares about memory safety. 0 for integrals is a time-saving feature.
Jul 23 2011