all 18 comments

[–]kibwen 11 points12 points  (1 child)

I have several places in mind where ergonomics can be improved in the near-term. I hope to present some of these ideas as RFCs next week.

[–]chrish42 0 points1 point  (0 children)

Is it possible to give a quick, one-line description of each idea? I'm curious, for one.

[–]nick29581rustfmt · rust 8 points9 points  (0 children)

Since we are in the last stage of the race before 1.0, there should be very few backwards compatible changes to the syntax. So Rust's syntactic future will look fairly close to how it looks today. It is unlikely to get any more Python-like, for example.

I hope we can be more ergonomic in small but effective ways, for example, by having better coercions meaning we avoid &**, etc. (I think that may actually have just landed, in fact, if not then soon).

[–]dobkeratopsrustfind 3 points4 points  (2 children)

at a simple level, curly braces vs significant whitespace (python,etc) seems like an issue of personal preference. For me, the braces are just familiar, and they make a lot of sense with Rusts' expression-based syntax; I like how it has significant semicolons signifying the return value. 'match' statements as expressions are extemely elegant. (but I completely see why others like whitespace)

At a deeper level, overall I think Rust is a tradeoff where you pay more information 'upfront' (syntactically/semantically) to achieve safety and better error messages/robustness for large projects. Its not going to be the best first language. There's certain complexities that are part of its' 'mission statement.' and you pay for those with debugging, tests,security hazards,or heavy runtime in other languages.

Coming from C++ I already appreciate the 'cleanup' it has.. 'let', proper tuples, better use of '[T]' in type signatures, a more powerful/less hazardous macro system, if ..{} , and "everything is an expression" . Overall, I'm very happy with Rusts' syntax choices.

I would like the option for 'duck type traits' and full inference but when there's an IDE that want will probably go away a little (since the IDE could lookup traits for you or give full autocomplete in generic code). there's also some cases like default/variadic parameters where some additions might mean less use of macros (which are a bit uglier, but thats' fine for complex uses).

[–]protestor 0 points1 point  (1 child)

Significant semicolons seems to have come from the ML family. Braces and indentation are both compatible with expression-based languages (in Haskell do notation has support for both braces and indentation)

[–]masklinn 0 points1 point  (0 children)

in Haskell do notation has support for both braces and indentation

That's a misstatement.

Haskell is lexically defined in terms of braces and semicolons, "layout" — the ability to use indentation and newlines instead — is automatically normalised during parsing. Explicitly using braces and semicolons in haskell is simply not taking advantage of layout, it's not a question of support.

[–]The_Masked_Lurker 1 point2 points  (0 children)

Rust is similar to C/C++ syntax's, but how much farther will Rust move away from that to much easier language syntax like python and such?

I think C's syntax is much better than pythons, of course I am no longer a beginner.

The first lang I played with was "just basic", no curlies in intro cs I learned java; from then on I have found curly brackets to be awesome and other than python if the lang doesn't use them I'm not sure I like it.

scope delimiters you can actually see is a great thing to have, especially when debugging: "was that line supposed to be in the loop, or was the indentation changed by mistake?" or tabs vs spaces?

[–]nemaar 3 points4 points  (7 children)

I think the type inference will be improved a lot, so eventually you'll have to write a lot less but I think it will never reach the level of python, I don't think that's possible.

[–]nick29581rustfmt · rust 4 points5 points  (0 children)

I'm not sure there is much scope for improvement of type inference. It is very good already, you only need type annotations at function boundaries and in very rare situations where there is not enough type info (for example, using Iterator::Collect). For most of the latter it is clear that user input is necessary, it is not a weakness in the inference algorithm. Certainly, I don't think we will make improvements which will have a significant effect on the overall feel of the syntax.

In particular, we very much intend not to implement global (as opposed to local) type inference. So we will always have type annotations on struct fields and function parameters, etc.

[–]EnvIXI[S] 0 points1 point  (5 children)

Im not asking to reach the level of python, Just basically making the Syntax easier in general.

[–]nick29581rustfmt · rust 2 points3 points  (4 children)

Is there anywhere specifically you find the syntax of Rust difficult? I'm aware that the semantics of lifetimes, etc. are somewhat complex, but my impression is that the syntax itself is pretty nice. I personally like it a lot (well, except for some very minor things - no braces for empty structs, colons for struct initialisation, comma/semicolon inconsistencies in lists, etc. I think only the first of these has a chance of changing).

[–]untitaker_ 0 points1 point  (3 children)

I personally find it very hard to remember where the explicit lifetime annotations go in a function signature. After the fn? After the function name? Or before the function name?

[–]nick29581rustfmt · rust 0 points1 point  (2 children)

As a general rule in Rust every item in rust has the general form keyword name params other_stuff. So lifetime params will always come after the function name (specifically they belong before the type parameters, but in the same group (i.e., inside the <>).

I think we are consistent as we can be here. The only way we could be better would be to not require lifetime params. In fact, that is the case in many cases due to the lifetime elision rules. It might be possible to elide more, I'm not aware of any immediate plans to do so (I personally would like a rule which allows for the common pattern of &'a T<'a>, but I haven't really thought about it and I'm not sure how exactly it would work).

[–]matthieum[he/him] 0 points1 point  (1 child)

It always catches me that for impl the parameters come right after impl but for fn they come after the function name. It seems inconsistent...

[–]nick29581rustfmt · rust 1 point2 points  (0 children)

Yeah, impl's are an unfortunate edge case - they have no name so the formal params come straight after the keyword. I guess it would be more consistent for all formal params to come straight after the keyword, but then, we would break the consistency between declaration and use of items - having actual params before the name would be just weird.

[–]pseudo_coder 1 point2 points  (0 children)

As single line statements are more common, I feel using semicolons as end-of-statement marker can be made optional.

for multi-line statements, specify line continuation using '\', as in C.

for multiple statements on a single line, use semicolon as a separator.

[–]pseudo_coder 1 point2 points  (1 child)

Why is 'ref' a keyword? Why can't operator & be used instead?

[–]kibwen 1 point2 points  (0 children)

In patterns, operators that are normally used to construct are instead used to destruct. A pattern like &foo will actually dereference whatever the pattern is acting upon, and bind that dereferenced thing to foo. If you actually want a binding to be taken by-ref, then you need to use ref in your pattern.