The ability to define how external types can be transformed into internal types is very powerful. With a few impls, the readability of error handling has been improved drastically. However, there are other areas that would benefit from this flexibility (event handling comes to mind). My hope is to remove the FromError trait and add a From trait. The only change between the two would be the name.
Let me know what you think! If there’s good feedback, I’ll write up an RFC!
Edit: Looking into the standard library, we also have FromPrimitive and FromString traits. Could these be replaced by a general From trait?
It would be nice if this could be used instead of FromPrimitive, ToPrimitive, FromStr, etc. However, those methods return the result wrapped in an Option, but FromError doesn’t. Should the generic From trait wrap the return value in an Option, or not? If not, it would mean that this couldn’t be used as a replacement for FromPrimitive etc.
I have some code in a linear algebra library that would be greatly simplified by something like this. I have a Vector3<T> struct and I sometimes need to convert between different T. AFAIK, it’s not currently easy to write a generic method to do the conversion, and it sounds like this proposal could help.
Replacing FromPrimitive with a generic From trait could be problematic because FromPrimitive has two required methods (for converting from u64 and i64 respectively) and a whole bunch of default methods for converting from the other primitive types. We could create blanket impls:
impl<T> From<u32> for T where T: From<u64> {
fn from(x: u32) -> T { From::from(x as u64) }
}
But then you can’t do the equivalent of overriding FromPrimitive's from_u32 default method because of conflicting impls.
I’m not 100% sure that this is a good idea. The purpose of a trait is not to require that a type has a method with a certain name with a certain set of argument types with a certain return type. The purpose of a trait is to require that a type has a method which does a certain thing. Generalising all From traits (FromError, FromPrimitive, FromStr, FromIterator, BorrowFrom) into a single trait will lose the extra requirements and invariants that must be obeyed that come with the trait, making a trait whose signature is all that matters, and the actual purpose of the function left undefined.
But to be honest I can’t think of a concrete example of any trait’s connotations that would be lost by a generalisation to a single From trait. So I’m going to say that this is a neat idea, and could be made even cooler if it were a special lang item trait that actually controlled the as operator. That would mean that you could convert a String to a &str with as ("foo".to_string() as &str), and maybe even convert them the other way round (perhaps with to and into operators instead).
I don’t have a ton of time to be writing up RFCs right now, but I’m willing to provide help.
Also I pseudo-retract the SmartPtr point. If you know you need some concrete contents like int, then you can use Smaht, but if you just want to take a Smaht and then use it with multiple types (or just have your interface hide which types are needed), then you probably needed HKT or something.
Strong -1 on this. I wrote a bunch of FromSomething traits already and they have vastly diverging requirements to the signature. For instance FromError in rust-welder changed the situation to include error location information. FromRedisValue in redis-rs has more than one method, FromSQL in Postgres has more than one parameter (postgres type + option value).
The tuple solution is both looking ugly and not solving the problem where you need more than one method on the trait. So you will still see other FromX traits showing up. What’s the point of a generic From trait then?
The point would be that in 90% of cases, converting between one type to another is good enough. Other languages have language features (overridable casting) to get exactly this.