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

You are right about the compiler changes but even so you can't compare 1-2 compiler BK with Rust which has language changes as well. Compiler changes are the norm in Rust.

>> The parts of the Rust standard library that are marked stable have remained completely backwards compatible, in both interface and implementation.

This looks like a breaking change on a stable API. Am I wrong? https://github.com/rust-lang/rust/pull/28811



> Rust which has language changes as well

Rust doesn't have backwards incompatible language changes.

> This looks like a breaking change on a stable API.

No. It is a method addition. It is breaking only in the sense that code that didn't explicitly invoke the previous "as_ref" method might call this new method instead. It's the moral equivalent of:

    type A struct { ... }

    type B struct {
        A
    }

    func (a ﹡A) Foo() {}
and then a later version of Go adds a method:

    func (b ﹡B) Foo() {}
Such that code that called Foo() on an instance of ﹡B might call the new method instead. Go can make those changes.


> Compiler changes are the norm in Rust.

Compiler changes are the norm everywhere? I'm not sure what you're trying to say here.

> This looks like a breaking change on a stable API. Am I wrong?

Yes and no.

Rust's policy on breaking changes is that changes that can be fixed by properly qualifying an implicit path are not breaking. Otherwise, adding any method to anything would be a breaking change. In this case, you can use the UFCS syntax to disambiguate.

So it's an "allowed" kind of breakage because not allowing this means freezing the stdlib.

(Go doesn't have this issue due to lack of generics, overloading, and interface-based overloading. Edit: actually, go does too, due to inheritance, but that is easier to avoid and isolate. In rust you can always write client code that breaks if the stdlib adds a method, anywhere. This is true for most typed languages).

Anything that has the chance of practically breaking things is still run through crater (which tests impact on the ecosystem) and as you can see that PR had minimal impact.


> Go doesn't have this issue

Steve has pointed out that go did have this issue as it has a limited level of auto-deref, which it has changed in the past: implementations performed two levels of auto-deref when executing methods when the spec only requires one, the implementations were changed to only allow a single auto-deref: https://golang.org/doc/go1.4#methodonpointertopointer


Right. However, as I mentioned in the edit, you can still be careful about avoiding breaking changes through inheritance and autoderef in the evolution of Go's stdlib. It forbids very specific types of methods from being added, and if you avoid that, you can continue to add methods as if nothing is wrong.

Rust (and C++, because SFINAE, and many other languages), on the other hand, technically has a breaking change each time any method is added to any public type in the stdlib. It's always possible that the client lib was using a trait method of the same name, and now has to fully qualify the method call.




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

Search: