Repository navigation
Conversation
Partially applying a native function now wraps the function itself as the lambda body (bodyAST.body = native) instead of generating a trampoline expression that calls the builtin by name. As in JS, the signature of the native function is not validated when the partial is invoked. - implement applyNativeFunction / getNativeFunctionArguments - only '?' leaves a parameter unbound, missing args are bound to null (#86) - fix '?' comparison (token value is a Character) - no lookup by name, so unnamed / custom JFunctions work (#83) - arity of a JFunctionCallable is taken from its signature - $each / $merge iterate arrays like JS for..in (#79) - fix inverted T1007 check Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- JLambda (Fn0..Fn8) reports its number of declared parameters, which JFunctions created via Jsonata.function(...) keep - arity unknown (callable / FnVarArgs without signature): use the number of args supplied at the partial application - implement the JS "typeof proc === 'function'" branch: lambdas bound via Frame.bind can be partially applied Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tests contributed by @sergeevik in the earlier PRs, adapted to the existing API. All pass with the partial application changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aeberhart
commented
Nov 4, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
might be better to split this large PR into the following smaller parts:
|
sergeevik
reviewed
Nov 4, 2026
| var evaluatedArgs = new ArrayList<>(); | ||
| for(var ii = 0; ii < ((Symbol)result).body.arguments.size(); ii++) { | ||
| evaluatedArgs.add(/* await */ evaluate(((Symbol)result).body.arguments.get(ii), ((Symbol)result).input, ((Symbol)result).environment)); | ||
| for(var ii = 0; ii < ((Symbol)((Symbol)result).body).arguments.size(); ii++) { |
Contributor
There was a problem hiding this comment.
maybe extract (Symbol)result to var?
so many cast. so many code. and now it's twice cast
sergeevik
reviewed
Nov 4, 2026
| if (next instanceof Symbol) // Java: not if JFunction | ||
| ((Symbol)next).token = ((Symbol)result).body.procedure.value; | ||
| ((Symbol)next).token = ((Symbol)((Symbol)result).body).procedure.value; | ||
| } |
Contributor
There was a problem hiding this comment.
bad formatting
closing parenthesis looks like for "if (next instanceof Symbol)" but not
Contributor
Author
|
closing this PR. will be done in 3 smaller steps |
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.
Fixes #95, #79, #83, #86
Root cause
jsonata-js partially applies a native function by building
function($a, $b){ _ }and replacing the body with the native function (bodyAST.body = native). When invoked,applyProcedurecallsapplyNativeFunction, which does not validate the signature. The Java port instead generated a trampoline that called the builtin by name ($each($a, $b)), so the signature was checked again and the function had to be looked up by name.Changes (following the JS code)
partialApplyNativeFunctionsetsbodyAST.body = _native(Symbol.bodyis nowObject); implemented the commented-outapplyNativeFunction/getNativeFunctionArgumentsand the native branch inapplyProcedurepartialApplyProcedure: only?leaves a parameter unbound; missing args are bound to null like JS bindsundefined(incorrect result when $map($, $append(?)) #86)?comparison: the token value is aCharacter, soarg.value.equals("?")was always falseJFunctions work (Custom function pipe error #83)$each/$mergeiterate arrays like JSfor..in(string index keys), since the signature is no longer enforced for partials (Incorrect each function signature validation #79)proc != nullvs JStypeof proc === 'undefined')typeof proc === 'function'branch:Fn*lambdas bound viaFrame.bind(...)can be partially appliedArity of Java functions
JS takes the parameters of a native function from
func.toString(). In Java,JFunction.getNumberOfArgs()now uses, in order:MethodJLambda(Fn0–Fn8→ 0–8), kept by theJsonata.function(...)factoriesJFunctionCallable/FnVarArgswithout signature): the number of args supplied at the partial application, e.g.$add(?, 3)→ 2. This is the only deviation from JS (no dropping of extra args / binding of missing ones)API note
JLambdawas an empty marker interface and now declaresgetJFunctionCallable()and a defaultgetNumberOfArgs(). AllFn*types implement them; a class implementingJLambdadirectly would need to addgetJFunctionCallable().Testing
New
PartialTest(11 cases); full suite: 1747 tests pass, also with-Dmaven.compiler.release=11. Compared 31 partial-application expressions against jsonata-js 2.1.0.🤖 Generated with Claude Code