Oops, I should have referenced de Bruijn indexes [2], not notation. [2] https://en.wikipedia.org/wiki/De_Bruijn_index
> On Feb 20, 2026, at 5:56 PM, Julian Hyde <[email protected]> wrote: > > Limame, > > Do you know of any databases that support closures? > > It’s ironic. It was the very limited support for lambdas in dialects like > Spark SQL, and the difficulty of doing lambdas properly — with changes to the > type system and scoping rules — that drove me to create Morel. > > Are “depth” and “step_out” related to de Bruijn notation [1]? > > Julian > > [1] https://en.wikipedia.org/wiki/De_Bruijn_notation > > >> On Feb 20, 2026, at 5:30 PM, Mihai Budiu <[email protected]> wrote: >> >> 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 >
