C2 forum
General Category => Ideas => Topic started by: lerno on October 30, 2018, 03:35:19 PM
-
We could have tuples through anonymous structs with destructuring.
func struct { i32, f64 } foo() {
return struct { 1, 4 };
// also ok: return { 1, 4 };
}
i32 a, f64 f = foo(); // <- we need to consider parsing here, this collides with the C comma operator.
struct { i32, f64 } x = foo();
What's missing here is some way to only keep one part. If we had named arguments, that could work though!
func struct { i32 loop, f64 time } foo();
i32 x = foo().loop;
The rewrite to C is fairly straightforward here, since we're just using structs.
-
This is actually multiple return types right?
-
Well, it enables "multiple return types", but it's actually just partial assignment from a struct.
Let's say you have this:
type Foo struct {
i32 a;
f64 b;
}
func Foo getFoo() { ... }
Now obviously it's possible to do:
Foo f = getFoo();
i32 a = f.a;
f64 b = f.b;
What we allow is destructuring, that is:
i32 a; f64 b; Foo f;
{ a, b } = f; // or (a, b) = f, struct { a, b } = f, or whatever syntax we pick.
What I like about this approach is that there's no magic. There is no tuple type, just a plain struct. It feels magic, but all we do is to assemble our variables into an ad-hoc struct to receive the reply.
It's merely a quick way of assigning fields from structs that mirror how we can create structs.
I mean we can do this:
f = { .a = a, .b = b };
f = { a, b };
And what we enable is the reverse, so basically
{ a, b } = f;
{ a = .b, b = .b } = f; // <- placeholder syntax
The reason why we want the latter (the one with placeholder syntax) is if we have a very large struct, say with 5 fields, and we like to keep 3 of them. Also, it might be useful if we don't remember the order of the fields.
So the feature is struct destructuring, and what we get is multiple returns.