Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Adding a new method is a breaking change, for example, because I could have written a method with that name previously.

Then you should have used a way to namespace your method, as is done in Objective-C with category methods.



All methods are namespaced but there is sugar which can cause a conflict because it searches the namespaces in scope for methods.

Imagine the trait (namespace) `Baz` defines a method `bar()`, and `Foo` is a type which implements `Baz`. `foo.bar()` is sugar for `<Foo as Baz>::bar(foo)`. Imagine `Foo` also implements `Quux`, another trait in scope, and `Quux` is extended to also define `bar()`. Now `foo.bar()` is ambiguous, because it could also mean `<Foo as Quux>::bar(foo)`. As you can imagine, though, this happens very rarely.

You can't avoid a conflict unless you require specifying the namespace at every call-site, which is in my estimation a much greater burden than editing your code to use the explicit namespace form if a conflict arises because of a new method in a dependency.


We have a module system, but that doesn't help. You can still define methods on arbitrary types, subject to the coherence rules.

You can still write out a disambiguated form to distinguish the two, but it's not the default way. That's one of the reasons why adding a defaulted method to a trait is a minor change. See https://github.com/rust-lang/rfcs/blob/master/text/1105-api-... for more.


> Then you should have used a way to namespace your method, as is done in Objective-C with category methods.

Categories do nothing to protect against breakage due to adding methods.




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

Search: