There is currently no support for lambda expressions, as in C#, but we do support anonymous methods. These are specified as a code block delimited by keywords DELEGATE and END-DELEGATE and containing a procedure division header and a code block.
I'm going to paste in a program showing how you can use method invocation syntax to access LINQ-type extension methods (in this case the Where method in System.Linq.Enumerable). The program also shows the use of some experimental LINQ style syntax, which is not currently functional, but may included in future versions of the product.
Note that this program uses some of our new syntax for portable collection classes (i.e. portable between the .NET and JVM worlds), but these statements (CREATE, WRITE etc.) can easily be replaced by standard construction expression or method invocations.
$set sourceformat"Variable"
$set ilref"System.Core.dll"
$set ilusing"System"
$set ilusing"System.Collections.Generic"
program-id. Program2 as "Linq.Program2".
procedure division.
declare myList as list[binary-long]
create myList
write myList from 10
write myList from 9
write myList from 11
write myList from 999
declare func as type Func[binary-long condition-value] = method type a::Select
declare myEnumerable as type IEnumerable[binary-long]
display "Using type inference and delegate instance"
*> invoke 'Where' method, explicitly passing a parameter of type
*> Func[binary-long, condition-value]
*> In this case the compiler infers the generic parameter type
set myEnumerable to myList::Where(func)
perform varying i1 as binary-long through myEnumerable
display i1
end-perform
display "Using type inference and method group"
*> Here the parameter passed is a 'method group', which is implicitly converted
*> into the correct delegate type (Func[binary-long, condition-value)
set myEnumerable to myList::Where(method type a::Select)
perform varying i1 as binary-long through myEnumerable
display i1
end-perform
display "Using type inference and anonymous method"
*> Here the parameter is specified as an anonymous method, i.e. the code
*> between the delegate/end-delegate delimiters.
set myEnumerable to myList::Where
(delegate using i2 as binary-long returning ret as condition-value
if i2 > 10
set ret to true
else
set ret to false
end-if
end-delegate
)
perform varying i1 as binary-long through myEnumerable
display i1
end-perform
$if 0 = 1
display "Using LINQ syntax"
*> This last example does the same thing, but using experimental LINQ-like
*> syntax. Currently this is not documented and not guaranteed...
set myEnumerable to select i from mylist where i > 10
perform varying i1 as binary-long through myEnumerable
display i1
end-perform
$end
goback.
end program.
class-id a.
method-id Select static.
procedure division using by value i as binary-long
returning ret as condition-value.
if i > 10
set ret to true
else
set ret to false
end-if
end method.
end class.