One of the things that's made me the most frustrated learning rust is all the type coercion and inferencing. Sometimes code will just work when I have the wrong mental model because types are coerced but then it ends up biting me later when suddenly everything breaks because it can't coerce anymore and I find out nothing was the type I thought it was. I wish there was a way to turn it off while I'm learning just so I can understand what's really happening.
Nobody forces you to rely on type inference. It’s perfectly valid Rust where you type everything if you so wish. This might actually be a good way to learn the ins and outs of the type system.
EDIT: Also, what do you mean by type ‘coercion’? As far as I know the types in Rust are never silently coerced to anything. They just are what they are.
wow, I never contemplated before whether that kind of language design could be evil, but you make me think it might be. Maybe not in the ordinary course of sensible use, but in some horrible "I didn't think of that". Then I feel a bit hypocritical because I'm sure I've relied on a hundred more problematic abstractions without worrying about it.
Far from evil, it's amazingly useful, and is why things like `let x: Vec<_> = foo.collect();` work (the return type of the `collect` method is generic). Rust stops type inference at function boundaries, so the precise type of something is never far away if you need it.
I concur. Rust does it very sensible and elegantly. I will note that the other thing rust does is let you under specify the lifetimes of a function signature but when compile errors happen they tell you what they ended up inferring and you can always correct it when you need something slightly different. The two features are critical in making Rust code easy to read and write as the types and lifetimes can get tedious and most of you have to specify it literally everywhere.
True, although coercion in Rust is quite limited (it doesn't even coerce smaller ints into larger ones), and the coercions that exist are pretty harmless IMO (like letting you call a function that accepts a `&foo` if all you have is a `&mut foo`). I suspect they're referring to something else, as I've never seen coercion highlighted as a pain point before.
You should consider configuring your editor to display types inline, it's awesome. It'll provide annotations next to the code with relevant types, so you don't have to click or anything to display the type. I found it also sped up my learning process by increasing the bandwidth of the feedback loop between me and the language, so I developed an intuition for type inference rules & the return types of stdlib functions faster.
Most editors (or plugins for them) that support a LSP, like rust analyzer[0], can do it. This includes afaik (neo)vim (via coc.nvim), vscode (via rust-analyzer extension), emacs and Clion.
Thank you for pointing these out. I personally use coc but vim lsp was also a good experience. This lost is by far not complete as many other editprs also support LSP servers, like helix.
It could, but then you put off grumpy people like me with old editors that don't do that kind of thing. Plus you need fancy tools to look at patches. And none of it is going to work inside tokio's select macro (or other useful macros), which could be a lot of your code, depending on what you're writing.
I'd rather work in a language where nobody has type information. It's a much more even playing field. ;p
IMO a decent editor is a must for statically typed languages - it's such a productivity boost to navigate by type information, type safe refactoring, etc.
Main benefit of static typing is enabling tooling to reason about your code - not using IDEs is throwing a huge chunk of it away. Historically it was easy to get projects that would be too large for real-time tooling - but these days the IDEs got better and you can get 32 or even 64 GB ram into a workstation trivially - I haven't seen a scenario like that in years.
I've also noticed GitHub supports type navigation in some languages, but yeah for nontrivial reviews I'll usually do a checkout anyway.
I use joe. I've been using it for 25 years at this point, and it works enough, and I'm not interested in changing. About 15 years ago, I upgraded to a version of joe with syntax highlighting which was pretty cool, but I'm not much interested in more than that. I do occasionally poke around with things in fancy IDEs (it's easier to fiddle with Arduino projects with an IDE than otherwise, because nobody writes about how to do the pieces individually... but maybe I can drive platform.io from the command line in the future), but I'm much happier with a simple as dirt editor, and another terminal to run Make in (or whatever, using Rust for work now, so running cargo instead of make).
I get what you mean but it does come across a bit as "why would anyone want C compiler, ASM provides a much more even playing field". All of the "old" editors that people still use have LSP plugins these days, so feel free to treat yourself any day now. :)
Non-sarcastically: type systems have their place but are not quite there yet. I say this as someone currently doing Advent of Code in Haskell, which surely cannot be accused of being lacking in type safety. What I would love to see in a type system is the flexibility that (for example) Rails' ActiveRecord adds to a class while still being type-safe. AFAIK, no such system exists (yet) but I would love to be proven wrong sometime in the future.
Rather than turn off type coercion and inference, it sounds like you want a way to see the coerced/inferred types right in your editor. Rust Analyzer does this for you — there's a plugin for VSCode that will show inferred types as inline hints in your editor next to each expression, so you're never left guessing.
Personally, I agree, Rust is nigh impossible to write without types in your editor; thankfully Rust Analyzer provides them.
I already know Rust, and unexpected implicit refs and derefs in match/if let expressions or method calls still trip me up when writing or reading new code (especially now that match ergonomics can make `match &Option<T> { Some(x)` compile but not the way you expect). Nowadays I avoid higher-order generic functions like .filter(|...| ...) so don't hit unexpected &&T etc. there, but matching on Entry and regex searches still trips me up.