Replace Point { x: 3, y: 5 } with Point { x=3, y=5 }

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.

2 Likes

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.

1 Like
// 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:

http://strawpoll.me/3682338

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 :wink: