digitalmars.D - DIP32: Uniform tuple syntax
- kenji hara (2/2) Mar 29 2013 http://wiki.dlang.org/DIP32
- Dicebot (3/5) Mar 29 2013 Can't tell at the first read about possible issues, but
- Dmitry Olshansky (22/24) Mar 29 2013 A few typos like:
- kenji hara (14/31) Mar 29 2013 Because it already exists.
- angel (8/8) Mar 29 2013 Another reason to allow swapping values ( {a, b} = {b, a} ) is
- Adam D. Ruppe (7/7) Mar 29 2013 My first thought when I saw {} was json. This is getting a little
- bearophile (6/10) Mar 29 2013 I think Tuple!() has them mostly because there is no handy syntax
- Timon Gehr (4/11) Mar 29 2013 Remove the quotes and it looks like a struct literal.
- Jacob Carlborg (4/7) Mar 29 2013 I agree.
- kenji hara (10/17) Mar 29 2013 For tuple values with named fields, we need more thoughts about semantic...
- bearophile (6/8) Mar 29 2013 Tuples with named fields are records. Once we have a unpacking
- bearophile (9/18) Mar 29 2013 One solution:
- Jacob Carlborg (5/11) Mar 29 2013 I had a proposal of anonymous structs that is similar to this:
- bearophile (101/104) Mar 29 2013 Thank you Kenji for working on this :-)
- bearophile (6/8) Mar 29 2013 That was:
- =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= (11/34) Mar 29 2013 I suggest instead this syntax:
- bearophile (8/28) Mar 29 2013 Telling the language that there there is exactly one item to
- Timon Gehr (3/18) Mar 29 2013 It is already taken and equivalent to:
- Timon Gehr (2/7) Mar 29 2013 It is false.
- bearophile (9/9) Mar 29 2013 Once tuples have a built-in syntax it becomes possible to add
- kenji hara (34/116) Mar 29 2013 It will introduce a kind of "reference variable" to D.
- Zach the Mystic (2/14) Mar 30 2013 {c, ?} = tup;
- bearophile (7/17) Mar 30 2013 Right, I was forgetting that.
- timotheecour (12/28) Apr 05 2013 What about
- bearophile (5/8) Apr 05 2013 I think the question mark is better here. It's shorter and it has
- Zach the Mystic (4/12) Apr 05 2013 Not disagreeing, but you had mentioned nullable types before, and
- bearophile (12/15) Apr 06 2013 I opened this:
- Andrei Alexandrescu (4/18) Apr 06 2013 I think it's safe to close it. Nullable types have not enjoyed a lot of
- bearophile (9/11) Apr 06 2013 On the other hand they have gained appreciation in almost every
- deadalnix (3/12) Apr 06 2013 Non nullable should be the default. Compiler know know how to
- deadalnix (5/33) Apr 06 2013 In C#, all objects are already nullables, which make it not
- Maxim Fomin (13/28) Apr 06 2013 Once dmd pull 1724 is merged, it would be possible to write:
- Timon Gehr (30/32) Mar 29 2013 Looks quite nice. I especially like the {a, b} => ... thing.
- bearophile (6/8) Mar 29 2013 I have suggested to move the ... syntax to a Stage2, a different
- Timon Gehr (4/10) Mar 29 2013 No, please. Slicing should not auto-expand.
- Timon Gehr (3/8) Mar 29 2013 The outer { } are not necessary in order to make the point:
- kenji hara (31/59) Mar 29 2013 It will be parsed as:
- Timon Gehr (18/77) Mar 29 2013 There is no ';', therefore the DIP says it is a tuple brace.
- kenji hara (14/88) Mar 29 2013 Sorry my incomplete description and poor English. I'll improve descripti...
- bearophile (5/8) Mar 29 2013 This is a bad idea. It is not handy and it introduces a special
- kenji hara (14/21) Mar 29 2013 That is "explicit". In D, opened tuple (currently it's generated from
- bearophile (25/41) Mar 29 2013 I (and probably Timon) am just asking for another syntax to do
- Timon Gehr (11/32) Mar 29 2013 Because of prior language limitations, not because it makes any sense!
- Timothee Cour (10/63) Mar 30 2013 not 'open', there is already something called .expand property
- bearophile (7/10) Mar 29 2013 In the end it's not too much bad (despite my first instinct is
- Kagamin (2/6) Mar 31 2013 Should there be a difference?
- Timon Gehr (2/9) Mar 31 2013 Sure.
- bearophile (17/20) Mar 29 2013 You are right, I didn't know/remember about that:
- Timon Gehr (12/14) Mar 29 2013 One quite ugly thing about this is that function arguments will be a
- bearophile (102/109) Mar 29 2013 It's useful to switch on struct values:
- Traveler (6/8) Apr 01 2013 Why not square brackets?
- =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= (16/25) Apr 01 2013 Mostly because it already has a meaning in D, namely that of an array.
- Kagamin (4/4) Apr 01 2013 By the way, {int,int} - is it a type or a value?
- Chris Nicholson-Sauls (15/15) Apr 01 2013 Two different languages I've used in the distant past used @ for
- Jacob Carlborg (4/18) Apr 01 2013 Won't there be a conflict with UDA's?
- Chris Nicholson-Sauls (3/30) Apr 02 2013 Oh yeah, those exist. (I seriously forgot... just because I
- deadalnix (9/11) Apr 06 2013 The {} syntax is already crowded, I don't think this is wise to
- Philip Stuckey (13/15) Aug 13 2014 I'm not sure if this is off topic or redundant but couldn't many
- Dicebot (4/16) Aug 13 2014 This is already possible with standard library but the fact that
- Yota (4/26) Aug 14 2014 Brings to mind C#'s new ability to declare locals within 'out'
- bearophile (5/7) Aug 14 2014 The unpack() lacks most of the capabilities you expect and want
- Sean Kelly (11/11) Aug 14 2014 This looks really nice. I'd love to use it for std.concurrency,
- bearophile (7/11) Aug 14 2014 Elsewhere I have suggested to add to D an optional struct (and
- Jacob Carlborg (5/9) Aug 14 2014 It can be implemented as a library function. The syntax won't be as nice...
- bearophile (6/7) Aug 15 2014 It can't be implemented with a library function. You want to use
- Frustrated (2/4) Aug 15 2014 Will it allow for nested tuples? Or tuples containing lambdas?
On Friday, 29 March 2013 at 08:58:06 UTC, kenji hara wrote:http://wiki.dlang.org/DIP32 Kenji HaraCan't tell at the first read about possible issues, but conceptually - love it, fits nicely.
Mar 29 2013
29-Mar-2013 12:57, kenji hara пишет:http://wiki.dlang.org/DIP32 Kenji HaraA few typos like: {c, $} = tup; // Rewritten as: a = tup[0]; where it should be //Rewritten as c = tup[0]; About swapping values by tuple assignment. Why not simply make this work: {x, y} = {y, x} By lowering {x, y} = {y, x}; to auto temp0 = y; auto temp1 = x; x = temp0; y = temp1; And let the compiler do value propagation to remove the extra temp0. Another note - is there any way to extend this notation to common structs other then .tupleof ? I think we may hopefully extended it later towards struct destructruing a-la EcmaScript 6, see http://wiki.ecmascript.org/doku.php?id=harmony:destructuring All in all it's a great proposal, I'm loving it. -- Dmitry Olshansky
Mar 29 2013
2013/3/29 Dmitry Olshansky <dmitry.olsh gmail.com>A few typos like: {c, $} = tup; // Rewritten as: a = tup[0]; where it should be //Rewritten as c = tup[0];Thanks. Fixed.About swapping values by tuple assignment. Why not simply make this work: {x, y} = {y, x} By lowering {x, y} = {y, x}; to auto temp0 = y; auto temp1 = x; x = temp0; y = temp1; And let the compiler do value propagation to remove the extra temp0.Because it already exists. template Seq(T...) { alias Seq = T; } void main() { int x = 1, y = 2; Seq!(x, y) = Seq!(y, x); // tuple assigmnent assert(x == 2); assert(y == 2); } Another note - is there any way to extend this notation to common structsother then .tupleof ? I think we may hopefully extended it later towards struct destructruing a-la EcmaScript 6, see http://wiki.ecmascript.org/**doku.php?id=harmony:**destructuring<http://wiki.ecmascript.org/doku.php?id=harmony:destructuring>Hmm, interesting. I'll see it later. Kenji Hara
Mar 29 2013
Another reason to allow swapping values ( {a, b} = {b, a} ) is nice parallel semantics that might provide cool features on some future (or niche) parallel hardware. Think of {a, b} = {funcA(), funcB()}; Parallel semantics is able to evolve to parallel execution, which is one cool feature. In Go language it is so.
Mar 29 2013
My first thought when I saw {} was json. This is getting a little further away from tuples, but would it be hard to add named fields to this too like json: auto a = {"foo":12, "bar":"twelve"}; int a_foo = a.foo; string a_bar = a[1]; The std.typecons Tuple!() can do this kind of thing too.
Mar 29 2013
Adam D. Ruppe:auto a = {"foo":12, "bar":"twelve"}; int a_foo = a.foo; string a_bar = a[1]; The std.typecons Tuple!() can do this kind of thing too.I think Tuple!() has them mostly because there is no handy syntax to unpack them. Tuples with field names are records. Bye, bearophile
Mar 29 2013
On 03/29/2013 01:49 PM, Adam D. Ruppe wrote:My first thought when I saw {} was json. This is getting a little further away from tuples, but would it be hard to add named fields to this too like json: auto a = {"foo":12, "bar":"twelve"}; int a_foo = a.foo; string a_bar = a[1]; The std.typecons Tuple!() can do this kind of thing too.Remove the quotes and it looks like a struct literal. I think if named fields are allowed, it should look as follows: auto a = {foo: 12, bar: "twelve"};
Mar 29 2013
On 2013-03-29 14:26, Timon Gehr wrote:Remove the quotes and it looks like a struct literal. I think if named fields are allowed, it should look as follows: auto a = {foo: 12, bar: "twelve"};I agree. -- /Jacob Carlborg
Mar 29 2013
For tuple values with named fields, we need more thoughts about semantics. alias MyPair = typeof({1, "hi"}); alias MyRecord = typeof({count:1, msg:"hi"}); static assert(is(MyPair == MyRecord)); // true or false? static assert(is(MyPair : MyRecord)); // true or false? static assert(is(MyRecord : MyPair)); // true or false? alias MyStudent = typeof({num:1, name:"John"}); static assert(is(MyRecord == MyStudent)); // true or false? Kenji Hara 2013/3/29 Adam D. Ruppe <destructionator gmail.com>My first thought when I saw {} was json. This is getting a little further away from tuples, but would it be hard to add named fields to this too like json: auto a = {"foo":12, "bar":"twelve"}; int a_foo = a.foo; string a_bar = a[1]; The std.typecons Tuple!() can do this kind of thing too.
Mar 29 2013
On Friday, 29 March 2013 at 14:57:33 UTC, kenji hara wrote:For tuple values with named fields, we need more thoughts about semantics.Tuples with named fields are records. Once we have a unpacking syntax, the names become less needed. I suggest to leave field names to the Stage2. Bye, bearophile
Mar 29 2013
kenji hara:For tuple values with named fields, we need more thoughts about semantics. alias MyPair = typeof({1, "hi"}); alias MyRecord = typeof({count:1, msg:"hi"}); static assert(is(MyPair == MyRecord)); // true or false? static assert(is(MyPair : MyRecord)); // true or false? static assert(is(MyRecord : MyPair)); // true or false? alias MyStudent = typeof({num:1, name:"John"}); static assert(is(MyRecord == MyStudent)); // true or false?One solution: http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29 {count:1, "hi"} and {1, msg:"hi"} are invariant. {count:1, msg:"hi"}, {count:1, "hi"} and {1, msg:"hi"} are covariant to {1, "hi"}. But I think it's better to leave this to the Stage2. Bye, bearophile
Mar 29 2013
On 2013-03-29 13:49, Adam D. Ruppe wrote:My first thought when I saw {} was json. This is getting a little further away from tuples, but would it be hard to add named fields to this too like json: auto a = {"foo":12, "bar":"twelve"}; int a_foo = a.foo; string a_bar = a[1];I had a proposal of anonymous structs that is similar to this: http://forum.dlang.org/thread/kfbnuc$1cro$1 digitalmars.com -- /Jacob Carlborg
Mar 29 2013
kenji hara:http://wiki.dlang.org/DIP32Thank you Kenji for working on this :-) Some comments on your proposal: - - - - - - - - - - - -Use braces and commas. Inside tuple literal, ; never appears. So it will not be confused with lambdas and ScopeStatements.<This is true. On the other hand it's not too much hard to forget a ; or to not see it by mistake. So please let's think well about this important design decision. - - - - - - - - - - - - I presume this will be valid code: auto tup = {10, "hi", 3.14}; assert(tup[0..2] == {10, "hi"}); - - - - - - - - - - - - One handy tuple syntax in Haskell allows you to name both the items of a tuple and it whole: void foo(t2 {int a, string b}) { // here a and b are tuple items and t2 is the whole tuple. } auto t1 {x, y} = {10, "hi"}; foo(t1); - - - - - - - - - - - - auto tup = {}; // zero-element tuple (Syntax meaning will be changed!) Nullary tuples are not that useful in D. Scala doesn't even have a short literal for them. So a longer syntax like this is acceptable: auto tup = Tuple(); - - - - - - - - - - - - This is nice, so we are merging tuple types with tuples, this will simplify D language: // declare tuple value by using explicit tuple type {int, string} tup = {1, "hi"}; alias TL = {int, string[], double[string]}; // types But one thing to remember in the document is that here T1 and T2 are different, because your tuples do not auto-flatten as TypeTuples currently do: alias T1 = {float, double, real}; alias T2 = {float, double, {real}}; - - - - - - - - - - - - foreach (Float; {float, double, real}) { ... } I think you meant to put a variable name there. - - - - - - - - - - - - {1} // one-element tuple I presume this too will be accepted as 1-tuple: {1,} - - - - - - - - - - - - {c, $} = tup; // Rewritten as: c = tup[0]; $ is used for array lengths, so it's not so good to overload it to mean "don't care" too. Alternative syntaxes: {c, $_} = tup; {c, } = tup; {c, _} = tup; {c, $$} = tup; {c, {}} = tup; {c, {_}} = tup; {c, $~} = tup; {c, ~= tup; etc. - - - - - - - - - - - - if (auto {1, y} = tup) { // If the first element of tup (tup[0]) is equal to 1, // y captures the second element of tup (tup[1]). } I suggest to leave that pattern matching plus conditional to a future refinement of tuple implementation (a second stage. And remove it from this first stage proposal. So I suggest to split your proposal in two successive proposals). It seems handy, but D programmers need some time to go there. - - - - - - - - - - - - switch (tup) { case {1, 2}: case {$, 2}: case {1, x}: // capture tup[1] into 'x' when tup[0] == 1 default: // same as {...} } What's quite important here is the "final switch". D has to make sure you are considering all possible cases. - - - - - - - - - - - - I suggest to leave this to the second stage, and remove it from this proposal: auto tup = {1, "hi", 3.14, [1,2,3]}; if (auto {1, "hi", ...} = tup) {} - - - - - - - - - - - - "will" is written badly: // If the first element of coord is equal to 1 (== x), 'then' statement wil be evaluated. - - - - - - - - - - - - I think this is the third thing to leave to the second stage: int x = 1; if (auto {$x, y} = coord) { ... } - - - - - - - - - - - - This is nice: if (auto {x, y} = coord[]) {} // same, explicitly expands fields - - - - - - - - - - - - This is handy and it's vaguely present in Python3, but I suggest to leave this (4th thing) to the second stage: if (auto {num, msg, ...} = tup) {} // ok, `...` matches to zero-elements. - - - - - - - - - - - - Bye, bearophile
Mar 29 2013
{c, {}} = tup;This can't be used, because having an empty tuple as second tuple item is valid.{c, ~= tup;That was: {c, ~} tup; Bye, bearophile
Mar 29 2013
On Fri, 29 Mar 2013 13:56:08 +0100, bearophile <bearophileHUGS lycos.com> wrote:One handy tuple syntax in Haskell allows you to name both the items of a tuple and it whole: void foo(t2 {int a, string b}) { // here a and b are tuple items and t2 is the whole tuple. } auto t1 {x, y} = {10, "hi"}; foo(t1);I suggest instead this syntax: auto {x, y} t1 = {10, "hi"}; It's closer to regular D syntax.foreach (Float; {float, double, real}) { ... } I think you meant to put a variable name there.foreach (Type; {float, double, real}) { ... } See it now?- - - - - - - - - - - - {c, $} = tup; // Rewritten as: c = tup[0]; $ is used for array lengths, so it's not so good to overload it to mean "don't care" too. Alternative syntaxes: {c, $_} = tup; {c, } = tup; {c, _} = tup; {c, $$} = tup; {c, {}} = tup; {c, {_}} = tup; {c, $~} = tup; {c, ~= tup; etc.... has been introduced to match zero or more elements for pattern matching already. I see no reason not to use ... for this. -- Simen
Mar 29 2013
Simen Kjærås:But I'd like sometime to tie t1 to that {}, to help my eyes.void foo(t2 {int a, string b}) { // here a and b are tuple items and t2 is the whole tuple. } auto t1 {x, y} = {10, "hi"}; foo(t1);I suggest instead this syntax: auto {x, y} t1 = {10, "hi"}; It's closer to regular D syntax.Telling the language that there there is exactly one item to match on, that you don't care of, is important. The "..." syntax can't tell apart the case for zero, one, or more items. So "..." can't be enough here. Bye, bearophile{c, $_} = tup; {c, } = tup; {c, _} = tup; {c, $$} = tup; ... {c, {_}} = tup; {c, $~} = tup; ... etc.... has been introduced to match zero or more elements for pattern matching already. I see no reason not to use ... for this.
Mar 29 2013
On 03/29/2013 02:17 PM, Simen Kjærås wrote:On Fri, 29 Mar 2013 13:56:08 +0100, bearophile <bearophileHUGS lycos.com> wrote:It is already taken and equivalent to: {x, y} t1 = {10, "hi"};One handy tuple syntax in Haskell allows you to name both the items of a tuple and it whole: void foo(t2 {int a, string b}) { // here a and b are tuple items and t2 is the whole tuple. } auto t1 {x, y} = {10, "hi"}; foo(t1);I suggest instead this syntax: auto {x, y} t1 = {10, "hi"}; It's closer to regular D syntax. ...
Mar 29 2013
On 03/29/2013 01:56 PM, bearophile wrote:kenji hara:It is false.... Use braces and commas. Inside tuple literal, ; never appears. So it will not be confused with lambdas and ScopeStatements.<This is true. ...
Mar 29 2013
Once tuples have a built-in syntax it becomes possible to add pairs/byPair to associative arrays: auto aa = [1:2, 3:4]; {int, int}[] myPairs1 = aa.pairs; foreach ({k, v}; myPairs1) {} auto myPairs2 = aa.byPair; foreach ({k, v}; myPairs2) {} Bye, bearophile
Mar 29 2013
2013/3/29 bearophile <bearophileHUGS lycos.com>One handy tuple syntax in Haskell allows you to name both the items of a tuple and it whole: void foo(t2 {int a, string b}) { // here a and b are tuple items and t2 is the whole tuple. } auto t1 {x, y} = {10, "hi"}; foo(t1);It will introduce a kind of "reference variable" to D. auto t1 {x, y} = {10, "hi"}; assert(&t1[0] == &x); // t1[0] and x may refer same address on stack. Such case, you can repeat pack and unpack. void foo({int a, string b}) { // auto t2 = {a, b}; // make tuple by copy, or // {a, b} = {1, 2}; // make pack and use it immediately } auto {x, y} = {10, "hi"}; foo({x, y});auto tup = {}; // zero-element tuple (Syntax meaning will be changed!) Nullary tuples are not that useful in D. Scala doesn't even have a short literal for them. So a longer syntax like this is acceptable: auto tup = Tuple();This is for the consistency of language elements. If you want to zero-parameter lambda, you can write like follows. auto fn = (){}; auto fn = {;};- - - - - - - - - - - - This is nice, so we are merging tuple types with tuples, this will simplify D language: // declare tuple value by using explicit tuple type {int, string} tup = {1, "hi"}; alias TL = {int, string[], double[string]}; // types But one thing to remember in the document is that here T1 and T2 are different, because your tuples do not auto-flatten as TypeTuples currently do: alias T1 = {float, double, real}; alias T2 = {float, double, {real}};It would need more description. I'll explain about that. - - - - - - - - - - - -foreach (Float; {float, double, real}) { ... } I think you meant to put a variable name there.Float is the iterated type.- - - - - - - - - - - - {1} // one-element tuple I presume this too will be accepted as 1-tuple: {1,}Currently D allows redundant commas in some places. void foo(int x, int y,) {} enum E { a = 1, b = 2, } auto arr = [1,2,3,]; So, compiler would accept following tuples. auto tup = {1,}; auto tup = {1,"hi",};- - - - - - - - - - - - {c, $} = tup; // Rewritten as: c = tup[0]; $ is used for array lengths, so it's not so good to overload it to mean "don't care" too. Alternative syntaxes: {c, $_} = tup; {c, } = tup; {c, _} = tup; {c, $$} = tup; {c, {}} = tup; {c, {_}} = tup; {c, $~} = tup; {c, ~= tup; etc.Placeholder token is debatable.- - - - - - - - - - - - if (auto {1, y} = tup) { // If the first element of tup (tup[0]) is equal to 1, // y captures the second element of tup (tup[1]). } I suggest to leave that pattern matching plus conditional to a future refinement of tuple implementation (a second stage. And remove it from this first stage proposal. So I suggest to split your proposal in two successive proposals). It seems handy, but D programmers need some time to go there.For complex tuple unpacking requires the part of pattern matching. auto tup = {1, {2,3,4,5,6}} auto {x, {$, y, ...}} = tup; // makes nested tuple pattern for unpacking assert(x == 1); assert(y == 3); So I'd like to keep one DIP.- - - - - - - - - - - - switch (tup) { case {1, 2}: case {$, 2}: case {1, x}: // capture tup[1] into 'x' when tup[0] == 1 default: // same as {...} } What's quite important here is the "final switch". D has to make sure you are considering all possible cases. - - - - - - - - - - - - I suggest to leave this to the second stage, and remove it from this proposal: auto tup = {1, "hi", 3.14, [1,2,3]}; if (auto {1, "hi", ...} = tup) {} - - - - - - - - - - - - "will" is written badly: // If the first element of coord is equal to 1 (== x), 'then' statement wil be evaluated.Will fix.- - - - - - - - - - - - I think this is the third thing to leave to the second stage: int x = 1; if (auto {$x, y} = coord) { ... } - - - - - - - - - - - - This is nice: if (auto {x, y} = coord[]) {} // same, explicitly expands fields - - - - - - - - - - - - This is handy and it's vaguely present in Python3, but I suggest to leave this (4th thing) to the second stage: if (auto {num, msg, ...} = tup) {} // ok, `...` matches to zero-elements.Kenji Hara
Mar 29 2013
On Friday, 29 March 2013 at 12:56:10 UTC, bearophile wrote:$ is used for array lengths, so it's not so good to overload it to mean "don't care" too. Alternative syntaxes: {c, $_} = tup; {c, } = tup; {c, _} = tup; {c, $$} = tup; {c, {}} = tup; {c, {_}} = tup; {c, $~} = tup; {c, ~= tup; etc.{c, ?} = tup;
Mar 30 2013
Zach the Mystic:Right, I was forgetting that. Or this if you want to keep the single "?" for hypothetical future nullable types: {c, ?_} = tup; Bye, bearophile{c, $_} = tup; {c, } = tup; {c, _} = tup; {c, $$} = tup; {c, {}} = tup; {c, {_}} = tup; {c, $~} = tup; {c, ~= tup; etc.{c, ?} = tup;
Mar 30 2013
On Saturday, 30 March 2013 at 18:05:27 UTC, bearophile wrote:Zach the Mystic:What about ---- {c, void} = tup; ---- (proposed by Hara Kenji in the original AutoTupleDeclaration declaration pull request https://github.com/D-Programming-Language/dmd/pull/341 ) (and, independently of the missing symbol choice) ---- {a,b,void...} = tup; //tup = {1,2,3,4,5}; ----Right, I was forgetting that. Or this if you want to keep the single "?" for hypothetical future nullable types: {c, ?_} = tup;{c, $_} = tup; {c, } = tup; {c, _} = tup; {c, $$} = tup; {c, {}} = tup; {c, {_}} = tup; {c, $~} = tup; {c, ~= tup; etc.{c, ?} = tup;
Apr 05 2013
timotheecour:What about ---- {c, void} = tup;I think the question mark is better here. It's shorter and it has only one meaning. Bye, bearophile
Apr 05 2013
On Friday, 5 April 2013 at 23:49:49 UTC, bearophile wrote:timotheecour:Not disagreeing, but you had mentioned nullable types before, and I was wondering what they might look like also. Have you made an enhancement for these I could examine?What about ---- {c, void} = tup;I think the question mark is better here. It's shorter and it has only one meaning. Bye, bearophile
Apr 05 2013
Zach the Mystic:Not disagreeing, but you had mentioned nullable types before, and I was wondering what they might look like also. Have you made an enhancement for these I could examine?I opened this: http://d.puremagic.com/issues/show_bug.cgi?id=4571 Part of the syntax is: T? means T nullable T = means not nullable. But that ER is a confused mess, and in the meantime the disable was introduced. Now the probability of such nullable syntax+semantics to be introduced in D is very low, so probably I will close down that ER. Bye, bearophile
Apr 06 2013
On 4/6/13 4:10 AM, bearophile wrote:Zach the Mystic:I think it's safe to close it. Nullable types have not enjoyed a lot of AndreiNot disagreeing, but you had mentioned nullable types before, and I was wondering what they might look like also. Have you made an enhancement for these I could examine?I opened this: http://d.puremagic.com/issues/show_bug.cgi?id=4571 Part of the syntax is: T? means T nullable T = means not nullable. But that ER is a confused mess, and in the meantime the disable was introduced. Now the probability of such nullable syntax+semantics to be introduced in D is very low, so probably I will close down that ER. Bye, bearophile
Apr 06 2013
Andrei Alexandrescu:I think it's safe to close it. Nullable types have not enjoyedOn the other hand they have gained appreciation in almost every Java-Like languages running on the JavaVM, so this is a not small failure point of D. I think all type-rich languages that will be designed in future will have nonnullable typing. D is old-school on this. Bye, bearophile
Apr 06 2013
On Saturday, 6 April 2013 at 12:59:53 UTC, bearophile wrote:Andrei Alexandrescu:Non nullable should be the default. Compiler know know how to track initialization.I think it's safe to close it. Nullable types have not enjoyedOn the other hand they have gained appreciation in almost every Java-Like languages running on the JavaVM, so this is a not small failure point of D. I think all type-rich languages that will be designed in future will have nonnullable typing. D is old-school on this.
Apr 06 2013
On Saturday, 6 April 2013 at 12:41:46 UTC, Andrei Alexandrescu wrote:On 4/6/13 4:10 AM, bearophile wrote:really useful. In D, this is implementable as a lib anyway.Zach the Mystic:I think it's safe to close it. Nullable types have not enjoyed AndreiNot disagreeing, but you had mentioned nullable types before, and I was wondering what they might look like also. Have you made an enhancement for these I could examine?I opened this: http://d.puremagic.com/issues/show_bug.cgi?id=4571 Part of the syntax is: T? means T nullable T = means not nullable. But that ER is a confused mess, and in the meantime the disable was introduced. Now the probability of such nullable syntax+semantics to be introduced in D is very low, so probably I will close down that ER. Bye, bearophile
Apr 06 2013
On Saturday, 6 April 2013 at 08:10:30 UTC, bearophile wrote:Zach the Mystic:Once dmd pull 1724 is merged, it would be possible to write: class A {} enum E : A { e = new A } void main() { E e; //a is allocated on heap } So, E type is some kind of nullable type (but this approach has drawbacks).Not disagreeing, but you had mentioned nullable types before, and I was wondering what they might look like also. Have you made an enhancement for these I could examine?I opened this: http://d.puremagic.com/issues/show_bug.cgi?id=4571 Part of the syntax is: T? means T nullable T = means not nullable. But that ER is a confused mess, and in the meantime the disable was introduced. Now the probability of such nullable syntax+semantics to be introduced in D is very low, so probably I will close down that ER. Bye, bearophile
Apr 06 2013
On 03/29/2013 09:57 AM, kenji hara wrote:http://wiki.dlang.org/DIP32 Kenji HaraLooks quite nice. I especially like the {a, b} => ... thing. I think, however, that there are a handful serious flaws that need to be addressed: 0 "Inside tuple literal, ; never appears." {{;}} // a tuple not matching your specification {{if(foo()){}}} // a non-tuple matching your specification 1 "Note: Cannot swap values by tuple assignment." IMO a no-go. The syntax is too accessible to introduce this kind of pitfall. 2 "// Error: cannnot use $ inside a function literal" That's a DMD-ism presumably stemming from laziness during "fixing" of an ICE/wrong code bug or something. I'd hate to carry this over to the spec. Don't rely on it. The disambiguation is arbitrary, but may be necessary. (It's not like it is a case actually occurring in real code.) 3 Unpacking / pattern matching is underspecified. - Do patterns nest? - Which right-hand sides are allowed with which semantics? - Which left-hand sides are allowed with which semantics? eg, what about: ref int foo() { ... } { foo(), foo() } = {1, 2}; 4 There is no way to capture the part matched by "..." 5 .expand (or similar) property is missing. 6 Relation to {a: 2, b: 3}-style struct literals not explained. 7 Tuple unpacking for template parameters not mentioned. Is there a migration path for Phobos tuples planned? Eg. template Tuple(T...){ alias Tuple = {T}; } (field spec parsing left out for illustration)
Mar 29 2013
Timon Gehr:4 There is no way to capture the part matched by "..."I have suggested to move the ... syntax to a Stage2, a different DEP.5 .expand (or similar) property is missing.I think Kenji has suggested to use a trailing [] for that. Bye, bearophile
Mar 29 2013
On 03/29/2013 02:25 PM, bearophile wrote:Timon Gehr:No, please. Slicing should not auto-expand. Leading to: 8 Slicing operations on tuples missing.4 There is no way to capture the part matched by "..."I have suggested to move the ... syntax to a Stage2, a different DEP.5 .expand (or similar) property is missing.I think Kenji has suggested to use a trailing [] for that. ...
Mar 29 2013
On 03/29/2013 02:20 PM, Timon Gehr wrote:... 0 "Inside tuple literal, ; never appears." {{;}} // a tuple not matching your specification {{if(foo()){}}} // a non-tuple matching your specification ...The outer { } are not necessary in order to make the point: {if(foo()){}}
Mar 29 2013
2013/3/29 Timon Gehr <timon.gehr gmx.ch>Looks quite nice. I especially like the {a, b} => ... thing. I think, however, that there are a handful serious flaws that need to be addressed: 0 "Inside tuple literal, ; never appears." {{;}} // a tuple not matching your specificationIt will be parsed as: { // tuple braces {;} // function literal braces }{{if(foo()){}}} // a non-tuple matching your specification{ // tuple braces { // function literal braces if (foo()){} // "if" always appears in statement scope } }1 "Note: Cannot swap values by tuple assignment." IMO a no-go. The syntax is too accessible to introduce this kind of pitfall.Allowing value swap in tuple assignment will make language complex. I can't agree with it.2 "// Error: cannnot use $ inside a function literal" That's a DMD-ism presumably stemming from laziness during "fixing" of an ICE/wrong code bug or something. I'd hate to carry this over to the spec. Don't rely on it. The disambiguation is arbitrary, but may be necessary. (It's not like it is a case actually occurring in real code.) 3 Unpacking / pattern matching is underspecified. - Do patterns nest?I think it should be allowed.- Which right-hand sides are allowed with which semantics?Whether it is a pattern or a tuple-literal, is distinguished by their appeared locations.- Which left-hand sides are allowed with which semantics? eg, what about: ref int foo() { ... } { foo(), foo() } = {1, 2};It will be lowered to: // { foo(), foo() } = {1, 2}; foo() = 1; foo() = 2;4 There is no way to capture the part matched by "..."I think this should be allowed. auto {x, r...} = tup; // Lowered to: // auto x = tup[0]; // auto r = tup[1..$] `...` is very consistent token for this purpose. template X(T...) {} alias x = X!(int, long); // T captures {int, long}5 .expand (or similar) property is missing.Use tup[]. It is already exists.6 Relation to {a: 2, b: 3}-style struct literals not explained.I am skeptical of the necessity of tuple literal with named fields. 7 Tuple unpacking for template parameters not mentioned.Is there a migration path for Phobos tuples planned? Eg. template Tuple(T...){ alias Tuple = {T}; } (field spec parsing left out for illustration)Kenji Hara
Mar 29 2013
On 03/29/2013 04:32 PM, kenji hara wrote:2013/3/29 Timon Gehr <timon.gehr gmx.ch <mailto:timon.gehr gmx.ch>> Looks quite nice. I especially like the {a, b} => ... thing. I think, however, that there are a handful serious flaws that need to be addressed: 0 "Inside tuple literal, ; never appears." {{;}} // a tuple not matching your specification It will be parsed as: { // tuple bracesIt contains ';', therefore the DIP says it is a function literal brace.{;} // function literal braces } {{if(foo()){}}} // a non-tuple matching your specification { // tuple braces { // function literal bracesThere is no ';', therefore the DIP says it is a tuple brace.if (foo()){} // "if" always appears in statement scope } }I know how it _should_ be. The DIP contradicts what you say.1 "Note: Cannot swap values by tuple assignment." IMO a no-go. The syntax is too accessible to introduce this kind of pitfall. Allowing value swap in tuple assignment will make language complex. I can't agree with it.Quite obviously it is the other way round. There will be a never-ending flood of d.D.learn posts on the topic.2 "// Error: cannnot use $ inside a function literal" That's a DMD-ism presumably stemming from laziness during "fixing" of an ICE/wrong code bug or something. I'd hate to carry this over to the spec. Don't rely on it. The disambiguation is arbitrary, but may be necessary. (It's not like it is a case actually occurring in real code.) 3 Unpacking / pattern matching is underspecified. - Do patterns nest? I think it should be allowed.ok.- Which right-hand sides are allowed with which semantics? Whether it is a pattern or a tuple-literal, is distinguished by their appeared locations.Obviously, but this statement is not related to my question. Valid right-hand sides seem to be at least tuples and expanded tuples (sequences). Anything else?- Which left-hand sides are allowed with which semantics? eg, what about: ref int foo() { ... } { foo(), foo() } = {1, 2}; It will be lowered to: // { foo(), foo() } = {1, 2}; foo() = 1; foo() = 2;ok.4 There is no way to capture the part matched by "..." I think this should be allowed. auto {x, r...} = tup; // Lowered to: // auto x = tup[0]; // auto r = tup[1..$] `...` is very consistent token for this purpose.Questionable.template X(T...) {} alias x = X!(int, long); // T captures {int, long}Not really. T captures {int, long}.expand.5 .expand (or similar) property is missing. Use tup[]. It is already exists.Slicing obviously shouldn't auto-expand. It's a shortcoming of the Phobos tuple introduced because static slicing cannot be overloaded.6 Relation to {a: 2, b: 3}-style struct literals not explained. I am skeptical of the necessity of tuple literal with named fields.Sure, but you'd at least have to argue in the DIP that the parser can distinguish the two, and how.7 Tuple unpacking for template parameters not mentioned. Is there a migration path for Phobos tuples planned? Eg. template Tuple(T...){ alias Tuple = {T}; } (field spec parsing left out for illustration) ...You have not answered the last two points.
Mar 29 2013
2013/3/30 Timon Gehr <timon.gehr gmx.ch>On 03/29/2013 04:32 PM, kenji hara wrote:Sorry my incomplete description and poor English. I'll improve description in DIP.2013/3/29 Timon Gehr <timon.gehr gmx.ch <mailto:timon.gehr gmx.ch>> It will be parsed as: { // tuple bracesIt contains ';', therefore the DIP says it is a function literal brace. {;} // function literal braces} {{if(foo()){}}} // a non-tuple matching your specification { // tuple braces { // function literal bracesThere is no ';', therefore the DIP says it is a tuple brace. if (foo()){} // "if" always appears in statement scope} }I know how it _should_ be. The DIP contradicts what you say.Allowing value swap in tuple assignment will make language complex. IYes, I agree with it. But, I won't change my opinion. So I'll stop talking about that.can't agree with it.Quite obviously it is the other way round. There will be a never-ending flood of d.D.learn posts on the topic.- Which right-hand sides are allowed with which semantics?Sorry I don't understand you question. 4 There is no way to capture the part matched by "..."Whether it is a pattern or a tuple-literal, is distinguished by their appeared locations.Obviously, but this statement is not related to my question. Valid right-hand sides seem to be at least tuples and expanded tuples (sequences). Anything else?I think it will become reasonable. If you really want re-packing tuple, you can use {tup[0..1]}. It's quite handy. 6 Relation to {a: 2, b: 3}-style struct literals not explained.I think this should be allowed. auto {x, r...} = tup; // Lowered to: // auto x = tup[0]; // auto r = tup[1..$] `...` is very consistent token for this purpose.Questionable. template X(T...) {}alias x = X!(int, long); // T captures {int, long}Not really. T captures {int, long}.expand. 5 .expand (or similar) property is missing.Use tup[]. It is already exists.Slicing obviously shouldn't auto-expand. It's a shortcoming of the Phobos tuple introduced because static slicing cannot be overloaded.Will add description about it. Is there a migration path for Phobos tuples planned?I am skeptical of the necessity of tuple literal with named fields.Sure, but you'd at least have to argue in the DIP that the parser can distinguish the two, and how. 7 Tuple unpacking for template parameters not mentioned.I have no plan. Kenji HaraEg. template Tuple(T...){ alias Tuple = {T}; } (field spec parsing left out for illustration)
Mar 29 2013
kenji hara:I think it will become reasonable. If you really want re-packing tuple, you can use {tup[0..1]}. It's quite handy.This is a bad idea. It is not handy and it introduces a special case. Explicit is better than implicit. Bye, bearophile
Mar 29 2013
2013/3/30 bearophile <bearophileHUGS lycos.com>kenji hara: I think it will become reasonable. If you really want re-packing tuple,That is "explicit". In D, opened tuple (currently it's generated from template parameters, e.g. std.typetuple.TypeTuple) and closed tuple (currently created by structs with alias tuple_field this; e.g. std.typecons.Tuple) are distinct. Slice operator always returns opened tuple. If tup[0..1] makes closed tuple implicitly, you cannot make new flattened tuple from other tuples. auto x = {1,"hi"}; auto y = {[1,2], S(1)}; auto tup1 = {x[], y[]}; // creates {1,"hi", [1,2], S(1)} auto tup2 = {x, y}; // creates {{1,"hi"}, {[1,2], S(1)}} Under your semantics, it is impossible. Kenji Hara.you can use {tup[0..1]}. It's quite handy.This is a bad idea. It is not handy and it introduces a special case. Explicit is better than implicit.
Mar 29 2013
kenji hara:If tup[0..1] makes closed tuple implicitly, you cannot make new flattened tuple from other tuples. auto x = {1,"hi"}; auto y = {[1,2], S(1)}; auto tup1 = {x[], y[]}; // creates {1,"hi", [1,2], S(1)} auto tup2 = {x, y}; // creates {{1,"hi"}, {[1,2], S(1)}} Under your semantics, it is impossible.I (and probably Timon) am just asking for another syntax to do that. Not to make it impossible. A clean syntax to concatenate tuples: auto tup3 = x ~ y; // creates {1,"hi", [1,2], S(1)} In general I agree we need a syntax to apply the tuple items to a function. But I think the slice syntax is the wrong syntax for it. In Python you use a star, this syntax can't be used in D:...def foo(x, y): passIn the Python itertools there is also a map that performs a star too:t = (1, 2) foo(*t)8from itertools import starmap pow(2, 3)[8] In Haskell there is more than one way to do that, like using uncurry that creates a new function: Prelude> mod 10 4 2 Prelude> let t = (10, 4) Prelude> let mod2 = uncurry mod Prelude> mod2 t 2 Prelude> uncurry mod (10, 4) 2 Bye, bearophilet = (2, 3) list(starmap(pow, [t]))
Mar 29 2013
On 03/29/2013 05:39 PM, kenji hara wrote:2013/3/30 bearophile <bearophileHUGS lycos.com <mailto:bearophileHUGS lycos.com>> kenji hara: I think it will become reasonable. If you really want re-packing tuple, you can use {tup[0..1]}. It's quite handy. This is a bad idea. It is not handy and it introduces a special case. Explicit is better than implicit. That is "explicit". In D, opened tuple (currently it's generated from template parameters, e.g. std.typetuple.TypeTuple) and closed tuple (currently created by structs with alias tuple_field this; e.g. std.typecons.Tuple) are distinct. Slice operator always returns opened tuple.Because of prior language limitations, not because it makes any sense! Current operator overloading limitations mandate that it is simply not possible to create a Phobos tuple with a sane slice operator.If tup[0..1] makes closed tuple implicitly, you cannot make new flattened tuple from other tuples. auto x = {1,"hi"}; auto y = {[1,2], S(1)}; auto tup1 = {x[], y[]}; // creates {1,"hi", [1,2], S(1)} auto tup2 = {x, y}; // creates {{1,"hi"}, {[1,2], S(1)}} Under your semantics, it is impossible. ...Certainly not. Creating opened tuples from closed ones is not an operation necessarily tied to slicing. Making an opened tuple should be an explicit operation on closed tuples. Slicing and opening are orthogonal operations. auto tup1 = {x.open, y.open}; // creates {1,"hi", [1,2], S(1)} auto tup2 = {x[0..2], y[]}; // creates {{1,"hi}, {[1,2], S(1)}} auto tup3 = {x[0..2].open, y[].open}; // creates {1,"hi", [1,2], S(1)}
Mar 29 2013
not 'open', there is already something called .expand property http://forum.dlang.org/thread/fdkalkzhchuerkqlpzkg forum.dlang.org how about this: auto x = {1,2,3}; auto x2 = {1,2}; assert(x[0..2]==x2);//no expansion void fun(int x, int y); fun(x2.expand); fun(x[0..2].expand); keeps slicing orthogonal from expansionOn Fri, Mar 29, 2013 at 10:31 AM, Timon Gehr <timon.gehr gmx.ch> wrote:On 03/29/2013 05:39 PM, kenji hara wrote:2013/3/30 bearophile <bearophileHUGS lycos.com <mailto:bearophileHUGS lycos.com>> kenji hara: I think it will become reasonable. If you really want re-packing tuple, you can use {tup[0..1]}. It's quite handy. This is a bad idea. It is not handy and it introduces a special case. Explicit is better than implicit. That is "explicit". In D, opened tuple (currently it's generated from template parameters, e.g. std.typetuple.TypeTuple) and closed tuple (currently created by structs with alias tuple_field this; e.g. std.typecons.Tuple) are distinct. Slice operator always returns opened tuple.Because of prior language limitations, not because it makes any sense! Current operator overloading limitations mandate that it is simply not possible to create a Phobos tuple with a sane slice operator.If tup[0..1] makes closed tuple implicitly, you cannot make new flattened tuple from other tuples. auto x = {1,"hi"}; auto y = {[1,2], S(1)}; auto tup1 = {x[], y[]}; // creates {1,"hi", [1,2], S(1)} auto tup2 = {x, y}; // creates {{1,"hi"}, {[1,2], S(1)}} Under your semantics, it is impossible. ...Certainly not. Creating opened tuples from closed ones is not an operation necessarily tied to slicing. Making an opened tuple should be an explicit operation on closed tuples. Slicing and opening are orthogonal operations. auto tup1 = {x.open, y.open}; // creates {1,"hi", [1,2], S(1)} auto tup2 = {x[0..2], y[]}; // creates {{1,"hi}, {[1,2], S(1)}} auto tup3 = {x[0..2].open, y[].open}; // creates {1,"hi", [1,2], S(1)}
Mar 30 2013
kenji hara:I think it will become reasonable. If you really want re-packing tuple, you can use {tup[0..1]}. It's quite handy.In the end it's not too much bad (despite my first instinct is for a slice of a tuple to be a true tuple), and so far I have not found better alternatives. Let's see what other people think about that. Bye, bearophile
Mar 29 2013
On Friday, 29 March 2013 at 15:47:52 UTC, Timon Gehr wrote:Should there be a difference?template X(T...) {} alias x = X!(int, long); // T captures {int, long}Not really. T captures {int, long}.expand.
Mar 31 2013
On 03/31/2013 08:20 PM, Kagamin wrote:On Friday, 29 March 2013 at 15:47:52 UTC, Timon Gehr wrote:Sure.Should there be a difference?template X(T...) {} alias x = X!(int, long); // T captures {int, long}Not really. T captures {int, long}.expand.
Mar 31 2013
kenji hara:You are right, I didn't know/remember about that: import std.typecons; void foo(int, int) {} void main() { auto t = tuple(1, 2); foo(t.tupleof); foo(t[]); auto t2 = tuple(1, 2, 3); foo(t2[0 .. 2]); } But I don't like that. t2[0 .. 2] should return a new tuple that contains just the first two items. And like every one tuple it's not supposed to auto-unpack. So I think this is a design mistake that should be fixed in the new tuples. Bye, bearophile5 .expand (or similar) property is missing.Use tup[]. It is already exists.
Mar 29 2013
On 03/29/2013 09:57 AM, kenji hara wrote:http://wiki.dlang.org/DIP32 Kenji HaraOne quite ugly thing about this is that function arguments will be a distinct, incompatible and underpowered form of packing together and unpacking multiple values. auto foo(int a, int b){ } // unpacking void main(){ foo(1,2); // packing } Ideal for UFCS would be: {a,b}.zip.map!({x,y}=>x+y); It is therefore likely that people will start to write two overloads, where one takes multiple arguments and the other takes one tuple argument.
Mar 29 2013
kenji hara:http://wiki.dlang.org/DIP32Regarding case values:switch (tup) { case {1, 2}: case {$, 2}: case {1, x}: // capture tup[1] into 'x' when tup[0] == 1 default: // same as {...} }It's useful to switch on struct values: import std.bigint; void main() { auto x = BigInt(3); switch (x) { case BigInt(0): break; default: break; } } Other examples of Phobos structs that is useful to switch on are Nullable, Algebraic, etc. Switching on structs is more easy if the struct has no ctor. So it's a POD (despite having some other method). To support the general case of structs that have a constructor such structs need a standard method named like "unapply", that is used by the switch itself. This is the solution used by Scala language: http://www.scala-lang.org/node/112 This example is in Scala language: object Twice { def apply(x: Int): Int = x * 2 def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None } object TwiceTest extends Application { val x = Twice(21) x match { case Twice(n) => Console.println(n) } // prints 21 } It's equivalent to the D code: import std.stdio; import std.typecons: Nullable; struct Twice { int static opCall(int x) { return x * 2; } Nullable!int unapply(int z) { if (z % 2 == 0) return typeof(return)(z / 2); else return typeof(return).init; } } void main() { immutable int x = Twice(21); assert(x == 42); switch (x) { case Twice(n): writeln(n); // prints 21 break; default: } } A different example: import std.stdio; import std.typecons: Nullable; struct Foo { int x; this(int x_) { this.x = x_ * 2; } Nullable!int unapply(Foo f1) const { return typeof(return)(f1.x / 2); } } void main() { immutable Foo f2 = Foo(10); assert(f1.x == 20); switch (f2) { case Foo(5): writeln("First case: 5"); break; case Foo(n): writeln(n); // Prints: 10 break; default: } } A third example: import std.stdio; struct Even { bool unapply(int x) { return x % 2 == 0; } } void main() { int x = 17; switch (x) { case Even(): writeln("even"); break; default: writeln("odd"); } } unapply() is allowed to return a bool or a Nullable (including a Nullable of a tuple). For more info: http://lamp.epfl.ch/~emir/written/MatchingObjectsWithPatterns-TR.pdf Bye, bearophile
Mar 29 2013
On Friday, 29 March 2013 at 08:58:06 UTC, kenji hara wrote:http://wiki.dlang.org/DIP32 Kenji HaraWhy not square brackets? int i; string str; [i, str] = [5, "line"]; Tuple as alias to Object[] or to Variant[].
Apr 01 2013
On Mon, 01 Apr 2013 09:08:47 +0200, Traveler <nooneknows example.com> wrote:On Friday, 29 March 2013 at 08:58:06 UTC, kenji hara wrote:Mostly because it already has a meaning in D, namely that of an array. What you have above certainly does not compile, but consider the case of a homogeneous tuple: int i = 1, j = 2; [i, j] = [3, 4]; This is equivalent to this code: [1, 2] = [3, 4]; Which of course is nonsense, but it already has a meaning. Using an existing syntax leads to many many more corner cases and gray areas than creating a new syntax does. Of course, {} also has a meaning already, but the overlap of semantics is much smaller, and thus the potential corner cases and gray areas are fewer and smaller. -- Simenhttp://wiki.dlang.org/DIP32 Kenji HaraWhy not square brackets? int i; string str; [i, str] = [5, "line"]; Tuple as alias to Object[] or to Variant[].
Apr 01 2013
By the way, {int,int} - is it a type or a value? auto t={int,int}; t[1] a; ^what is this? 1-element array of {int,int} tuples or `int a;` ?
Apr 01 2013
Two different languages I've used in the distant past used for expansion. auto t1 = {1, "hi"}; auto t2 = {2, "yo"}; auto t3 = {t1, t2}; // == {{1, "hi"}, {2, "yo"}} auto t4 = { t1, t2}; // == {1, "hi", 2, "yo"} Are there still unspecified plans for , or is it now available for something like this? Regarding the $ident syntax (which I was glad to see, since my first question when reading the DIP was whether a way existed to do that), couldn't the syntax then be allowed for this as well, with expansion of a scalar defined as the scalar itself? int x = 1; if ( auto { x, y} = tmp ) // {1, y} = tmp if ( auto {x, y} = tmp } // same as in DIP
Apr 01 2013
On 2013-04-02 02:16, Chris Nicholson-Sauls wrote:Two different languages I've used in the distant past used for expansion. auto t1 = {1, "hi"}; auto t2 = {2, "yo"}; auto t3 = {t1, t2}; // == {{1, "hi"}, {2, "yo"}} auto t4 = { t1, t2}; // == {1, "hi", 2, "yo"} Are there still unspecified plans for , or is it now available for something like this? Regarding the $ident syntax (which I was glad to see, since my first question when reading the DIP was whether a way existed to do that), couldn't the syntax then be allowed for this as well, with expansion of a scalar defined as the scalar itself? int x = 1; if ( auto { x, y} = tmp ) // {1, y} = tmp if ( auto {x, y} = tmp } // same as in DIPWon't there be a conflict with UDA's? -- /Jacob Carlborg
Apr 01 2013
On Tuesday, 2 April 2013 at 06:42:00 UTC, Jacob Carlborg wrote:On 2013-04-02 02:16, Chris Nicholson-Sauls wrote:Oh yeah, those exist. (I seriously forgot... just because I haven't gotten to play with recent D releases any.)Two different languages I've used in the distant past used for expansion. auto t1 = {1, "hi"}; auto t2 = {2, "yo"}; auto t3 = {t1, t2}; // == {{1, "hi"}, {2, "yo"}} auto t4 = { t1, t2}; // == {1, "hi", 2, "yo"} Are there still unspecified plans for , or is it now available for something like this? Regarding the $ident syntax (which I was glad to see, since my first question when reading the DIP was whether a way existed to do that), couldn't the syntax then be allowed for this as well, with expansion of a scalar defined as the scalar itself? int x = 1; if ( auto { x, y} = tmp ) // {1, y} = tmp if ( auto {x, y} = tmp } // same as in DIPWon't there be a conflict with UDA's?
Apr 02 2013
On Friday, 29 March 2013 at 08:58:06 UTC, kenji hara wrote:http://wiki.dlang.org/DIP32 Kenji HaraThe {} syntax is already crowded, I don't think this is wise to use it here. Timon already presented plenty of cases where it isn't as simple as presented in the DIP, and I can come up with a bunch of my own to add here. It don't think this is necessary as point have been made. As a side note, I'd vote for deprecation of the {} syntax for structs to merge it with whatever is decided for tuples.
Apr 06 2013
On Friday, 29 March 2013 at 08:58:06 UTC, kenji hara wrote:http://wiki.dlang.org/DIP32 Kenji HaraI'm not sure if this is off topic or redundant but couldn't many of these things be added to the standard library without a special syntax. for instance s function like unpack could allow import std.typecons; int a; char b ; unpack(a,b) = tuple(5, 'A'); assert(a==5 && b=='A'); instead 0f (int a, char b) = (5,'A'); or whatever. Would this help the problem?
Aug 13 2014
On Wednesday, 13 August 2014 at 23:02:44 UTC, Philip Stuckey wrote:I'm not sure if this is off topic or redundant but couldn't many of these things be added to the standard library without a special syntax. for instance s function like unpack could allow import std.typecons; int a; char b ; unpack(a,b) = tuple(5, 'A'); assert(a==5 && b=='A'); instead 0f (int a, char b) = (5,'A'); or whatever. Would this help the problem?This is already possible with standard library but the fact that declarations need to be separate makes people not happy.
Aug 13 2014
On Wednesday, 13 August 2014 at 23:26:29 UTC, Dicebot wrote:On Wednesday, 13 August 2014 at 23:02:44 UTC, Philip Stuckey wrote:arguments. if (int.TryParse("123", out int i)) { ...use 'i'... }I'm not sure if this is off topic or redundant but couldn't many of these things be added to the standard library without a special syntax. for instance s function like unpack could allow import std.typecons; int a; char b ; unpack(a,b) = tuple(5, 'A'); assert(a==5 && b=='A'); instead 0f (int a, char b) = (5,'A'); or whatever. Would this help the problem?This is already possible with standard library but the fact that declarations need to be separate makes people not happy.
Aug 14 2014
Dicebot:This is already possible with standard library but the fact that declarations need to be separate makes people not happy.The unpack() lacks most of the capabilities you expect and want from tuples handling. Bye, bearophile
Aug 14 2014
This looks really nice. I'd love to use it for std.concurrency, but I'm still trying to sort out a way for this to work. Specifically, it would be nice if there were a way to know from a tuple's TypeInfo if it matches a pattern. For example, would something like this work: receive( ({1, $} x) { ... do something with tuple x }, ({2, $} x) ... ); I suppose it might be possible to say whether a tuple is {int, stuff}, then deserialize it into a variable and compare against the pattern explicitly? Though maybe this would end up requiring me to parse the mangled name of the tuple type?
Aug 14 2014
Sean Kelly:This looks really nice. I'd love to use it for std.concurrency, but I'm still trying to sort out a way for this to work. Specifically, it would be nice if there were a way to know from a tuple's TypeInfo if it matches a pattern.Elsewhere I have suggested to add to D an optional struct (and tuple) method now named onMatch, similar to the unapply method of Scala language, that is also called by the switch case to perform a basic version of pattern matching. Bye, bearophile
Aug 14 2014
On 14/08/14 21:12, bearophile wrote:Elsewhere I have suggested to add to D an optional struct (and tuple) method now named onMatch, similar to the unapply method of Scala language, that is also called by the switch case to perform a basic version of pattern matching.It can be implemented as a library function. The syntax won't be as nice looking tough. With AST macros the syntax could probably look good enough. -- /Jacob Carlborg
Aug 14 2014
Jacob Carlborg:It can be implemented as a library function.It can't be implemented with a library function. You want to use it in function signatures, foreach, and so on. We have discussed this many times. Bye, bearophile
Aug 15 2014
On Friday, 29 March 2013 at 08:58:06 UTC, kenji hara wrote:http://wiki.dlang.org/DIP32 Kenji HaraWill it allow for nested tuples? Or tuples containing lambdas?
Aug 15 2014