Hacker News new | past | comments | ask | show | jobs | submit login
Rust shenanigans: return type polymorphism (loige.co)
45 points by mrmagoo17 on April 13, 2021 | hide | past | favorite | 8 comments



I was under the impression that this is something you get for free with Hindley-Millner: There is nothing in there that says: This works only for parameters. As long as there are enough hints left so the compiler can find exactly 1 correct type, the inference will work.

To rephrase this: Some languages have syntax for calling functions like this:

  returned=function(arg1,arg2)
and some have it like this:

   function(arg1 in,arg2 in,returned out)
You can mechanically transform between these 2 styles. The second style works with argument-only type inference, so the compiler has no reason to have problems with the first style.

Update: I played around with it - see https://godbolt.org/z/nfjz8hKa8

I added a trait User with D6->i32 and D8->u8 implementations, and then this:

    let temp=Die::roll();
    let _:u8=User::user(temp);
The compiler can first decide which impl of User to use from the u8, namely the D8. This means it has to use the D8 variant of Die::roll. This compiles, even if the type of temp was never explicitly specified.

This means rustc is even more powerfull than the article implies. When using collect the type definition is not necessary, as long as the function contains enough hints to infer it.


> When using collect the type definition is not necessary, as long as the function contains enough hints to infer it.

Absolutely, rusc can also often detect the type the collect needs if you do a few simple things to the return value and then return it from a function.


Hey Great comments! Thanks a lot. They certainly help to get a better understanding of how the type system actually work under the hood :)


The best thing is you can do

    let values: Vec<_> = some().iterator().chain().collect();
    // use values for stuff
and let the compiler infer what type of values your vec should hold.


I really love the incremental narrative style of this post. I got to go on the discovery ride with you and understood better than if you just explained the feature.


Author here. Thanks for your comment. I did experiment a bit with a different writing style for this new article and this feedback is really useful :)


I fail to understand the importance of this article, why it's a shenigan. About every self respecting OO language honors and can infer return types (union or single), and follow properly the Liskov Substitution Principle (covariant returns, in opposite to args).

Next time another Rust fanboy will detect subtyping, and the strange behavior of different subtyping for return types. Inverse unification! Rust is special! Genius!

Liskov wrote that 1994.


This is not about LSP but about Hindley-Milner. The return type influences the choice of function, not the other way around.

This is also not rust-specific. It is just someone learning how a new tool works, by pushing it to a boundary, then writing about the result. Both learning and sharing are a healthy reflex.

In the worst case, the author is one of today's lucky 10 000.Besides, the article made me realize an imperfection in my own understanding, so I am gratefull for having read it'




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: