# Could introducing formal interfaces be nonbreaking?

**URL:** <https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567>\
**Category:** Internals & Design\
**Tags:** speculative\
**Created:** [June 2, 2025, 2:10pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567 "2025-06-02T14:10:58Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [June 2, 2025, 2:10pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/1 "2025-06-02T14:10:58Z")

</div>

I’m surprised by the talk about formal interfaces coming to the base language. I thought that was impossible before Julia 2.0, as they will necessarily break all the packages who don’t conform to the new interface. For example, there might be some package now where `==` returns an `Int`, and that’s allowed.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [June 2, 2025, 2:14pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/2 "2025-06-02T14:14:31Z")

</div>

once you make the distinction between traits (a feature) and interfaces (more comments in code, less ambiguous docs, shared cultural values of rigorous testing suites) I think it would become less surprising to see more interfaces before a 2.0

with a stricter interface for `==`, returning an `Int` would not start erroring, but it might give rise to a GH issue (which is not breaking)

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [June 2, 2025, 2:24pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/3 "2025-06-02T14:24:47Z")

</div>

GH issue?

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [June 2, 2025, 2:30pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/4 "2025-06-02T14:30:48Z")

</div>

GitHub, i.e. “hey package `XYZ`, you should be aware that the current definition of `==` here does not satisfy the interface decided upon in v1.x”

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [June 2, 2025, 2:37pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/5 "2025-06-02T14:37:43Z")

</div>

> [@araujoms](#):
>
> I’m surprised by the talk about formal interfaces coming to the base language. I thought that was impossible before Julia 2.0, as they will necessarily break all the packages who don’t conform to the new interface. For example, there might be some package now where `==` returns an `Int`, and that’s allowed.

Well yes and no. It’s not breaking to add interfaces to the language. It’s breaking to enforce such an interface on a Base abstract type / function. So adding the ability to define an interface isn’t necessarily breaking, but saying `AbstractArray` now needs to satisfy a specific interface is.

We will of course want the latter, and that’s a whole different discussion…

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [June 2, 2025, 2:49pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/6 "2025-06-02T14:49:06Z")

</div>

Maybe make it throw a warning, and 3 years after throwing warnings, turn it into an error? Otherwise it’s useless.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 2, 2025, 2:54pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/7 "2025-06-02T14:54:58Z")

</div>

> [@araujoms](#):
>
> For example, there might be some package now where `==` returns an `Int`, and that’s allowed.

It’s not allowed (according to the doc string). However, yeah, in practice mechanically disallowing that now would be very disruptive. Relevant discussion:

- [Generalize `==` Documentation to not be Statistics-Specific by ChrisRackauckas · Pull Request #53024 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/53024)

To be specific, this is what the doc string says currently:

> The result is of type `Bool`, except when one of the operands is [`missing`](https://docs.julialang.org/en/v1.13-dev/manual/missing/#missing), in which case `missing` is returned ([three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic)).

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [June 2, 2025, 3:08pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/8 "2025-06-02T15:08:02Z")

</div>

I meant allowed in the sense that it does not throw an error, or even a warning. The docstring does not enforce anything. And without enforcement it is doomed to happen. Hence the need for formal interfaces.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [June 2, 2025, 5:01pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/9 "2025-06-02T17:01:58Z")

</div>

There are many many degrees of freedom in how such a feature might be developed. And there are lots of different possible mechanisms for opt-in and enforcement — and precisely how and when that enforcement happens.

I could imagine many designs that are both non-breaking and still very useful. But it’s all highly speculative.

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [June 2, 2025, 5:22pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/10 "2025-06-02T17:22:03Z")

</div>

Such as?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 2, 2025, 6:16pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/11 "2025-06-02T18:16:50Z")

</div>

> [@araujoms](#):
>
> The docstring does not enforce anything.

Disagree. More tooling for mechanically enforcing stuff would be nice, however at the end of the day it all comes down to having good documentation. Any static analysis approach is limited due to basic results from computability theory (“does a program halt?”).

One of the Julia compiler developers happens to have a series of relevant blog posts, on the basics of static analysis:

- [Notes on "Introduction to Static Analysis"](https://aviatesk.github.io/posts/introduction-to-static-analysis/)

EDIT: what I’m trying to say is that documentation is the most important aspect for ensuring interface compliance or correctness. I’m not arguing against tooling. Formal specifications or model checking or stuff like that are another possibility, however that’s clearly not relied on very much, except in specific industries, where it’s presumably mandated by laws or regulation?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 2, 2025, 6:22pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/12 "2025-06-02T18:22:07Z")

</div>

> [@araujoms](#):
>
> Such as?

One relevant approach is letting programmers opt into a language subset:

- [Add `strict` mechanism for opting into stricter subsets of the language · Issue #54903 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/54903)

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [June 2, 2025, 6:27pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/13 "2025-06-02T18:27:08Z")

</div>

> [@araujoms](#):
>
> I meant allowed in the sense that it does not throw an error, or even a warning.

It’s still a bug. I would not consider it breaking to start enforcing interfaces. Of course there is always code that depends on bugs or some undefined behavior, but breaking such code does not violate SemVer.

 ![workflow](https://global.discourse-cdn.com/julialang/original/3X/9/d/9d2e70847354f2521a81057dbdd47dcf9de79059.png)

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 2, 2025, 6:27pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/14 "2025-06-02T18:27:56Z")

</div>

In principle I agree, but, taking the linked Github issue above as an example, starting to enforce the `==` return type contract would break Symbolics.jl.

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [June 2, 2025, 6:30pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/15 "2025-06-02T18:30:20Z")

</div>

Please. Even in the stdlibs I found (and fixed) several examples of docstrings that contradicted the code. One can do a lot of good static analysis without making it Turing complete. In this particular case one could require the function signature to be `==(a::MyType, b::MyType)::Bool`, which is trivial to check.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 2, 2025, 6:31pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/16 "2025-06-02T18:31:52Z")

</div>

> [@araujoms](#):
>
> One can do a lot of good static analysis without making it Turing complete.

Sure. What I’m saying is: at the end of the day you still need the docs to be the “word of god”. Because it’s only “a lot of”.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [June 2, 2025, 6:34pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/17 "2025-06-02T18:34:24Z")

</div>

> [@goerz](#):
>
> It’s still a bug. I would not consider it breaking to start enforcing interfaces.

I don’t know if I would call that a bug. Julia is a dynamic language, after all. If someone intentionally disregards the `Base.==` docstring when they implement it for their type, they accept the consequences of doing that. In particular, as we’ve seen, it can be handy to “pun” on operators when you are creating a DSL. I lean toward allowing DSLs to do whatever they want with their function overloads.

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [June 2, 2025, 6:34pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/18 "2025-06-02T18:34:25Z")

</div>

Well in the cases I fixed the word of god was the code, the docstrings were wrong. Which I think is the usual case, as docstrings are easy to ignore, bugs less so.

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [June 2, 2025, 6:37pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/19 "2025-06-02T18:37:49Z")

</div>

From a quick glance, the extension proposed in [Generalize `==` Documentation to not be Statistics-Specific by ChrisRackauckas · Pull Request #53024 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/53024) seems to broaden the contract, not narrow it. That shouldn’t break code adhering to the currently documented contract. ~~So I wouldn’t necessarily have a problem with that kind of extension.~~ (Edit: actually, I think [one of the comments on the issue](https://github.com/JuliaLang/julia/pull/53024#issuecomment-1913070339) nails it: It’s fine to use `==` with a non-standard meaning in a DSL macro, but not in actual code)

> [@araujoms](#):
>
> Even in the stdlibs I found (and fixed) several examples of docstrings that contradicted the code.

A mismatch between documentation and code is always a bug, by definition, and fixing it either by changing the code or fixing the documentation is not “breaking”. This is of course arguable, but I don’t think “wrong documentation” automatically trounces “wrong code”.

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [June 2, 2025, 6:39pm UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/20 "2025-06-02T18:39:19Z")

</div>

> [@CameronBieganek](#):
>
> If someone intentionally disregards the `Base.==` docstring when they implement it for their type, they accept the consequences of doing that.

I agree, and one of those consequences might be having a non-breaking Julia release require some adjustments in the package

[Next page](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567.md?page=2)
