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
> 

Reply via email to