Skip to main content
This revision made December 13, 2011 21:29, by Kin-man Chung

Lambda Expression in EL

To support query expressions on collections, it is necessary to pass EL expressions as argument to methods. These expressions will be evaluated in the methods. So essentially we need closures in EL. Fortunately, EL already has the concept of deferred expressions, so we just need to put the pieces together to add lambda expressions to EL.

An EL lambda expression is a deferred expression with parameters.

Syntax

The proposed syntax follows that of the one jsr 335 edr

Lambda Expression cannot be nested.

Grammar:

  Lambda := LambdaParameters '->' Expression
  LambdaParameters := identifier | '(' Parmeters ')'
  Paramters := (identifier (',' identifier)*)?
  

Example:

  #{ 42 }
  ${x -> x+1}
  #{x,y -> x+y}

Operations on Lambda Expression

  • It can be assigned to a variable:
    fn = #{x -> x+1}
  • It can be invoked:
    fn(100) yields 101
    #{x, y -> x+y}(3,4) yields 7
  • It can be passed to a method:
    employees.where(#{p->p.name.first == 'Larry'})

API

  • A couple of methods in ELContext for managing arguments for lambda expressions, making it easy to set up arguments for calling the lambda expression, and to remove the arguments from ELContext after the call. See here
  • A new class LambdaExpression to encapsulate the EL Lambda expression, and to call it with arguments.


Additional Considerations

  • Current EL insists that functions be bound and mapped at parse time. This will not work well with lambda, which may be evaluated another JVM or even another machine. We'll need to consider lazy and late function binding at evaluation time.
Difference compared to previous revision
<span>Lambda Expression cannot be nested. Grammar: Lambda := <span style="text-decoration:underline;color:green">LambdaParameters </span>=Lambda Expression in EL= To support query expressions on collections, it is necessary to pass EL expressions as argument to methods. These expressions will be evaluated in the methods. So essentially we need closures in EL. Fortunately, EL already has the concept of deferred expressions, so we just need to put the pieces together to add lambda expressions to EL. An EL lambda expression is a deferred expression with parameters. ... Lambda Expression cannot be nested. Grammar: Lambda := '<span style="text-decoration:line-through;color:red">#{</span>'<span style="text-decoration:underline;color:green">-></span>' <span style="text-decoration:line-through;color:red"> (A</span><span style="text-decoration:underline;color:green">Exp</span>r<span style="text-decoration:line-through;color:red">gL</span><span style="text-decoration:underline;color:green">ess</span>i<span style="text-decoration:underline;color:green">on LambdaParameter</span>s<span style="text-decoration:underline;color:green"> := iden</span>t<span style="text-decoration:underline;color:green">ifier</span> <span style="text-decoration:underline;color:green">| </span>ist '<span style="text-decoration:line-through;color:red">-></span>'<span style="text-decoration:underline;color:green">(</span><span style="text-decoration:line-through;color:red">)?</span> <span style="text-decoration:line-through;color:red">Body</span>' <span style="text-decoration:underline;color:green">Parmeters</span> '<span style="text-decoration:line-through;color:red">}</span><span style="text-decoration:underline;color:green">)</span>' <span style="text-decoration:line-through;color:red">A</span><span style="text-decoration:underline;color:green">Pa</span>r<span style="text-decoration:line-through;color:red">gLis</span><span style="text-decoration:underline;color:green">am</span>t<span style="text-decoration:underline;color:green">ers</span>t := <span style="text-decoration:line-through;color:red">I</span> := <span style="text-decoration:underline;color:green">(i</span>dentifier (',' <span style="text-decoration:line-through;color:red">I</span><span style="text-decoration:underline;color:green">i</span>dentifier)*<span style="text-decoration:line-through;color:red"> Body := Expression</span><span style="text-decoration:underline;color:green">)?</span> Example: #{ 42 }<span>
 
 
Close
loading
Please Confirm
Close