Skip to content

allow vcat on single ChainedVector - #96

Merged
quinnj merged 2 commits into
JuliaData:mainfrom
stuartthomas25:main
Aug 5, 2026
Merged

allow vcat on single ChainedVector#96
quinnj merged 2 commits into
JuliaData:mainfrom
stuartthomas25:main

Conversation

@stuartthomas25

@stuartthomas25 stuartthomas25 commented Mar 19, 2024

Copy link
Copy Markdown
Contributor

Formerly, vcat(a::ChainedVector) failed with an error. This PR makes one-input vcat return an unaliased ChainedVector, matching the typical Julia behavior that vcat(a) == a but vcat(a) !== a.

It also adds wrapper-preserving unaliasing for nested ChainedVector and SentinelArray storage, with regression tests for identity, mutation isolation, missing and sentinel values, heterogeneous chunks, nesting, and inference.

Co-authored by Codex

Formerly, `vcat(a::ChainedVector)` would fail with an error.
@codecov

codecov Bot commented Mar 19, 2024

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.64%. Comparing base (fa840f9) to head (0e73ea6).
⚠️ Report is 18 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #96      +/-   ##
==========================================
+ Coverage   94.82%   95.64%   +0.82%     
==========================================
  Files           5        5              
  Lines        1043     1056      +13     
==========================================
+ Hits          989     1010      +21     
+ Misses         54       46       -8     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@JoaoAparicio

Copy link
Copy Markdown
Contributor

One observation: The typical Julia behavior is that vcat copies its inputs:

x = [1,2,3]
vcat(x) === x  # false

whereas here

x = ChainedVector([[1,2,3],[4,5]])
vcat(x) === x  # true

Comment thread src/chainedvector.jl Outdated
Comment on lines 632 to 634
Base.vcat(A::ChainedVector{T, AT}) where {T, AT <: AbstractVector{T}} = A

function Base.vcat(A::ChainedVector{T, AT}, arrays::ChainedVector{T, AT}...) where {T, AT <: AbstractVector{T}}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest folding this into the same method, either with a fast path like

Suggested change
Base.vcat(A::ChainedVector{T, AT}) where {T, AT <: AbstractVector{T}} = A
function Base.vcat(A::ChainedVector{T, AT}, arrays::ChainedVector{T, AT}...) where {T, AT <: AbstractVector{T}}
function Base.vcat(A::ChainedVector{T, AT}, arrays::ChainedVector{T, AT}...) where {T, AT <: AbstractVector{T}}
isempty(arrays) && return Base.unaliascopy(A)

or by fixing the source of the error directly by passing init=0 to sum a few lines down. (The latter would require bumping the minimum Julia compat to at least 1.6, but IMO that's fine.)

Return a wrapper-preserving copy for one-argument vcat.

Teach SentinelArray and nested ChainedVector storage how to make
unaliasing copies. Add coverage for identity, mutation isolation,
missing and sentinel values, heterogeneous chunks, nesting, and
inference.
@quinnj
quinnj merged commit 0a3363f into JuliaData:main Aug 5, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants