5 ms·
Putting class methods in separate impl blocks is actually objectively better; it allows you to define new methods on types that you didn't write, like typeclass
by tines 3y ago
Putting class methods in separate impl blocks is actually objectively better; it allows you to define new methods on types that you didn't write, like typeclasses in Haskell.
- tialaramex 3y agoNotice Rust actually forbids you from doing this to types you don't own. Rust's own standard library gets a pass. For example the [T] (a slice of T) generic type is a built-in, and the core library defines methods on that type, but in terms of sorting it only provides sort_unstable - an unstable sort, and the associated variants of that sort. Then Rust's alloc crate, which is optional, has a new impl block for [T] and it defines sort, a stable sort on this same type which is much faster than it might be otherwise because it uses a temporary buffer, hence it needs an allocator and can't live in core. You are not allowed to do this for other people's types. If I make a Goose in crate A, and then you try to write an impl block for A::Goose so that you can add a fly method to it, that won't work. Rust obviously could allow this, but it would invite chaos, so they don't. What you can do is invent a trait Flying and impl Flying for A::Goose
- lf-non 3y agoYeah I found it somewhat surprising too. Coming from kotlin I had expected this to be similar to extension methods but apparently not. I never fully understood the motivation behind this restriction.
- tialaramex 3y agoSuppose I use Jim's birds crate, Sarah's noises crate and Hannah's shape crate. If Hannah is allowed to write impl birds::Goose { fn fudge(&mut self) { self.counter += 1; } } and Sarah is allowed to write impl birds::Goose { fn fudge(&mut self) { self.counter -= 1; } } ... Now what happens when I call fudge on a Goose? Does it increment the counter? Or decrement the counter? If instead the program is rejected because of the ambiguity, whose fault is the ambiguity? Sarah's fault? Hannah's fault? Jim's fault?
- lf-non 3y agoI'd get what I import (explicitly). If I import conflicting extensions then its my fault for doing so and (only) my program fails to compile.
- conradludgate 3y agoYou cannot import specific inherent methods. What you can do though is use the extension trait concept and import those traits. If you import both traits you get an ambiguous function error and are asked to resolve which trait you want `<Goose as noises::Trait>::fudge(...)`.
- lf-non 3y agoAh, I was not aware of extension traits. Thanks for pointing out.