Clarify local scope semantics and add explicit type check in SumLocalStep - #3616
Open
xiazcy wants to merge 1 commit into
Open
Clarify local scope semantics and add explicit type check in SumLocalStep#3616xiazcy wants to merge 1 commit into
xiazcy wants to merge 1 commit into
Conversation
… boxing semantics Add an instanceof Number guard in SumLocalStep to deterministically reject non-numeric input on the single-element path, fixing a JIT-dependent type-erasure hole where sum(local) on a non-numeric scalar would sometimes pass through as identity instead of erroring. Document the Scope.local boxing/wrapping contract in the semantics doc (scalars are coerced to single-element sequences) and add tests locking the behavior for sum, mean, min, and max local steps, plus the IteratorUtils singleton-wrapping contract. Assisted-by: Kiro:claude-opus-4 [kiro-cli]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a non-deterministic type-safety hole in
SumLocalStepand documents theScope.localboxing semantics in theprovider semantics specification.
Problem
sum(local)on a single non-numeric scalar (e.g.g.inject("hello").sum(local)) would non-deterministically eitherthrow
ClassCastExceptionor pass the value through as identity, depending on JIT compilation state. This is becausethe generic bound
E extends Numberis erased at runtime, and the arithmetic call that would enforce it(
NumberHelper.add) is only reached when there are 2+ elements.mean(local)was already correct (always callsdiv()), whilemin(local)/max(local)are unaffected (they useComparablebounds, andNumberHelper.min/maxcorrectly falls back to
compareTofor non-Numbers).Fix
Added an explicit
instanceof Numbercheck inSumLocalStepafteruntilNonNull()returns the first element, makingthe error deterministic.
Documentation
Added a "Local scope and single values" section (
[[gremlin-semantics-local-scope-boxing]]) togremlin-semantics.asciidocspecifying:sum(local)on29→29)Tests
Sum.feature):sum(local)on a non-numeric list (error) and a single non-numeric scalar (error),with GLV translations for .NET, Go, JS, Python
SumLocalStepTest): numeric scalar identity + non-numeric errorMeanLocalStepTest): numeric scalar identity + non-numeric errorMinLocalStepTest): numeric identity, String identity (valid Comparable), String-list min, numeric-listmin
MaxLocalStepTest): numeric identity, String identity, String-list max, numeric-list maxIteratorUtilsTest): Number singleton wrapping + generic Object singleton wrappingVOTE +1