type inference surely?
type inference surely?
Posted Jul 30, 2021 1:22 UTC (Fri) by tialaramex (subscriber, #21167)In reply to: type inference surely? by jgg
Parent article: A GPIO driver in Rust
As I see it, the main problem is that C++ chooses to deduce types when the programmer intent isn't at all clear.
Inference is used in Rust to let the programmer not state the obvious. Whenever what is meant isn't obvious, Rust prefers to have the programmer spell out what they mean. The language owners have frequently been conservative here, identifying narrow cases that are obvious, inferring those cases only. If the covered inference is too narrow they can iterate. Code which makes explicit something that subsequently became obvious and could now be inferred still compiles, more inference does not break anything.
But because C++ deduction is mandatory in some places, and can be invoked elsewhere with auto even when the type is not clear, C++ must have some rules to "deduce" a type even when it isn't at all clear to the programmer, which is where the surprises leak in.
I think a LOT of places where auto is surprising in C++ ought to be compile errors instead. "Nope, I don't know for sure what the intended type is, write it down so I can check we're both on the same page".
As to tooling, there already exist popular Rust tools that will tell you what types things are, e.g. if you hover over something, or in greyed "ghost" text in your editor next to the line with the inferred type, or by context clicking. If there isn't already a way to say "Find the places I use the type Vec<Foo<i32>>" then I wouldn't anticipate it being difficult to add. One of the things Rust dodged that C++ inherited from C is the tool-hostile macro system. Any non-trivial C++ codebase is riddled with macros which make it impossible for simple tools to understand the source code, but Rust's ordinary ("by example" or declarative) macros are at worst opaque to such tools (ie the tool doesn't understand some macro calls but can press on unphased), while its "procedural" macros - which are effectively code running inside your compiler - at least respect the idea that the program consists of tokens, not just arbitrary text they should mangle. So a tool could definitely mis-understand what's going on in your source due to a proc macro in theory, but in practice that's rare.
Posted Jul 30, 2021 8:07 UTC (Fri)
by farnz (subscriber, #17727)
[Link] (1 responses)
Part of the difference between the two is that Rust permits partial declaration of an unclear type, while C++ does not. It would be easier to punt on the hard cases if C++ provided a way to express things like "it's definitely going to be a std::vector::iterator, but you can infer the type of the contents of the iterator". Something like std::vector<T=auto>::iterator would be currently free syntax that would make it easier for C++ to say "nope, can't infer that", and the change could be introduced in a epoch thingy (by saying that old epoch code has the old rules, but can use the new syntax, but the new epoch code gets a compile failure if the surprising rules are needed to find a type).
And while I'd agree that Rust's procmacros are better for syntax highlighting than CPP (especially if the procmacro author bothered with span information in their error cases), they do have own their issues that CPP doesn't share - the better-macro crate is designed to open a web page with a surprise in it when you use a "standard" macro, and because it's a procmacro, it'll run in your type-inferring tool.
Posted Jul 31, 2021 2:00 UTC (Sat)
by tialaramex (subscriber, #21167)
[Link]
Still, the proc macros that do this are on purpose. "That's scary, punt" is a reasonable strategy for them - what went in was tokens, and what comes out would have been tokens (modulo somebody forking the compiler, Mara again) so if you get scared give up and pass the un-processed macro through to your next phase. I feel like things get out of hand in the C pre-processor in a more gradual frog-boiling way with no individual step seeming outrageous and yet you can't understand your own code.
As to fixing things in C++ with Epochs, my impression is that all the big interesting changes proposed for Epochs turn out to get into difficulties with templates, and specifically template meta-programming. It may be that introducing some extra places where you can write "auto" is allowed without that particular problem, but I don't see it being more than a band-aid.
type inference surely?
type inference surely?
