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

Reply via email to