I suspect that nested lambdas actually do not work. There are no tests with nested lambdas or even with "closures", where a lambda refers in its body to values that are not constants or its own parameters.
Mihai ________________________________ From: Limame Malainine via dev <[email protected]> Sent: Friday, February 20, 2026 6:52 AM To: [email protected] <[email protected]> Cc: Limame Malainine <[email protected]> Subject: Support for Nested Lambda Expressions and Lexical Scoping in RexLambda Hi Devs, I am looking into how Calcite handles nested lambda expressions, particularly as it relates to integrating with *Substrait <https://substrait.io/expressions/lambda_expressions/#lambdaparameterreference-fields>* . In Substrait, nested lambdas use a steps_out mechanism to reference parameters in parent scopes. For example: (outer_x) -> ((inner_y) -> add(outer_x, inner_y)) # - steps_out: 1 with struct_field: 0 -> outer_x # - steps_out: 0 with struct_field: 0 -> inner_y This would be the Calcite representation of the expression: The RexNode Hierarchy - *Top Level*: RexLambda - *Parameters*: [RexLambdaRef(name="outer_x", index=0)] - *Body*: (Another RexLambda) - *Parameters*: [RexLambdaRef(name="inner_y", index=0)] - *Body*: RexCall(op: ADD) - *Operand 0*: RexLambdaRef (refers to inner_y) - *Operand 1*: RexLambdaRef (refers to outer_x) I have a few questions regarding Calcite's RexLambda and RexLambdaRef: 1- Does Calcite natively support lexical scoping where an inner RexLambda body contains a RexLambdaRef pointing to a parameter defined in an outer RexLambda? 2- Is there a recommended way to represent this "depth" or "step out" logic within RexLambdaRef, or does Calcite assume the visitor/shuttle will manage the scope stack during traversal? Thanks, Limame Malainine
