this post was submitted on 01 Sep 2025
31 points (94.3% liked)
Rust
7313 readers
132 users here now
Welcome to the Rust community! This is a place to discuss about the Rust programming language.
Wormhole
Credits
- The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)
founded 2 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
I would like to take this a step further: support default arguments (
fn func(a: int = 0); func(); func(a=0)
), and then have struct initialization work like that. It's really nice in Python, though I'd like some rules to require args w/ default values to use the assignment syntax, and _require args w/o default values to be in positional order (our codebase is littered withlong_func_name(long_var_name=long_var_name, ...)
where function calls are incredibly long and redundant). That does a few things for us:T::new()
since now you can just doT()
if you just want defaultsfunc(1, 2, some_arg=value)
makes it obvious thatvalue
is specialT{...}
syntax, since you can just use theT(...)
syntaxWe probably disagree about requiring positional args to use the assignment syntax, but both your preference and mine can be enforced w/ conventions (i.e. give your variables relevant names to the function).
I disagree, though I can see where you're coming from. Many OOP languages use the first option, and the second try to reuse keywords.
But you're also missing one use of the
impl
keyword:fn func() -> impl Trait
.I come from Go and I honestly like the syntax there:
Many don't. I like it because it shows that these methods aren't part of the type T, they're "attached" to it. That's much closer to how this actually works that how Java represents it. It's a small thing, but for something low-level like Rust, I think that makes sense.
Also, it makes room for implementing additional functionality on existing types outside of that package. This doesn't work exactly as I'd prefer, but the syntax opens the door to that.
I'm on the fence about this. The
println!("{}", val)
syntax is really nice, and that's one of the common uses for varargs. If your varargs are all the same type, you can use slices:fn func(varargs: &[T]); func(&[1, 2, 3])
and avoid macros entirely. If your types are inconsistent (i.e. C's varargs), you're going to have a rough time w/ any vararg syntax and will need a macro anyway.I agree that macros shouldn't be abused to emulate varargs, but I don't think we actually need a vararg syntax and can use existing tools.
Agree. Use a built-in like Python's
range(...)
instead of fancy syntax, and have the type ([T]
,&[T]
, orvec<T>
) be inferred at compile time. This can probably just drop-in to everywhere the range syntax is being used currently. It's a little more verbose, but it's way clearer.Are you suggesting using keywords/methods instead? So
[T].slice(...)
or evenArray<T>.slice(...)
? I think that's reasonable, and it can work similarly toVec
, but it would complicate the syntax a bit for my vararg proposal. But yeah,[T, count]
is pretty ugly, but I'm not convincedArray<T, count>
is all that much better.I think your post could benefit from a couple examples.
I prefer D's
!
approach:T!U
orT!(U)
. I would switch macros toT#(...)
instead, since#
is already used for things adjacent to macros anyway. But to minimize impact, we could just use#
for generics instead.I'm not a fan of the
[]
for generics, and I disagree w/ Go using that.<>
is awkward due to conflicts with comparison operators, so I agree that it needs to go.Eh, I'm less interested in this one, but I don't have a strong opinion. Calling
*T.index(...)
isn't a big ask...This is certainly annoying, but surely the right solution is to just make floats implement Eq/Ord, no? I can understand someone preferring the PartialEq/PartialOrd behavior, but that's way more niche than just treating
0
and-0
as equal andNaN
as always unequal.Agreed.
Disagree. I prefer changing it to only do type conversions (i.e. f32 -> f64 is valid, but f64 -> f32 isn't). Value conversions should use a different syntax.
Disagree. Either keep as-is, or put
let
next to the new symbol (if Some(let i) = ...
). I don't like chaining, if you want that, just introduce a block or something. It's a bit more verbose, but it's way less confusing.Other languages have destructuring, and this is basically the same thing, and should be handled similarly. For example, in javascript:
let {some: myVar} = option_object;
(i.e. object that looks like{some: value}
. An option is basically just an object w/ two members, so the syntax should be similar:let Some(my_var) = option_object else default_value;
. Throwing anif
in front should merely do something like Python's walrus operator,if my_var := some_call()
, which evaluates whether the expression is truthy, but in the Rust case, it would evaluate whether the assignment was able to be made.I think if-let makes sense, but don't expand it.
Why? What value does
-> ()
provide? Why not elide that?This sounds pretty pedantic. Most of those are quite intuitive, and a lot of this is redundant given the rest of your post.
Disagree. I like that semicolons have meaning in Rust, because in most languages they just feel unnecessary, and languages w/o them feel awkward since you're generally limited to one statement per line.
Thanks for your reply, some replies below!
Not sure, maybe my wording isn't clear enough. What I intended to say is that arguments can be named, not that they have to. In any case, the order of arguments must match the order of parameters, named or not.
That removal could actually happen, so I didn't list it. (Rust started requiring
dyn
and disallowed naked trait returns with edition 2018. So dropping theimpl
in that position might not be completely impossible like the other uses ofimpl
.)Yes, just methods.
You can have both – that's what's being made possible by them not being in a hierarchy.
It's a bit late for that, isn't it? ;-)
What value is provided by keeping it? Why a syntactic special-case for exactly that type and not any other random type?
Then fixing that might make sense. :-)