A tiny software package for the Julia programming language, providing zero-dimensional array types. Ref-killer.
Exports these zero-dimensional subtypes of AbstractArray, differing on topics such as mutability and identity:
-
ZeroDimArray -
Box -
BoxConst -
ZeroDimArrayInTypeParameter
See their doc strings for more info!
Any zero-dimensional array is an iterator containing exactly one element (this follows from the zero-dimensional shape). Ref, too, is a zero-dimensional iterator, however it's not an array. Even though Ref supports being indexed like a zero-dimensional array is commonly indexed, without an index: x[].
The motivation for creating this package is:
-
To prevent the frequent confusion regarding
RefvsBase.RefValueby offering a replacement that makesRefunnecessary in many use cases. Previous discussion: -
To provide "mutable wrapper" functionality:
-
Boxcan be a good choice. Examples:-
make a
constbinding that's mutable:const some_const_binding = Box(0.2)
-
make a field within an immutable
structmutable (warning: it's usually more efficient to change the entirestructinto amutable struct)struct SomeImmutableType immutable_bool::Bool immutable_float::Float64 mutable_int::Box{Int} end
-
-
previous discussion:
-
-
To provide a boxing feature, for example for data deduplication to avoid excessive memory use. Either
BoxorBoxConstmight be a good choice here, depending on whether mutability is desired. Compare:-
julia> large_data = ntuple(identity, 8) (1, 2, 3, 4, 5, 6, 7, 8) julia> for _ ∈ 1:4 large_data = (large_data, large_data) end julia> Base.summarysize(large_data) 1024 julia> Base.summarysize([large_data for _ ∈ 1:1000]) # duplicates `large_data` a thousand times 1024040 julia> using ZeroDimensionalArrays julia> large_data_reference = Box(large_data); julia> Base.summarysize([large_data_reference for _ ∈ 1:1000]) # `large_data` isn't stored inline 9064
-
-
To provide a wrapper type for treating a value as a scalar in broadcasting:
-
ZeroDimArraycan be a good choice:julia> using ZeroDimensionalArrays julia> isa.([1,2,3], [Array, Dict, Int]) 3-element BitVector: 0 0 1 julia> isa.(ZeroDimArray([1,2,3]), [Array, Dict, Int]) # now escape the vector from broadcasting using `ZeroDimArray` 3-element BitVector: 1 0 0
The other types,
BoxorBoxConstwould work for this use case, too, as would any zero-dimensional array, butZeroDimArrayis more likely to have zero cost for performance. -
previous discussion regarding
Ref:
-
-
Zero-dimensional
Array:-
fill(x), creating a zero-dimensionalArraycontainingxas its element, is often used instead ofRef(x). -
Array{T, 0} where {T}is very similar toBox, albeit less efficient. The inefficiency is due to the fact that the implementation ofArraysupports resizeability (even though that's currently only available to users in the one-dimensional case ofVector), implying extra indirection, leading to extra pointer dereferences and extra allocation.
-
-
- Less heavy than
Array, but still may be less efficient thanBox.
- Less heavy than
-
- Zero-dimensional
Fill, constructible withFill(x), is equivalent toZeroDimArray.
- Zero-dimensional