digitalmars.D - A different tuple syntax
- bearophile (27/27) May 30 2013 Regarding the syntax to unpack tuples into single variables,
- bearophile (14/14) May 30 2013 If you don't like to introduce a new keyword, then a different
- Frank Fuente (2/16) May 30 2013 My eyes, they burn...
- bearophile (6/7) May 30 2013 It looks a bit like Perl, it's not very nice, but for me it's not
- eles (3/5) May 30 2013 I prefer tup() over the @{} thing, although I would like to have
- Peter Williams (3/8) May 30 2013 Yes, don't over use {} as they'll be need for sets when they're added :-...
- dennis luehring (3/10) May 30 2013 what about !(float, double, real) because the tupple syntax is near to
- dennis luehring (2/16) May 30 2013 sadly not context free and indentical strange like !{float, double, real...
- Diggory (5/5) May 30 2013 Could also do something in the style of token strings, ie.
- watcher (4/9) May 30 2013 These are the hacks that bring languages into a kind of brainfuck
- dennis luehring (8/19) May 30 2013 then is the only solution to free tuple/or use tup with {}
- Diggory (7/19) May 30 2013 I'm sorry that you don't like it, but I don't see why it's any
- bearophile (7/9) May 30 2013 t{} doesn't look wonderful compared to Python-like tuples, but
- watcher (4/24) May 30 2013 I hope i did not sound mean. I just think that a language should
- bearophile (35/39) May 30 2013 I agree that too much terseness is bad, making code less easy to
- bearophile (14/16) May 30 2013 It's less noisy than @{} or ${}:
- Marco Leise (6/6) May 30 2013 Using @ isn't pretty, but I like {} a bit since it is the
- js.mdnq (7/21) May 30 2013 Or rather # or & as they do have some inherent relation to
- Diggory (2/26) May 30 2013 # would not be bad, but not & as that would just be confusing...
- Marco Leise (7/8) May 30 2013 It has the additional advantage to be a non-modifier symbol on
- nazriel (33/57) May 30 2013 That actually looks good...
- deadalnix (8/33) May 30 2013 This have an issue with one element tuple. Not unsolvable, but
- nazriel (1/15) May 30 2013 I agree.
- w0rp (3/22) May 31 2013 Smalltalk (Also Objective C) went this way long ago, and it
- Paulo Pinto (5/30) May 31 2013 Except that in Smalltalk's case, the language is quite similar to
- Timothee Cour (4/30) May 30 2013 Do you have a reference to the post(s) mentioning the problems with Kenj...
Regarding the syntax to unpack tuples into single variables, Kenji Hara wrote a DIP (http://wiki.dlang.org/DIP32 ) denoting tuples with the univesal syntax {...}, but people have found some problems in it. (I think Kenji didn't update that DIP with all the small improvements we suggested in that thread, so they risk getting lost.) Maybe one solution is to use a "tup(...)" syntax, it's a bit heavy, but it's clear and maybe it has no corner cases: tup(int, string) tup = tup(1, "hi"); foreach (Float; tup(float, double, real)) { ... } auto tup(x, y) = tup(1, "hi"); tup(auto x, y) = tup(1, "hi"); tup(int x, string y) = tup(1, "hi"); foreach (i, const tup(x, y); [tup(1,2), tup(3,4), tup(5,6), ...]) { void foo(tup(int, string name), string msg); (tup(A a, B b)) => a + b; switch (tup) { case tup(1, 2): ... } This is not very elegant, "tup" becomes a new keyword and generally I don't like such strong abbreviations, like the ones used in Rust language, but "tuple()" clashes with the library-defined ones, and it's even more wordy if you want to define an array of them: [tuple(1,2), tuple(3,4), tuple(5,6), ...] Bye, bearophile
May 30 2013
If you don't like to introduce a new keyword, then a different alternative is to use the again, a bit like UDAs: {...} [10] {int, string} tup = {1, "hi"}; // With UDA. foreach (Float; {float, double, real}) { ... } auto {x, y} = {1, "hi"}; {auto x, y} = {1, "hi"}; {int x, string y} = {1, "hi"}; foreach (i, const {x, y}; [ {1,2}, {3,4}, {5,6}, ...]) { void foo( {int, string name}, string msg); ( {A a, B b}) => a + b; switch (tup) { case {1, 2}: ... } Bye, bearophile
May 30 2013
On Thursday, 30 May 2013 at 12:32:46 UTC, bearophile wrote:If you don't like to introduce a new keyword, then a different alternative is to use the again, a bit like UDAs: {...} [10] {int, string} tup = {1, "hi"}; // With UDA. foreach (Float; {float, double, real}) { ... } auto {x, y} = {1, "hi"}; {auto x, y} = {1, "hi"}; {int x, string y} = {1, "hi"}; foreach (i, const {x, y}; [ {1,2}, {3,4}, {5,6}, ...]) { void foo( {int, string name}, string msg); ( {A a, B b}) => a + b; switch (tup) { case {1, 2}: ... } Bye, bearophileMy eyes, they burn...
May 30 2013
Frank Fuente:My eyes, they burn...It looks a bit like Perl, it's not very nice, but for me it's not easy to find something significantly better. The syntax with tup() is longer but less noisy. Bye, bearophile
May 30 2013
On Thursday, 30 May 2013 at 13:02:24 UTC, bearophile wrote:Frank Fuente: The syntax with tup() is longer but less noisy.I prefer tup() over the {} thing, although I would like to have something that looks like "a syntax" instead of "a function".
May 30 2013
On 30/05/13 23:14, eles wrote:On Thursday, 30 May 2013 at 13:02:24 UTC, bearophile wrote:Yes, don't over use {} as they'll be need for sets when they're added :-) PeterFrank Fuente: The syntax with tup() is longer but less noisy.I prefer tup() over the {} thing, although I would like to have something that looks like "a syntax" instead of "a function".
May 30 2013
Am 30.05.2013 15:02, schrieb bearophile:Frank Fuente:what about !(float, double, real) because the tupple syntax is near to template parametersMy eyes, they burn...It looks a bit like Perl, it's not very nice, but for me it's not easy to find something significantly better. The syntax with tup() is longer but less noisy. Bye, bearophile
May 30 2013
Am 30.05.2013 15:43, schrieb dennis luehring:Am 30.05.2013 15:02, schrieb bearophile:sadly not context free and indentical strange like !{float, double, real}Frank Fuente:what about !(float, double, real) because the tupple syntax is near to template parametersMy eyes, they burn...It looks a bit like Perl, it's not very nice, but for me it's not easy to find something significantly better. The syntax with tup() is longer but less noisy. Bye, bearophile
May 30 2013
Could also do something in the style of token strings, ie. t{ ... } It's lighter than "tup" and there's a precedent for it already in the language with q{ ... } which also means there should be no issues parsing it.
May 30 2013
On Thursday, 30 May 2013 at 14:06:15 UTC, Diggory wrote:Could also do something in the style of token strings, ie. t{ ... } It's lighter than "tup" and there's a precedent for it already in the language with q{ ... } which also means there should be no issues parsing it.These are the hacks that bring languages into a kind of brainfuck syntax. Why not keep a language easy readable and understandable. A precedence does not imply that it is a desirable thing to have.
May 30 2013
Am 30.05.2013 16:26, schrieb watcher:On Thursday, 30 May 2013 at 14:06:15 UTC, Diggory wrote:then is the only solution to free tuple/or use tup with {} this way a tuple is similar from a syntax perspective like class or struct - the {} scope defines the interface of the tuple which are by default unnamed ordered aliases for type/value class { int a; int b; ... } tuple { int, double, "hello" } its easy to parse, context free and doesn't need a new type of scopeCould also do something in the style of token strings, ie. t{ ... } It's lighter than "tup" and there's a precedent for it already in the language with q{ ... } which also means there should be no issues parsing it.These are the hacks that bring languages into a kind of brainfuck syntax. Why not keep a language easy readable and understandable. A precedence does not imply that it is a desirable thing to have.
May 30 2013
On Thursday, 30 May 2013 at 14:26:11 UTC, watcher wrote:On Thursday, 30 May 2013 at 14:06:15 UTC, Diggory wrote:I'm sorry that you don't like it, but I don't see why it's any more of a hack than any of the other methods presented thus far? I've always found token strings to be exceedingly readable myself, and when new syntax is needed it's usually best to base it on some existing syntax so that there's some sort of consistency.Could also do something in the style of token strings, ie. t{ ... } It's lighter than "tup" and there's a precedent for it already in the language with q{ ... } which also means there should be no issues parsing it.These are the hacks that bring languages into a kind of brainfuck syntax. Why not keep a language easy readable and understandable. A precedence does not imply that it is a desirable thing to have.
May 30 2013
Diggory:I'm sorry that you don't like it, but I don't see why it's any more of a hack than any of the other methods presented thus far?t{} doesn't look wonderful compared to Python-like tuples, but maybe it's the best syntax seen so far that doesn't clashes with tuple(), Tuple!(), TypeTuple!(), comma operator syntax, lambdas, parameter-less lambdas, and so on. Bye, bearophile
May 30 2013
On Thursday, 30 May 2013 at 16:25:27 UTC, Diggory wrote:On Thursday, 30 May 2013 at 14:26:11 UTC, watcher wrote:I hope i did not sound mean. I just think that a language should not be that terse. It must be human readable with little room to make typing or other mistakes. I rather type more if necessary.On Thursday, 30 May 2013 at 14:06:15 UTC, Diggory wrote:I'm sorry that you don't like it, but I don't see why it's any more of a hack than any of the other methods presented thus far? I've always found token strings to be exceedingly readable myself, and when new syntax is needed it's usually best to base it on some existing syntax so that there's some sort of consistency.Could also do something in the style of token strings, ie. t{ ... } It's lighter than "tup" and there's a precedent for it already in the language with q{ ... } which also means there should be no issues parsing it.These are the hacks that bring languages into a kind of brainfuck syntax. Why not keep a language easy readable and understandable. A precedence does not imply that it is a desirable thing to have.
May 30 2013
watcher:I hope i did not sound mean. I just think that a language should not be that terse. It must be human readable with little room to make typing or other mistakes. I rather type more if necessary.I agree that too much terseness is bad, making code less easy to read. On the other hand too much long to type syntax is bad, for different reasons. So you need a compromises, between lot of tiny operators as in J, K, Ursala or Perl6 languages, that are hard to remember, understand and look in the documentation, and very long names as std.functional.binaryReverseArgs of Phobos that are too much long. Such intermediate point between too much long and too much short syntax is not a constant, it must be adapted according to how much common an operation is, in the language, across languages, or even more generally, in mathematics, and natural languages. The more common something is, the shorter it's better for it to be: http://en.wikipedia.org/wiki/Zipf%27s_law Tuples are used very often, they are not meant to be uncommon parts of the language. In range-heavy code you are probably going to use a tuple every 1-5 lines of code. And even more normal D code may use a tuple every 10-30 lines of code. So using a succinct syntax is good. Python uses just commas (with a bit of help of ( ) in some cases, like for the empty tuple), but to not break a certain compatibility with C the D language can't do the same. So we are trying to look for something that works, doesn't clash with currently used syntaxes, including library solutions like Tuple!() and tuple(), and is short enough. Tuple syntax can be short because it's going to be used often enough, and it has to be short because where you use tuples you don't want too much boilerplate, because functional-style code becomes rather worse if your syntax is not terse. That's why most functional languages, or languages with some support for have a nice short syntax for tuples. Bye, bearophile
May 30 2013
Diggory:Could also do something in the style of token strings, ie. t{ ... }It's less noisy than {} or ${}: auto t = t{}; // empty. [10] t{int, string} tup = t{1, "hi"}; // With UDA. foreach (Float; t{float, double, real}) { ... } auto t{x, y} = t{1, "hi"}; t{auto x, y} = t{1, "hi"}; t{int x, string y} = t{1, "hi"}; foreach (i, const t{x, y}; [t{1,2}, t{3,4}, t{5,6}, ...]) { void foo(t{int, string name}, string msg); (t{A a, B b}) => a + b; switch (tup) { case t{1, 2}: ... } Bye, bearophile
May 30 2013
Using isn't pretty, but I like {} a bit since it is the "highest-level" structuring syntax element in D which seems right for this sort of stuff and especially when the tuple resembles an anonymous struct. -- Marco
May 30 2013
On Thursday, 30 May 2013 at 12:32:46 UTC, bearophile wrote:If you don't like to introduce a new keyword, then a different alternative is to use the again, a bit like UDAs: {...} [10] {int, string} tup = {1, "hi"}; // With UDA. foreach (Float; {float, double, real}) { ... } auto {x, y} = {1, "hi"}; {auto x, y} = {1, "hi"}; {int x, string y} = {1, "hi"}; foreach (i, const {x, y}; [ {1,2}, {3,4}, {5,6}, ...]) { void foo( {int, string name}, string msg); ( {A a, B b}) => a + b; switch (tup) { case {1, 2}: ... } Bye, bearophiletuples.. &(int, string) tup The second remind one it is a sort of concatenation of types. e.g., int & string.
May 30 2013
On Thursday, 30 May 2013 at 21:40:47 UTC, js.mdnq wrote:On Thursday, 30 May 2013 at 12:32:46 UTC, bearophile wrote:If you don't like to introduce a new keyword, then a different alternative is to use the again, a bit like UDAs: {...} [10] {int, string} tup = {1, "hi"}; // With UDA. foreach (Float; {float, double, real}) { ... } auto {x, y} = {1, "hi"}; {auto x, y} = {1, "hi"}; {int x, string y} = {1, "hi"}; foreach (i, const {x, y}; [ {1,2}, {3,4}, {5,6}, ...]) { void foo( {int, string name}, string msg); ( {A a, B b}) => a + b; switch (tup) { case {1, 2}: ... } Bye, bearophiletuples.. &(int, string) tup The second remind one it is a sort of concatenation of types. e.g., int & string.
May 30 2013
Am Thu, 30 May 2013 23:48:00 +0200 schrieb "Diggory" <diggsey googlemail.com>:It has the additional advantage to be a non-modifier symbol on a few Latin based keyboard layouts (English, German, Maltese, ...). -- Marco
May 30 2013
On Thursday, 30 May 2013 at 21:40:47 UTC, js.mdnq wrote:On Thursday, 30 May 2013 at 12:32:46 UTC, bearophile wrote:That actually looks good... I liked idea of: auto (x, y) = foo(); (int x1, string y1) = foo(); (int, string) foo() { (int tmp, string tmp2) = (3, "dsa"); return (42, "dsa"); } but it was shoot down because of various issues. Then proposal with {} risen: auto {x, y} = foo(); {int x1, string y1} = foo(); {int, string} foo() { {int tmp, string tmp2} = {3, "dsa"}; return {42, "dsa"}; } Now this: } I like eye-candies and the 1st syntax looks the best for me but it won't happen. Both 2nd example and 3rd proposed by js.mdnq looks good but IMHO the 3rd is way more clear what is it about... also {} IMHO clash a bit with our curly-bracket based language... it gets a bit complicated where function begins, where if blocks begins and where tuple declaration begins. My 2 cents :)) bearophile what do you think?If you don't like to introduce a new keyword, then a different alternative is to use the again, a bit like UDAs: {...} [10] {int, string} tup = {1, "hi"}; // With UDA. foreach (Float; {float, double, real}) { ... } auto {x, y} = {1, "hi"}; {auto x, y} = {1, "hi"}; {int x, string y} = {1, "hi"}; foreach (i, const {x, y}; [ {1,2}, {3,4}, {5,6}, ...]) { void foo( {int, string name}, string msg); ( {A a, B b}) => a + b; switch (tup) { case {1, 2}: ... } Bye, bearophiletuples.. &(int, string) tup The second remind one it is a sort of concatenation of types. e.g., int & string.
May 30 2013
On Friday, 31 May 2013 at 03:07:22 UTC, nazriel wrote:That actually looks good... I liked idea of: auto (x, y) = foo(); (int x1, string y1) = foo(); (int, string) foo() { (int tmp, string tmp2) = (3, "dsa"); return (42, "dsa"); } but it was shoot down because of various issues.This have an issue with one element tuple. Not unsolvable, but must be considered.Then proposal with {} risen: auto {x, y} = foo(); {int x1, string y1} = foo(); {int, string} foo() { {int tmp, string tmp2} = {3, "dsa"}; return {42, "dsa"}; }This is a reciepe for disaster. {} are already used way too much, sometime on way that are hard to deambiguate.Now this: }This have the advantage of not having issue with one element tuples.My 2 cents :)) bearophile what do you think?I also do agree that the 3rd one is probably the best.
May 30 2013
I agree.Then proposal with {} risen: auto {x, y} = foo(); {int x1, string y1} = foo(); {int, string} foo() { {int tmp, string tmp2} = {3, "dsa"}; return {42, "dsa"}; }This is a reciepe for disaster. {} are already used way too much, sometime on way that are hard to deambiguate.
May 30 2013
On Friday, 31 May 2013 at 04:49:41 UTC, deadalnix wrote:On Friday, 31 May 2013 at 03:07:22 UTC, nazriel wrote:Smalltalk (Also Objective C) went this way long ago, and it worked. http://en.wikipedia.org/wiki/Smalltalk#LiteralsNow this: }This have the advantage of not having issue with one element tuples.My 2 cents :)) bearophile what do you think?I also do agree that the 3rd one is probably the best.
May 31 2013
On Friday, 31 May 2013 at 07:32:42 UTC, w0rp wrote:On Friday, 31 May 2013 at 04:49:41 UTC, deadalnix wrote:Except that in Smalltalk's case, the language is quite similar to Lisp in the sense that its syntax is quite minimalist with most language constructs being achieved by messages. In D you will be adding even more constructs to the grammar.On Friday, 31 May 2013 at 03:07:22 UTC, nazriel wrote:Smalltalk (Also Objective C) went this way long ago, and it worked. http://en.wikipedia.org/wiki/Smalltalk#LiteralsNow this: }This have the advantage of not having issue with one element tuples.My 2 cents :)) bearophile what do you think?I also do agree that the 3rd one is probably the best.
May 31 2013
Regarding the syntax to unpack tuples into single variables, Kenji Hara wrote a DIP (http://wiki.dlang.org/DIP32 ) denoting tuples with the univesal syntax {...}, but people have found some problems in it.Do you have a reference to the post(s) mentioning the problems with Kenji's proposed syntax? Thanks On Thu, May 30, 2013 at 5:29 AM, bearophile <bearophileHUGS lycos.com>wrote:Regarding the syntax to unpack tuples into single variables, Kenji Hara wrote a DIP (http://wiki.dlang.org/DIP32 ) denoting tuples with the univesal syntax {...}, but people have found some problems in it. (I think Kenji didn't update that DIP with all the small improvements we suggested in that thread, so they risk getting lost.) Maybe one solution is to use a "tup(...)" syntax, it's a bit heavy, but it's clear and maybe it has no corner cases: tup(int, string) tup = tup(1, "hi"); foreach (Float; tup(float, double, real)) { ... } auto tup(x, y) = tup(1, "hi"); tup(auto x, y) = tup(1, "hi"); tup(int x, string y) = tup(1, "hi"); foreach (i, const tup(x, y); [tup(1,2), tup(3,4), tup(5,6), ...]) { void foo(tup(int, string name), string msg); (tup(A a, B b)) => a + b; switch (tup) { case tup(1, 2): ... } This is not very elegant, "tup" becomes a new keyword and generally I don't like such strong abbreviations, like the ones used in Rust language, but "tuple()" clashes with the library-defined ones, and it's even more wordy if you want to define an array of them: [tuple(1,2), tuple(3,4), tuple(5,6), ...] Bye, bearophile
May 30 2013