# \[ANN\]: ZeroDimensionalArrays.jl: zero-dimensional arrays/references/boxes

**URL:** https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002
**Category:** Package Announcements
**Tags:** package, announcement, array, mutable-structure, ref
**Created:** [April 12, 2025, 10:17am UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002 "2025-04-12T10:17:05Z")
**Posts on this page:** 20
**Page:** 1

<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: [April 12, 2025, 10:17am UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/1 "2025-04-12T10:17:05Z")

</div>

[ZeroDimensionalArrays.jl](https://github.com/JuliaArrays/ZeroDimensionalArrays.jl) is being registered, meaning it has entered the three-day-long wait period. Feel free to suggest breaking changes until the wait period is over!

It’s a tiny package, implementing several similar types, each being a zero-dimensional array.

The package is a response to the frequent confusion regarding `Ref` because of the semantic overloading, and the fact that Julia programmers often don’t expect `Ref` to be an abstract type. It’s meant to replace most/all non-ccall-related use of `Ref`. It’s also suitable for replacing `Array{T, 0}`.

---

<div class="post-metadata">

### Author: ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)
#### Post date: [April 12, 2025, 12:59pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/2 "2025-04-12T12:59:49Z")

</div>

Why not `Scalar` instead of `ZeroDimArray`?

I think `Box` is a pretty good name, but isn’t it used already in Julia in another context, for boxed variable in closures? That might create some confusion…

---

<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: [April 12, 2025, 1:02pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/3 "2025-04-12T13:02:51Z")

</div>

> [@favba](#):
>
> Why not `Scalar` instead of `ZeroDimArray`?

This would kind of make sense, but I think it’s not acceptable to name an array type just “scalar”? Perhaps something like `ScalarArray` or `ArrayScalar`? The bigger issue, I think, is that “scalar” implies something numeric, however a `ZeroDimArray` is not restricted to holding numbers.

> [@favba](#):
>
> I think `Box` is a pretty good name, but isn’t it used already in Julia in another context, for boxed variable in closures? That might create some confusion…

True, there will be a slight amount of confusion when reading `code_warntype`/`code_typed` output, but it seems worth it. Keep in mind `Core.Box` is always fully qualified (the `Core.` part), and also colored in red in `code_warntype` output.

---

<div class="post-metadata">

### Author: ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)
#### Post date: [April 12, 2025, 1:24pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/4 "2025-04-12T13:24:02Z")

</div>

I agree with @favba, I don’t really love the current names in the package, I think that `Box` would be better. Maybe also `RefBox` or `BoxRef` could work? They are a bit repetitive but they don’t clash as much with `Core.Box` at least

---

<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: [April 12, 2025, 1:41pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/5 "2025-04-12T13:41:23Z")

</div>

> [@Tortar](#):
>
> I think that `Box` would be better

What do you mean? Is that a typo?

---

<div class="post-metadata">

### Author: ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)
#### Post date: [April 12, 2025, 1:45pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/6 "2025-04-12T13:45:18Z")

</div>

Not as short as `Box`, but I think `RefVal` is also a good name, and closer to its origin.

---

<div class="post-metadata">

### Author: ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)
#### Post date: [April 12, 2025, 1:54pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/7 "2025-04-12T13:54:26Z")

</div>

I think @favba was also proposing `Box` as a name, or am I wrong? In any case the new proposal of `RefVal` seems also good to me

---

<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: [April 12, 2025, 1:59pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/8 "2025-04-12T13:59:08Z")

</div>

> [@Tortar](#):
>
> proposing `Box`

`Box` is what’s currently used.

Let’s have a poll:

_Poll ([view on site](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/8))_

---

<div class="post-metadata">

### Author: ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)
#### Post date: [April 12, 2025, 2:05pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/9 "2025-04-12T14:05:45Z")

</div>

But this does nothing that isn’t already available in Base, not even more convenient APIs?

I mean, literally the only issue is the unfortunate naming (`Base.Ref` for the abstract type, `Base.RefValue` for the concrete type)?

I feel like this is not a fixable thing: Julia 2.0 will learn not repeat the mistake of the bad name; maybe julia will in the future export a type alias, aka a better name, than `Base.RefValue`. But otherwise, it’s just a minor wart that we have to live with (and `Base.Ref` is taken, using that name for something else would be breaking).

The cure is obviously much worse than the disease: If you can remember to use an extra package, then you would also be able to remember to use `Base.RefValue` instead of `Base.Ref`. And each additional dependency introduces a certain overhead, a la the NPM leftpad debacle. (the overhead is in terms of mental bandwidth and “software supply chain”, not in terms of moving electrons)

Also, `Box` is a terrible name because `ZeroDimensionalArrays.Box` rhymes with `Core.Box`!

---

<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: [April 12, 2025, 2:34pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/10 "2025-04-12T14:34:27Z")

</div>

> [@foobar\_lv2](#):
>
> But this does nothing that isn’t already available in Base

This is a tiny package, obviously reimplementing it is easy, so I don’t really get your point. That said, you’re wrong, of the provided types, `Box` most clearly corresponds to `Ref` (`RefValue`), but the other two are not found in `Base`. In any case, `RefValue` is not available to be _used_ from `Base`, it’s not a public interface.

> [@foobar\_lv2](#):
>
> not even more convenient APIs

Anything specific in mind? I’d say the interface is slightly more convenient, given that these are array types, unlike `Ref`.

> [@foobar\_lv2](#):
>
> literally the only issue is the unfortunate naming

No. The situation with `Ref` is a mine field and using it should be avoided except when doing ccalls:

- `Ref` is an abstract type, but some of its subtypes don’t implement it according to spec: [`Ptr` doesn't observe the supertype semantics of `Ref` · Issue #49004 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/49004)
- The fact that `Ref` is abstract doesn’t seem to be communicated clearly enough in the docs, as apparent from the frequent issues people have with it, see some of the Discourse and Github links in the package readme.
- Again, `RefValue` is private.
- `Ref` was initially meant to be used for FFI (ccall-ing), but then got hijacked for broadcasting and other uses. Something with FFI-specific features shouldn’t be used as a generic container.
- `Ref` has constructor methods even though it’s an abstract type

> [@foobar\_lv2](#):
>
> each additional dependency introduces a certain overhead, a la the NPM leftpad debacle. (the overhead is in terms of mental bandwidth and “software supply chain”, not in terms of moving electrons)

`Base` is a dependency, too, for what that’s worth. A fat one. I don’t want to get too off-topic, however I strongly dislike the anti-dependency attitude that lots of people share with you. Especially considering the superb package management story with Julia. IMO, ideally:

- `Base` would be _much_ slimmer than it is, something like it should only define primitive types
- Small packages would be more prominent in the ecosystem.

> [@foobar\_lv2](#):
>
> Also, `Box` is a terrible name

Cast your vote above?

---

<div class="post-metadata">

### Author: ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)
#### Post date: [April 12, 2025, 3:05pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/11 "2025-04-12T15:05:45Z")

</div>

I have to say that I also find the name of the package itself a bit confusing, specifically: Why the package is named `ZeroDimensionalArrays.jl` if the main use case is boxing fields? something like e.g. `BoxedVals.jl` seems better to me. Besides that, why the struct version is called `ZeroDimArray` while all the rest refers to boxes? Isn’t there a way to uniformize a bit more the naming?

---

<div class="post-metadata">

### Author: ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)
#### Post date: [April 12, 2025, 3:14pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/12 "2025-04-12T15:14:18Z")

</div>

Just to augment the readme, a `ZeroDimArray` differs from a 0-dim `FillArrays.Fill` when it comes to broadcasting. A `Fill` doesn’t drop the array container, whereas a `ZeroDimArray` does. This behavior is consistent with 0-dim `Array`s, whereas a `Fill` isn’t consistent.

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [April 12, 2025, 3:58pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/13 "2025-04-12T15:58:22Z")

</div>

> [@jishnub](#):
>
> This behavior is consistent with 0-dim `Array`s, whereas a `Fill` isn’t consistent.

Is that a bug?

```julia
julia> using ZeroDimensionalArrays, FillArrays

julia> fill(1) .+ 1
2

julia> Fill(1) .+ 1
0-dimensional Fill{Int64}, with entry equal to 2

julia> ZeroDimArray(1) .+ 1
2

```

Edit, found [my issue](https://github.com/JuliaArrays/FillArrays.jl/issues/145) about this. Original example was:

```julia
julia> real(fill(1+im)) # returns an array
0-dimensional Array{Int64, 0}:
1

julia> real(Fill(1+im)) # returns an array of arrays
0-dimensional Array{Fill{Int64, 0, Tuple{}}, 0}:
Fill(1)

```

But there’s another broadcasting difference, that `Fill` makes purity assumptions. This one I think is a choice, which FillArrays.jl does not regard as a bug:

```julia
julia> (_ -> rand()).(fill(1)) .+ zeros(2,3) # ordinary fused broadcast
2×3 Matrix{Float64}:
 0.720996 0.162743 0.170527
 0.217833 0.417129 0.955952

julia> (_ -> rand()).(Fill(1)) .+ zeros(2,3) # calls rand just once
2×3 Matrix{Float64}:
 0.72484 0.72484 0.72484
 0.72484 0.72484 0.72484

julia> (_ -> rand()).(ZeroDimArray(1)) .+ zeros(2,3)
2×3 Matrix{Float64}:
 0.0791902 0.467466 0.74044
 0.06619 0.701926 0.531931

```

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [April 12, 2025, 4:15pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/14 "2025-04-12T16:15:24Z")

</div>

> [@Tortar](#):
>
> Besides that, why the struct version is called `ZeroDimArray` while all the rest refers to boxes? Isn’t there a way to uniformize a bit more the naming?

I agree, the names seem confusing to me too. I’m not sure why there are 3 different cases at all. I had to look at the source to see what “`BoxConst` \* declared with `mutable struct`” means. What’s that even for? The only thing I can think of is someplace you do need an `objectid` but also want to forbid mutation, which seems quite deep in the weeds.

If this is a prototype aiming to replace the use of `Ref` in broadcasting, then IMO it should be one `struct` and as few lines as possible.

```julia
julia> isa.(Ref([1,2,3]), [Array, Dict, Int]) # README's user-facing example
3-element BitVector:
 1
 0
 0

julia> println.("hello", " ", ["user", "world"]); # internal usage
hello user
hello world

julia> Base.broadcastable("hello")
Base.RefValue{String}("hello")

```

There was a PR adding basically `Fill` to Base for this purpose, and IIRC it failed on the above surprising-broadcasting, plus just being more code than seemed justified.

But this package seems to aim at many other uses of `Ref`. In this example, I’m not really sure why this is better, why not `Ref(0.2)` here?

```julia
const some_const_binding = Box(0.2)

```

For fields, clearly abstract `mutable_int::Ref{Int}` is bad, but isn’t the right pattern for some mutable fields to have `mutable struct` with `const immutable_bool::Bool`? Why is this better?

```julia
struct SomeImmutableType
    immutable_bool::Bool
    immutable_float::Float64
    mutable_int::Box{Int}
end

```

---

<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: [April 12, 2025, 4:45pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/15 "2025-04-12T16:45:33Z")

</div>

> [@Tortar](#):
>
> I have to say that I also find the name of the package itself a bit confusing, specifically: Why the package is named `ZeroDimensionalArrays.jl` if the main use case is boxing fields?

Boxing is merely one of the uses, see the examples in the readme. Two of the three types, the ones whose names currently start with `Box*` prefix, box their only element, due to being defined with `mutable struct`. In contrast, the third type, `ZeroDimArray`, is defined with `struct`, not with `mutable struct`, so it doesn’t do boxing.

Will try to make this more clear in the readme again.

> [@Tortar](#):
>
> something like e.g. `BoxedVals.jl` seems better to me. Besides that, why the struct version is called `ZeroDimArray` while all the rest refers to boxes? Isn’t there a way to uniformize a bit more the naming?

A name such as `BoxedVals.jl` would only cover two of the three exported types, as just explained.

> [@mcabbott](#):
>
> I’m not sure why there are 3 different cases at all.

For performance mostly:

- Use `ZeroDimArray` to avoid the overhead of a `mutable struct`, when a `mutable struct` is not required.
- Use `BoxConst` (that’s the current name at least) to:
  - forbid mutation
  - reap the benefits from letting the compiler know there can’t be any mutation, such as better inferred effects, to enable constant folding

Will try to add something to that effect to the readme, or make it more clear.

> [@mcabbott](#):
>
> I had to look at the source to see what “`BoxConst` \* declared with `mutable struct`” means. What’s that even for?

Just addressed this immediately above.

> [@mcabbott](#):
>
> For fields, clearly abstract `mutable_int::Ref{Int}` is bad, but isn’t the right pattern for some mutable fields to have `mutable struct` with `const immutable_bool::Bool`? Why is this better?

Sometimes one just needs a reference to accomplish the goal, that is, access performance is not the only important thing. I’ll quote @foobar_lv2 from two days ago:

> [@Ref{T} vs Base.RefValue{T}](https://discourse.julialang.org/t/ref-t-vs-base-refvalue-t/127886/21):
>
> Why would you put a Ref into an immutable struct? Obviously because your program logic wants to put references to the same shared mutable state into many different immutable structs, duh! Same reason why you would put any mutable struct into an immutable one.
> 
> That’s eminently sensible.

It’s possible I haven’t ever written code like that, but the idea is, if it’s not clear, that there’s some data structure one wants to implement, one needs references to implement this data structure, and either:

- needs to forbid mutation for safety
- wants to let the compiler know there’s no mutation to enable the compiler optimizer more

Will also try to explain this better in the readme, however I’m afraid it’s becoming too big, possibly causing some to avoid reading it. It’s possibly already bigger than the source code. Perhaps it just needs better structure?

---

<div class="post-metadata">

### Author: ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)
#### Post date: [April 12, 2025, 5:07pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/16 "2025-04-12T17:07:48Z")

</div>

> [@nsajko](#):
>
> A name such as `BoxedVals.jl` would only cover two of the three exported types, as just explained.

It would cover the majority of the types, then?

While the Boxes can also serve as zero dimensional arrays, that use case is pretty much covered already in Julia: just use `Array{T,0}` if you want it mutable, `SVevtor{0}` for immutable. My guess is that’s what someone needing literally a zero dimensional array would do.

It is the boxing aspect that needs improvement in Julia because of the `Ref` abstract opaquenes and the gatekeeping of `Base.RefValue`…  
So I think a name like `RefVals.jl` would improve the discoverability of the package for the people that would be looking for a package to help them with their use case.

Of course, the best solution to the `Ref` problem would be for people to stop trying to babysit julia users, export the damn `Base.RefValue` type and let people use it as they see fit. But that is unlikely to happen.

---

<div class="post-metadata">

### Author: ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)
#### Post date: [April 13, 2025, 10:11pm UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/17 "2025-04-13T22:11:22Z")

</div>

I like the name ZerodimentionalArrays. It communicates the intent clearly. The names based on Ref assumes a lot of knowledge of implementation details of Julia.

---

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [April 14, 2025, 12:33am UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/18 "2025-04-14T00:33:50Z")

</div>

From the docs: “Any zero-dimensional array is an iterator containing exactly one element (this follows from the zero-dimensional shape).”

Call it nitpicky, but what is the difference between 1-d and 2-d arrays? Number of dimensions, not number of elements.

```julia
a = [1]

```

This array has exactly one element, but it is not zero-dimensional.

I find this terminology confusing.

---

<div class="post-metadata">

### Author: ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)
#### Post date: [April 14, 2025, 1:04am UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/19 "2025-04-14T01:04:24Z")

</div>

> [@nsajko](#):
>
> Will also try to explain this better in the readme, however I’m afraid it’s becoming too big, possibly causing some to avoid reading it. It’s possibly already bigger than the source code. Perhaps it just needs better structure?

My suggestion for this would be to have a separate blog post: the Readme should describe what’s in the package and how to use it, and the blog post should describe why it’s necessary and when to use it. (“blog post” can be a locked post here on Discourse, or even just a `why.md` file in the repo, whatever is most convenient).

In the [Diataxis](https://diataxis.fr/) framework, the Readme would cover the right hand side of the categorization, and the blog post the left hand side of it. If this is intended to be a package that’s quick to pickup, easy to use, and commonly used (and it seems to be intended so), such a post would also give you a lot more room to make it accessible to every Julia user, taking it closer to that intended goal.

---

<div class="post-metadata">

### Author: ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)
#### Post date: [April 14, 2025, 5:52am UTC](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002/20 "2025-04-14T05:52:17Z")

</div>

Just to chime in with a different perspective: I find this new package great. It fills an important API hole with a small, self-contained implementation with no dependencies.

What API hole is that? Broadly speaking, references. Julia’s references have poor semantics and seems ad-hoc designed. It’s annoying that `Ref` is an abstract type, yet does not behave like other abstract types: Clearly the API revolves around using the `Ref` constructor directly, and then having the returned type be implementation details. Which means any type which contains a `Ref` is now either abstractly typed, or parameterized with a private type. Not to mention the mistake of having `Ptr <: Ref`.

On top of that, having the trio of immutable, mutable + const, and mutable wrapper structs, covers all the types of references to Julia objects I can think of.

Ideally, this stuff is so basic it should not go in a standalone package. Base’s references should be cleaned up, but I’m skeptical that it’s doable in a non-breaking manner. In any case, whether or not this eventually ends up in Base, having it in a package is a good start.

[Next page](https://discourse.julialang.org/t/ann-zerodimensionalarrays-jl-zero-dimensional-arrays-references-boxes/128002.md?page=2)
