# 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:** 1\
**Showing post:** 25

<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 3, 2025, 12:18am UTC](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567/25 "2025-06-03T00:18:54Z")

</div>

> [@goerz](#):
>
> (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)

Is `missing` a DSL? Because `missing == missing -> missing` which is not a Bool. Why is `missing` special? Should interfaces allow for specifically having a different rule on one concrete type, or should the rule have to apply to all types?

I would argue that if we have to single out specific types in the rule for which the rule doesn’t apply to, we’ve got the rule wrong and should go back to the drawing board. We’ve always said Base isn’t special, we could do things in a package, but here is a case where `MyMissings.jl` would not be possible by definition. Are we okay with losing that fundamental tenant of Julia for a simpler interface on this function?

> [@Benny](#):
>
> This seems pretty clear: [Interfaces: AbstractArray](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array)

It’s not entirely, it’s actually quite ambiguous.

> `size(A)`: Returns a tuple containing the dimensions of `A`

Are those dimensions supposed to be scalar? Or for example with a ragged array, should it be a tuple of vectors for the dimensions of each vector?

Base code generally assumes that `size(A)` is a tuple of scalars, but it’s not actually in the interface definition.

> getindex(A, i::Int): (if `IndexLinear`) Linear scalar indexing

Should `A[i]::T` where eltype(A)==T? That isn’t required in the definition of the interface, but much of Base code relies on the idea that scalar indexing always gives something of `eltype(A)`. A classic type which violated this was always Tracker.jl’s TrackedArray, which stated `eltype(A) == Float64` but `a[i] == TrackedReal{Float64}`.

And for that matter, is `eltype(::AbstractArray{T,N}) where {T,N} = T` supposed to be true? Because the interface does not specify how `eltype` works.

> `getindex(A, I::Vararg{Int, N})`: (if `IndexCartesian`, where `N = ndims(A)`) N-dimensional scalar indexing

Is the identity `getindex(A, Base.Cartesian.CartesianIndex(i)) == getindex(A, i)` expected to hold? Because that’s not specified.

> setindex!(A, v, i::Int): (if `IndexLinear` ) Scalar indexed assignment

```julia

julia> a = rand(2)
2-element Vector{Float64}:
 0.8135346986182869
 0.7300081330807777

julia> a[1]= 2
2

```

Is it expected that `setindex!(A, v::T, i::Int)::T`, i.e. that it also returns `v`? Again there is some Base code in the AbstractArray that relies on this, but it’s not necessarily stated as something that should be true for all AbstractArrays

> length(A): **Default definition** `prod(size(A))`

Is this expected to be true, or just a default? There are some codes (IIRC broadcast is one?) that assumes this is true.

> `similar(A)`: Return a mutable array with the same shape and element type

Is `CuArray` considered mutable if `allowscalar` is false? Because then `A[1] = v` always errors. How do we define “mutable” here: that `A[i] = v` is a valid non-erroring operation? Since if it’s the latter, `similar(A::CuArray)::CuArray` is not correct.

Other functions aren’t even mentioned. Is `zero(x::T)::T` an identity we expect for array types? The only case I know that violates that is Measurements.jl.

I highly encourage folks to think beyond their own immediate codes when thinking about interface definitions and think holistically about how it applies to other codes and the downstream effects. When doing so, you get some not necessarily an easy questions to answer, and its okay for us to document the current limitations of our knowledge and understand that we commonly get interface definitions wrong or ambiguous.

---

_[View the full topic](https://discourse.julialang.org/t/could-introducing-formal-interfaces-be-nonbreaking/129567)._
