Lambda Expressions

From RemObjects Software

Jump to: navigation, search

This is a Oxygene Language Feature topic
Feel free to add your notes to this topic below.



What Are Lambda Expressions?

Lambda expressions are a special type of expression that can be best thought of as mapping a set of one or more values to a result, using a function. Lambda expressions are most notable used with the Query Operators that form the basis of Query Expressions, but can technically be used wherever a matching delegate of future is expected.

Discussion of lambda expressions is perhaps best started with an example, so the following code shows a lambda expression used with the "Where" method introduced by LINQ:

var MyCustomers: sequence of Customer;
//...
MyCustomers.Where(c -> c.Name = 'Smith');

As you can see, the lambda expression consists of an input variable (or possibly several input variables grouped using parenthesis), the "->" operator and an expression that typically uses the input variables to calculate the result.

Technically speaking, the lambda expression defines an anonymous method, so

c -> c.Name = 'Smith'

could be considered a shortcut for writing

method (c: ''type1''): ''type1'';
begin
  result := c.Name = 'Smith';
end;

where the type of "c" (type1) and of the result (type2) are inferred from the context; in this case, "MyCustomers.Where" expects a delegate where the input is a Customer and the result is a Boolean.

When used with the Query Operators, lambda expressions have several advantages over passing an anonymous method or a normal delegate (though both of these options are of course available):

  • Firstly, Lambda Expressions are much more concise, and work better "inline", especially when concatenating several Standard Query Operators in the same statement.
  • Secondly, as stated above, types are automatically inferred by the compiler based on the context (usually the type of sequence the SQO is being applied to).

Most importantly though, depending on the context and the used SQO, lambda expressions can either be compiled to managed code like the rest of your application, or can be translated into so called Expression Trees, for remote execution.


Using Lambda Expressions In Oxygene

Lambda expressions are extremely usefull when working with the standard query operators in LINQ:

var myList := new List<Person>;
myList.Add(new Person(Name := 'Albert', Age := 32));
myList.Add(new Person(Name := 'Chris', Age := 26));
//...
var youngOnes := myList.Where(p -> p.Age < 30); //sequence of people younger than 30

Oxygene will infer the type of the parameter from the delegate that is expected at this place. Of course you can have lambdas returning something else than a boolean:

var nameAndAge := myList.Select(p -> p.Name+' ('+p.Age.ToString+')'); //e.g. "Albert (32)"

Oxygene infers the return type and creates a String in this case (Select, in turn, then return a sequence of String.

Lambda expressions don't have to return a result at all, they can also be used as actions:

var printOut : Action<String> := s -> Console.WriteLine(s);
printOut('foo');


Paremeter-less Lambda Expressions

Starting with version 3.0, Oxygene supports lambda expressions without parameters, simply by omitting the operand to the left of the -> operator. for example

var r: future Int32 := -> 6*8;


Example: QuickSort Using A Lambda Expression

When you talk to guys that like the programming language "Haskell", they always show you how short they can write a QuickSort in Haskell. Well, with lambda expressions you can do it in the same way in Oxygene:

private fSort : Func<List<Int32>, List<Int32>>;
  (*...*)
fSort :=  xs -> iif(xs.Count = 0, new List<Int32>,
                    fSort(xs.Where(y -> y < xs[0]).ToList).Concat([xs[0]]).Concat(fSort(xs.Where(y -> y > xs[0]).ToList)).ToList);

The lambda returns an empty list if it is applied to an empty list. Otherwise it will take the first element of the input list as the middle element for the result list. In front of that it will insert all smaller elements, after it all bigger elements, in both cases sorted by a recursive call to the lambda expression. And no, that's not a very clever implementation regarding performance and readability, but it shows how powerfull lambda expressions can be.

External Links

See Also


Product: RemObjects Oxygene (formerly known as Chrome)
Current version: 3.0 Previous Versions: 'Joyride' (2.0), 'Floorshow' (1.5), 'Adrenochrome' (1.0)

GlossaryKeywordsLanguage FeaturesPlatform FeaturesSamplesArticlesHow ToIssues

Personal tools