Skip to content

Use bounds checks for keyword indices - #32

Merged
penelopeysm merged 3 commits into
mainfrom
use-keyword-bounds-checks
Nov 1, 2026
Merged

penelopeysm merged 3 commits into
mainfrom
use-keyword-bounds-checks

Conversation

@BJMCox

@BJMCox BJMCox commented Nov 1, 2026

Copy link
Copy Markdown
Member

Closes #31. Base for #29.

Use keyword bounds checks for standard indices, so an out-of-bounds lookup returns false without trying getindex. Keep native indexing as the fallback for other selectors and arrays without keyword bounds methods.

The fallback remains necessary after DimensionalData #1183. This reproduces without loading VarNames in both DimensionalData 0.30.2 and 0.30.3:

using DimensionalData

x = DimArray([1.0, 2.0, 3.0], (:i,))
x[i=Not(1)]                    # [2.0, 3.0]
checkbounds(Bool, x; i=Not(1)) # throws ArgumentError

The keyword bounds method dispatches through Dimension{<:StandardIndices}. Not(1) falls outside that type, although getindex accepts it. Trying and catching that error on every lookup makes valid Not indexing much slower. The guard therefore sends nonstandard selectors straight to the existing fallback. It also checks that a keyword bounds method exists before calling it.

Raise the test-only DimensionalData minimum to 0.30.2, which first includes keyword bounds checks. Add cases for out-of-bounds keywords, range/colon selectors and arrays without keyword bounds methods. Existing Not tests retain coverage of the selector fallback.

Validation: all 51,414 tests pass. Lookup tests also pass on DimensionalData 0.30.2 and 0.30.3. Benchmarks retain the allocation counts for valid lookups. Invalid integer-keyword lookup uses no allocations and skips getindex, instead of throwing and catching a bounds error.

Reject out-of-bounds keyword indices before retrieving values. Keep the native indexing fallback for unsupported selectors and providers so existing Not indexing remains correct and fast.
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown

Docs preview for PR #32

Comment thread src/varname/hasvalue.jl Outdated
# However, there's no `checkbounds` method (yet):
# https://github.com/rafaqz/DimensionalData.jl/issues/1156

@inline function _canview_kw(optic::Index, x)

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.

Curious, is there a reason to inline?

BJMCox and others added 2 commits November 1, 2026 14:08
Fresh-process comparisons show overlapping timings and identical allocation counts with and without the annotation. Let the compiler choose whether to inline the helper.
@penelopeysm
penelopeysm merged commit c816260 into main Nov 1, 2026
7 checks passed
penelopeysm added a commit that referenced this pull request Nov 1, 2026
Closes #27. Stacked on #32.

Support native indexing in `canview` and `getvalue` for `Tuple`, `Ref`
and custom containers, including dynamic indices, keyword indices and
nested fields.

```julia
getvalue((y=(1.0,),), @vn(y[1]))  # 1.0
getvalue((y=Ref(2.0),), @vn(y[])) # 2.0
```

Containers without a bounds interface use their native `getindex`.
Concrete Tuple and Ref leaf lookups use bounds or assignment checks
directly, avoiding an exception-handling fallback in log-density and
gradient evaluation. Numbers and characters retain their existing scalar
meaning. Interrupts from fallback access propagate.

Validation: all 51,437 tests pass. Tests pair successful `hasvalue` and
`getvalue` calls and cover custom positional/keyword indexers, nested
and dynamic access, invalid paths, and unassigned refs. Wren integration
probes restore the prior Tuple/Ref log-density and Enzyme gradient
timings with no allocations. Array and custom lookups also remain
allocation-free, with a small cost for checking existence compared with
Wren's previous unchecked getter.

---------

Co-authored-by: Penelope Yong <penelopeysm@gmail.com>
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.

Update getvalue/hasvalue for kwarg indices

2 participants