I just came up with an even cooler syntax!
struct Point {
x → f32,
y → f32,
}
distance(Point{x → 1, y → 2});
I just came up with an even cooler syntax!
struct Point {
x → f32,
y → f32,
}
distance(Point{x → 1, y → 2});
just do what Haskell users do and install a font that makes your =>
look like this:
struct Point {
x ⇒ f32,
y ⇒ f32,
}
distance(Point{x ⇒ 1, y ⇒ 2});
fn distance(point: Point) → f32 { ... }
+1
I strongly dislike the current syntax, and I’d like to lay out my personal reasoning for why I believe using =
(in some form) is better.
When you declare a struct like this:
struct Foo {
x: i32,
y: i32,
}
you’re basically declaring a new namespace of values like this (made-up syntax):
namespace Foo {
let x: i32;
let y: i32;
}
When you create a new struct, you’re creating an instance of that namespace of values, and you’re assigning values to each of the variables in the namespace:
let foo = Foo {
x = 1;
y = 2;
};
// or alternatively
let foo: Foo;
foo.x = 1;
foo.y = 2;
So why do we use :
for this today, when what it is doing is assigning values to the yet-to-be-initialised variables inside the instance of the namespace (struct)? Saying that :
fits with the ‘initialisation follows declaration’ pattern seems meaningless to me, because we don’t follow that with let
, and no, let
is not different. When declaring a struct field, the :
functions to declare the type of the struct field. When declaring a variable, the :
functions to declare the type of the variable. It follows pretty naturally (in my opinion) that =
should be used to declare the value of a struct field in the same way that =
declares the value of a variable.
Saying that struct initialisers declare a value instead of assigning one is also meaningless to me, as those two phrases mean the same thing. I can partially understand that argument, though, because you can use a struct initialiser as a value, whereas you can’t use let
as one. However, =
represents giving a value to a name. This is exactly what :
in struct initialisers does: it gives a value to a name (a field of a struct).
I also like the idea of :
being followed by a type everywhere in the Rust syntax. The only place (that I know of) that violates that in the entire Rust syntax (exempting macros, of course) is struct initialisers/patterns. :
represents type ascription everywhere else. So for consistency, we should change :
to only have one meaning: type ascription.
I’m not super fussed about the precise syntax to use (Foo { .x = 3 }
or Foo { x = 3 }
or something else; I personally like the former because it removes a lot of ambiguity) but I firmly believe that =
is the One True Syntax to use in struct expressions.
I submitted an RFC listing both of the syntaxes suggested in this thread as alternatives:
:
is followed by trait bounds too.
If you introduce =
then you should also introduce semicolons instead of commas. That would allow for a future RFC where the constructor becomes a code block.
let foo = Foo {
.x = 1;
let temp=2;
.y = .x*temp
};
But I still like the present syntax.
// alternative, scheme-like pairing
let foo = Foo { bar . 1,
baz . 2, }
// why not just a space?
let foo = Foo { bar 1,
baz 2, }
New proposal with in-depth implementation details and lots of argumentation:
I was curious which syntax would win if each of us voted, so I created a poll:
Because the font might be unreadable, the options are:
{ a => 2, b => 4, c => 8 }
{ .a = 2, .b = 4, .c = 8 }
{ a: 2, b: 4, c: 8 }
++
Foo { a: b: Bar, ... }
is not good.
+1 for { .a = 2, .b = 4, .c = 8 }, It is cleaner and easier for IDE code completion.
As this RFC wasn’t accepted, I’m going to lock up the bikeshed