I would like Point { x => 3, y => 5 }
,
which is similar to Scala’s map syntax
val band = Map("Dave" -> "Bass",
"Tony" -> "Guitar",
"Greg" -> "Drums")
I would like Point { x => 3, y => 5 }
,
which is similar to Scala’s map syntax
val band = Map("Dave" -> "Bass",
"Tony" -> "Guitar",
"Greg" -> "Drums")
This is a consequence of constructor-follows-declaration – tuple structs/variants have their constructor/declaration in a value-like form struct S(uint); S(5)
, with types inside parentheses like a method call (instead of within angle brackets, like all other type parameters), while dictionary-structs use the type form S { a: uint }; S { a: 5 }
, with types and values after a colon.
+1 I like C99 syntax, and to me it’s assignment, so similarity between struct.x = 1
and Struct{x = 1}
makes sense.
Also I have to press shift for :
, but not for =
I’m surprised this change wasn’t accepted, :
syntax is inconsistent
No, it’s not. See two posts above your post.
S { a: uint };
doesn’t make sense either, it should be S { a => uint };
because we’re not doing type ascription to a local called a
I actually like =>
in record/struct types because it is not ambiguous and doesn’t interfere with type ascription
I really like @glaebhoerl's Point { .x = x, .y = y }
syntax, as I've said on the rust-lang/rfcs issue:
I'd never seen that syntax before in the context of Rust and I kinda like it, I wish we had this discussion before the alpha (is it really too late for miracles?). It would fit well in with a likely expansion of move semantics:
Point { .x = 10, .y = 11 } // would expand to the more verbose { let p: Point; p.x = 10; p.y = 11; p } // even if that would be safe, I doubt it will be overused as the // struct literal syntax is always shorter - except if this worked: { let p: Point; (p.x, p.y) = (10, 11); p } // but why not Point { (.x, .y) = (10, 11) }
We can still change this... right?
Which leads to a further extension - if we had
IndexSet
:HashMap { ["foo"] = bar } // as sugar for: { let m = HashMap::new(); m["foo"] = bar; m }
I’m definately against =
, because it would imply that there’s assignment happening somewhere, where it’s not. The inconsistency with type ascription could be resolved by using different syntax, like =>
, but I don’t think it’s a big issue.
The assignment would make sense only if we already had a struct variable and wanted to assign few fields at the same time (similar to post above):
let mut p = Point {x: 1, y: 2};
p {.x = 0, .y = 0};
let mut vec = get_a_list_of_strs();
vec {[0] = "first", [1] = "second"};
Summing up: Only use =
where actual assignment is taking place.
Assignment doesn’t really happen anywhere either. If I wrote let x = 5;
it may or may not store that value anywhere. Most likely, x
will be replaced by 5
once the code is generated.
We’re talking about how the language specifies it. =
is an assignment operator right now, in Struct { a: 5 }
no assignment happens from the perspective of the language, it’s just specifying a possible value of the struct.
Yeah, but if you do the Point { .x = 3, .y = 5}
syntax it will be a “structured assignment”
let point = Point { .x = 3, .y = 5}
converts into let point = {let p: Point; p.x = 3; p.y = 5; p};
similarly if you have a let p: Point;
then you can do let point = p { .x = 3, .y = 5 };
which desugars to let point = { p.x = 3; p.y = 5; p}
I’m against changing the syntax. I think the syntax as it is now is the least surprising and don’t find the overloading of :
to be any more offensive than the overloading =
would be.
I love the symmetry we have now with struct definition, construction, and deconstruction via pattern match:
struct Point {
x: u8,
y: u8
}
let p = Point { x:3 , y:5 };
let Point { x:a, y:b } = p;
println!("x was {}, y was {}", a, b);
I recall a time recently where I was out of study, and I just took a guess at the syntax and found that it met my expectation exactly; so the “it’s inconsistent” argument is at least subjective, I would argue.
type ascription would let you do let Point { x: a: i32, y: b: i32} = p
which raises the question of operator associativity
the compiler has no problem with this, but I do
let Point { .x = a: i32, .y = b: i32} = p
looks subjectively better to me
I suppose if I had to pick one of the two syntaxes in your comment for type ascription I would agree. The double colons in let Point { x: a: i32, y: b: i32} = p
are rather ugly.
I don’t like the .x =
at all, however. Isn’t the .
superfluous? We already have the context that we are talking about the struct’s fields because of the surrounding Point { ... }
.
Syntactically, yes. (Syntactically, we could probably even lose the =
/ :
.) It might be helpful for a human reader, especially in patterns.
This syntax is definitely growing on me.
I kind of like being more explicit. Let’s say Rust 1.8 or some other 2017 version adds structural records so you can do this:
let point = { .x = 3, .y = 5};
this would actually conflict with blocks, but the .x
disambiguates it. You can emulate keyword arguments if your function takes a structural record:
drawRectangle({ .coords = { .x = 50, .y = 10 }, .dimensions = { .width = 150, .height = 120 }, .color = { .red = 1.0, .green = 0.0, .blue = 0.5 }});
the signature of the function being
fn drawRectangle(keywords: { .dimensions = { .width: i32, .height: i32 }, .coords = { .y: i32, .x: i32}, .color = { .red: f32, .green: f32, .blue: f32}})
The more I think about this, especially as it relates to type ascription, the more important I think it is that this be changed.
+1 for Point { .x = 3, .y = 5}
Yeah, when I saw that post, I was really confused how you get a variable named Bar when it was clearly a type, but then I realized it’s inside the struct…
I had to ask on IRC how it worked. It’s like a pattern in the parameters, and since you can have :
in signatures for both types and patterns it’s really confusing
+1 to Point {.x = 3, .y = 5}
, the fact that this syntax is in sync with C99 is also a plus.