tuple-syntax

electricface electricface at qq.com
Wed Mar 20 03:34:32 UTC 2024


On Tuesday, 19 March 2024 at 14:06:21 UTC, Lance Bachmeier wrote:

> The comma is used as a separator. A trailing comma isn't used 
> that way, so it looks weird to me. The spec says, "void has no 
> value", so we already have a way to represent something that 
> doesn't have a value: `(void)` and `(1, void)`. Although that's 
> more verbose, I'm not convinced there's enough benefit to 
> warrant the introduction of new syntax.

I think EOT is not a good keyword, so I use void instead of 
EOT.I'm reposting my existing example.

```
// tuple type and tuple literal
(-) t0 = (void);
(int-) t1 = (1, void);
const(int-) t1 = (1, void);
const(int-)* pt1 = &t1;
immutable(int-) t1 = (1,void);
(int-int) t2 = (1,2);
(int-int-string) t2 = (1,2,"ABC");


//Why not use `Tuple!(int)` instead of `(int-)`, because 
`Tuple!(int)` is essentially a template, not an essential tuple 
type.
// (-) => (int-) => (int-int) This shows that the elements of the 
tuple are gradually increasing

// unpack
auto (void) = (void);
auto (a, void) = (1, void); // a = 1
// Empty tuples and single-element tuples are rarely used, so it 
doesn't matter if you bother to write them.
// (1,) People with obsessive-compulsive disorder may think that 
an element is missing here, or that an element has been 
accidentally deleted.
auto (a, b) = (1, 2); // a = 1, b = 2
// "void" appears in the first bracket and serves as a 
placeholder.
auto (void, b) = (1, 2); // b = 2
auto (x, (y, z)) = (1, (2, 3)); // x = 1, y = 2, z = 3
auto (x, y, (z, void), (void)) = (1,2, (3, void), (void)); // x = 
1, y = 2, z = 3


auto t = (1, void);
// to string
writeln(t); // (1)
// unpack
auto (x , void) = t; // x = 1

auto t2 = (1, 2);
// unpack with type
(int64 v1, auto v2) = t2; // v1 = 1, v2 = 2

// function define
int foo(int a, int b) => a + b;

int func0( (-) t ) => 0;

int func1( (int-) t ) => t[0];
// with unpack
int func1_u( (int-)(v1, void) ) => v1;

int func2( (int-int) t ) => t[0] + t[1];

// with unpack
int func2_u( (int-int)(v1, v2)   ) => v1 + v2;

// call function
foo( 1,2 ); // ok
foo( (1,2).expand );  // ok
foo( (1,2) ); // error
// I don't think tuples should automatically expand into multiple 
parameters, which would cause cognitive trouble.

func0( (void) ); // ok
func0(); // err

func1( (1,void) ); // ok
func1( 1 ); // err

func1_u( (1,void)); // ok
func1_u( 1 ); // err

func2( (1,2) ); // ok
func2( 1, 2 ); // err

func2_u( (1, 2)); // ok
```

named tuple:

```
(int:a-) t1 = (a:1, void);
(int:a-int:b) t2 = (a: 1, b: 2);

int funcAB( (int:a-int:b)(a, b) ) => a + b;
auto tab =  (a: 1, b: 2);
funcAB( tab ); // ok

int func2(int a , int b) => a + b;

func2( (b:2, a: 1).expand ); // ok
func2( (b:2, a: 1) ); // err
```

with templates:

`Vector!(-)` represents a vector of empty tuples.
`Vector!(int-)` represents a vector of tuples with 1 int element.
`Vector!(int-int)` represents a vector of tuples with 2 int 
elements.

`(Vector!int-Vector!int)` represents a tuple of 2 vectors, where 
the first element's type is Vector!int and the second element's 
type is also the same. It should not be understood as 
`Vector!(int-Vector!int)`.
`(Vector!(int)-Vector!(int))` same as the previous one.

`(Vector!(int-int)-Vector!(int-int))` represents a tuple of 2 
vectors, where the first element's type is `Vector!(int-int)` and 
the second element's type is also the same.

lambda function:

```
auto lambda0 = ( (-) t0 ) => 0;
auto lambda0 = ( (void) ) => 0;

auto lambda1 = ( (int-) (a, void) ) => a;
auto lambda1 = ( (a, void) ) => a;

auto lambda2 = ( (int-int) (a, b) ) => a + b;
or:
auto lambda2 = ( (a,b) ) => a + b; // type similar to auto 
function( (T-T) t2)

// but:
auto lambdaArg2 = ( a, b ) => a + b; // type similar to auto 
function(T a, T b)
```

foreach:

```
auto ts = [(1,2), (3,4), (5,6)];
// with unpack:
​foreach( (int-int)(a, b); ts) {
	writeln(a," ", b) // 1 2\n3 4\n5 6
}
​foreach( (a, b); ts) {
	writeln(a," ", b) // 1 2\n3 4\n5 6
}

// with unpack:
​foreach(int i, (int-int)(a, b); ts) {
	writeln(i," ",a," ", b) //0 1 2\n1 3 4\n2 5 6
}
​foreach( i, (a, b); ts) {
	writeln(i," ",a," ", b) //0 1 2\n1 3 4\n2 5 6
}
```

functions return a tuple :

```
​(-) func0() {
	return (void);
}
​auto func0() {
	return (void);
}

auto lambda0 = () => (void);

​(int-) func1() {
	return (1, void);
}
​auto func1() {
	return (1, void);
}

auto lambda1 = () => (1, void);

​(int-int) func2() {
	return (1,2);
}
​auto func2() {
	return (1,2);
}
auto lambda2 = () => (1, 2);
```

Hopefully someone will pay attention to more than just the extra 
trailing commas.


More information about the Digitalmars-d mailing list