Hacker News new | ask | show | jobs
by tialaramex 1314 days ago
Even if the "Ad hoc union" becomes a thing in Rust, you are not likely to get inference of return types.

The return type is part of the function signature and Rust deliberately doesn't infer signatures, in languages with "too much" inference it's impractical for the human programmer to keep track of types because it's all inferred, this has started to be a problem in C++ as more and more things are auto. Rust has some very sophisticated inference inside a function (including partial inference and inferring types from how they're later used), but none for the signature.

2 comments

While I don't strongly object to Rust's choice here, and I agree that production code should have a type signature on every function, I think this is more a place for lint/clippy/whatever. There's no need to gate the programmer trying something on them having produced a type signature that could be inferred.
You might be interested to know that rustc does have some limited ability to infer return types[1], but there are so many edge cases that the feature as it exists today isn't perfect (and won't let you produce a binary). I believe that 1) type alias = impl Trait; will make prototyping easier, and 2) we should allow -> _ in return types in private functions so that they become an allowed part of the language but critically can't become a semver hazard in crates' APIs.

[1]: https://play.rust-lang.org/?version=stable&mode=debug&editio...

Where do I sign up to fight you on that last one? :D

Allowing _ in return position only for private functions feels like something that ends up surprising 99% of people either that this works, or that it doesn't work for their public function and neither group of people are filled with joy as a result.

It's not a hill I'd die on, but it would go on my list of things I don't like in Rust, along with most as casts, impl AddAssign for String, is_ascii_predicates(/* taking */ &self)

The likelihood of it actually landing is quite low, because I suspect quite a few people would agree with you, and as long as rustfix can deal with it I also don't care as strongly about it ^_^
I think it's the job of the IDE to make that work, but I agree, without IDE this can quickly become a problem.
I think method signatures are part of application/typesystem design and should not be inferred. Explicitly provided types are a feature. Inferred/auto type signatures are "necessariy evil" to reduce boilerplate type declarations around code.

While codeblocks `fn1(fn2(), fn3)` and `var r1 = fn2(); var r2 = fn3; fn1(r1, r2)` are more or less identical, unless you have static type definitions for these methods you start having a very bad time inferring what types are being passed around.

Consider typical python wrapper library with liberal use of *kwargs to pass non-wrapped arguments down to wrappee. Those arguments and their types (as much as they are available in python, you get the idea) are entirely missing from wrapper code and make changes at call site pretty difficult

> unless you have static type definitions for these methods you start having a very bad time inferring what types are being passed around.

It doesn't matter if the types are annotated explicitly or inferred. The amount of information is 100% the same. The IDE could just fill in the types _exactly_ in the same way as they would look like when annotated by hand - maybe just with a different color.

IntelliJ does this quite well, see for instance: https://i.stack.imgur.com/tiqjc.png

This is not a guess. This is the real types. There is literally no difference in the behaviour/semantics of the code.

> Consider typical python wrapper library with liberal

No, because python is not statically typed. You can't compare that.

> It doesn't matter if the types are annotated explicitly or inferred. The amount of information is 100% the same.

Explicit offers the opportunity for narrowing, comments, and sometimes choice of names. Otherwise, yes.

Good points!
I like OCaml's approach, where you write types in module signatures, but don't need to put them in the implementation.