> Rust is often different for no real reason. Casting is a good example of this; what was wrong with `(i8)thing`? What does `as` gain us? Couldn't we have used `as` in a more powerful way, like context managers in Python for example?

(type)expression is annoying to parse: in, say, '(i8)x' there's no way to tell that it's a cast expression until you get to the x. That is, (i8) is a valid expression (if there's a variable called i8), and is something like (x)(y) a cast or a function call?

In any case, destructors and move semantics gives most of the benefits of context managers.

> I'm not wild about `macro!`. Because macros are hygenic, I don't care if something is a macro or not and the `!` makes those calls stick out unnecessarily. I would have preferred that `!` indicated mutation in some way, like in Scheme for example. Or maybe get rid of the `mut` keyword and use `!` in variables. Really anything would be better.

It's a bit of a personal argument, but being explicitly marked highlights where weird things may happen, like side-effects that happen twice or returns out of the current function (a function call itself can't return: only `return`, `?` and macros that use them). But sure, it's something people might not like.

> Semicolons suppressing block expression values is one -- why would you ever want to use a block as an rvalue to only assign `unit` to the lvalue?

This is just consistency. Why have block-as-an-r-value as the only case when a semi-colon isn't allowed? Furthermore, there's places for blocks that are formally r-values, but perfectly legitimately have type (), like the arms of match blocks and bodies of closures. And, lastly, not having a special case like this makes writing macros easier.

> I'm a little on the fence with `match`. I think it strikes the right balance between Python's "use if/else for everything" and C's restrictive/dangerous switch, but most match blocks I see are messy. I think all in all I'm into it, and I like that it's got a history in other languages like OCaml, I just wish I could come up w/ a way to clean it up a little.

Match is necessary for working with `enum`s, and enums are great tool for avoiding allocations (e.g. Option<T> instead of a T* that's possibly null) and generally for guiding towards type safety. Having a single entity that does the complete deconstruction of an enum is important with move semantics, or else one would be forced to do a lot of extraneous nested "as_mut"/"is_none" etc. checking, especially for nested deconstructions.

> match guards make me crazy though; that's exactly what if statements are for. The whole reason I like match/switch more than if/else is that it's restricted to the thing you're matching/switching on. A match guard can run a conditional on anything. It's completely superfluous if your language has if/else.

It's very convenient for conditionalizing based on enums... and yes, it's unrestricted, but that's for consistency: why restrict it?

> You can probably guess I don't like match binding either. First I think that's what `let` is for, but I also think using `@` is both very non-intuitive and a big waste of an operator -- all to avoid a single `let` expression.

Do you don't like binding any variables in a match, or specifically doing it with @? I don't think you can use a let to emulate it, at least not without a lot of clunkiness. In any case, it's rarely used and rarely seen, and yes, probably not worth `@` (a keyword could be better).

> if/while let I really like, but its weird that they don't follow the same rules as regular let expressions, like can `Some(i)` be an lvalue normally (no, it can't). I would prefer that they did follow the same rules, or that they used different syntax than `let` because they are in fact different.

If they followed the same rules, they wouldn't be conditional and there would be no point. One can regard the 'if' and 'while' addition as exactly that difference in syntax: "if" means conditional, so an "if let" is a conditional let. I would think adding more keywords/syntax has a larger downside than the small expansion of let's behaviour, but it's hard to say without actually being able to compare it in practice. The "killer" argument for me is that other languages use the same syntax, so there's no particular reason for Rust to be different here, given it's mostly an aesthetics argument.

> `pub` doesn't really mean "public", it means "visibility" and pub without modifiers means "visibility(public)". I do sort of like `mod`, but I dislike having to nest things inside of it. I would prefer a file-based approach, where you declared the file's module at the top.

Rust does have a file-based approach.

"pub" does mean "public", just more restricted than globally. Which, to be fair, is usually what public means in english. Visibility/access control has been an endless argument in Rust.

> I would prefer `impl <trait> on <struct>` instead of `impl <trait> for <struct>` because `for` already means something else.

'for' means something else in a completely different context. I don't really see the benefit in distinguishing them, but sure, I guess you could rename a keyword.

> I would have liked to use traits as types in function signatures instead of the clunky generic syntax. Alternatively just require the `where` clause. Both options reduce the number of things you have to know.

You'll be excited for some of the "impl trait" stuff.

> I wish the "new type idiom" didn't reuse `struct`. Probably `type` goes there.

It's literally just an idiom built on top of a struct. There's nothing special about it. I take it you want the idiom to be baked into the language to be slightly nicer.

> I don't really like the ceremony around heap allocation. I know there are a lot of benefits to `Box`, but I'd prefer `` to Box<T> and `alloc` or even just `new` to `Box::new`. Or hey, if you're against operator reuse, let's use `@` now that we've tossed match binding. Mainly my complaint is this is unnecessarily different from other systems languages.*

Box is (only very slightly) special: it's more consistent to not preference it over other pointer types. In any case, Box literally used to be "~" and Rc "@". People complained endlessly about the impenetrable sigils.

Also, Box shouldn't be that common in most Rust code.