You are right, I remove the first issue which is not an issue ><
I'm not sure about this. There's a lot of ..
s in the code, and they have multiple meanings. Rust already has that kind of asymmetry for &
in patterns, where it dereferences instead of referencing, and it turned out to be difficult to learn, and eventually got de-facto removed with match ergonomics.
T: AutoTrait
is already an existing pattern, and it's googlable.
I think there are several points here:
Yes, multiple meaning is not good from a UX standpoint. First version of the RFC used ..
as prefix to rest and as postfix to expand. Maybe this is something we can redo to solve this ambiguity.
I'd like to have only a single syntax to declare the variadic tuple, and the issue about using a trait bound is that you can't group the declaration of variadic tuples to enforce that they have the same arity. (Like in (..(L, R))
). Otherwise, it could be a viable option. For this reason, I still prefer the (..T)
syntax.
Considering the for loop syntax, I would be in favor of one of these syntaxes:
// Option 1 - Enclosed in brackets
// Rationale: <> Is like a generic parameter, so a parameter that
// is evaluated at compile time
// Iterate over tuple and type
(for (ref k, map) type (Key, Value) in <k, maps> type <K, V> {
HashMap::<Key, Value>::get(&map, k)
})
(for ref key type Key in <k> type <K> {
Key::do_something(key)
})
// Iterate over tuple
(for (ref k, map) in <k, maps> {
map.get(k)
})
(for ref key in <k> {
key.do_something()
})
// Iterate over type
(for type (Key, Value) in type <K, V> {
(Key::zero(), Value::one())
})
(for type Key in type <K> {
Key::one()
})
// Option 2 - Prefixed by @
// Rationale: @ binds to a set of value,
// the type of the value is determined at compile time
// Iterate over tuple and type
(for (ref k, map) type (Key, Value) in @(k, maps) type @(K, V) {
HashMap::<Key, Value>::get(&map, k)
})
(for ref key type Key in @k type @K {
Key::do_something(key)
})
// Iterate over tuple
(for (ref k, map) in @(k, maps) {
map.get(k)
})
(for ref key in @k {
key.do_something()
})
// Iterate over type
(for type (Key, Value) in type @(K, V) {
(Key::zero(), Value::one())
})
(for type Key in type @K {
Key::one()
})
// Option 2 - Replace `in` by `@` and use `<>` for types
// Rationale: @ binds to a set of value and `<>` designates types variables
// Iterate over tuple and type
(for (ref k, map) <Key, Value> @ (k, maps) <K, V> {
HashMap::<Key, Value>::get(&map, k)
})
(for ref key <Key> @ k <K> {
Key::do_something(key)
})
// Iterate over tuple
(for (ref k, map) @ (k, maps) {
map.get(k)
})
(for ref key @ k {
key.do_something()
})
// Iterate over type
(for <Key, Value> @ <K, V> {
(Key::zero(), Value::one())
})
(for <Key> @ <K> {
Key::one()
})
I find it confusing to remove the in
keyword, what about:
// Rationale: @ binds to a set of value and `<>` designates types variables
// Iterate over tuple and type
for (ref k, map) <Key, Value> @in (k, maps) <K, V> {
HashMap::<Key, Value>::get(&map, k)
}
for ref key <Key> @in k <K> {
Key::do_something(key)
}
// Iterate over tuple
for (ref k, map) @in (k, maps) {
map.get(k)
}
for ref key @in k {
key.do_something()
}
// Iterate over type
for <Key, Value> @in <K, V> {
(Key::zero(), Value::one())
}
for <Key> @in <K> {
Key::one()
}
For the examples with @, the outer parentheses are unnecessary. Because @ isn't used anywhere instead of pattern matching, I don't think that it is ambiguous.
Do you mean in
(for (ref k, map) @in (k, maps) {
map.get(k)
})
having something like
(for (ref k, map) @in k, maps {
map.get(k)
})
I think it is ok as long as you don't have type arguments. (like:
(for (ref k, map) <Key, Value> @in (k, maps) <K, V> {
HashMap::<Key, Value>::get(&map, k)
})
)
So it could be a valid simplified syntax in that case.
So I think the last syntax is nice as it is clear about what you are iterating on and not being to ambiguous or different from existing syntax.
I re-post the syntax here:
// Rationale: @ binds to a set of value and `<>` designates types variables
// Iterate over tuple and type
for (ref k, map) <Key, Value> @in (k, maps) <K, V> {
HashMap::<Key, Value>::get(&map, k)
}
for ref key <Key> @in k <K> {
Key::do_something(key)
}
// Iterate over tuple
for (ref k, map) @in (k, maps) {
map.get(k)
}
for ref key @in k {
key.do_something()
}
// Iterate over type
for <Key, Value> @in <K, V> {
(Key::zero(), Value::one())
}
for <Key> @in <K> {
Key::one()
}
I'll add in future possibilities the case where we can omit the parentheses
I meant instead of
(for (ref k, map) @in (k, maps) {
map.get(k)
})
// do this
for (ref k, map) @in (k, maps) {
map.get(k)
}
You are right, the parenthesis are unnecessary when having a single for loop. I update the RFC and the posts
A PR is open now https://github.com/rust-lang/rfcs/pull/2775
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.