InfoQ Homepage News C# Futures: Closure Annotations

# C# Futures: Closure Annotations

Leia em Português

Though on the “Some Interest” list, the next proposal is very controversial. The basic premise for the Lambda Capture Lists proposal is that it would allow more control over how variables are captured in closures.

The proposal begins with capture lists, a concept seen in C++. Here is an example of a normal closure and one with a capture list:

var x = 100;
Func<int> a = () => x * 2;
Func<int> b = [x] () => x * 2;

If this syntax is used, any variable not in the capture list (denoted by brackets [x]) cannot be used inside the anonymous function without triggering a compiler error. If you use an empty list, [], then it will guarantee a closure won’t be created. This can help performance, as non-closure anonymous functions don’t require a memory allocation.

To access the current object from the closure, you would use [this]. This would reduce the occurrences of accidentally capturing the current object, which can lead to memory leaks.

Capturing by Value

There are times when you only need a copy of value inside the closure and don’t want to actually share a variable between the two. Under this proposal, you can indicate that using the capture list.

Func<int> c = [int xCopy = x]() => xCopy * 2;

This is very verbose, so alternatives are being suggested that would mean the same thing.

Func<int> d = [value x]() => x * 2; //this x is a copy Func<int> e = [val x]() => x * 2; //this x is a copy Func<int> f = [let x]() => x * 2; //this x is a copy Func<int> g = [=x]() => x * 2; //this x is a copy

In order to make the normal by reference closure more explicit, this syntax was proposed:

Func<int> h = [ref x]() => x * 2; //x is an alias Func<int> i = [&x]() => x * 2; //x is an alias

Related to this is the “skinny arrow” proposal. This would implicitly capture all variables by value.

Func<int> j = () -> x * 2; //this x is a copy

Weak Captures

As mentioned before, closures that outlast the function that creates them are a common source of memory leaks. So Miguel do Icaza suggested that weak references be included in the proposal. Stephen Toub offered this syntax for it:

Action k = [weak myObject] () => […] Action l = [weak this] () => […] Action m = [wro = new WeakReference(myObject)] () => […]

Criticism

As mentioned in the introduction, this proposal is controversial. No matter which variants you choose, this new syntax add a lot of visual clutter to the code. And for shorter closures, it doesn’t add much information that you wouldn’t already have.

Adding the capture list has to be optional for backwards compatibility. Given how tedious it is, most developers will probably just not bother to type it, which would bring into doubt the usefulness of the feature at all.

Style

## Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

• ##### Capture lists not necessary

by Jules Jacobs /

• ##### Re: Capture lists not necessary

by arnaud m /

• ##### Capture lists not necessary

by Jules Jacobs /

Your message is awaiting moderation. Thank you for participating in the discussion.

There is no reason to include a capture list since you can already see what is captured by looking at the code in the closure. Don't repeat yourself. The by value capture and weak reference capture could be done like so:

const int xCopy = x;
Func<int> f = () => xCopy * 2;

var wro = new WeakReference(myObject);
Func<int> f = () => ...;

• ##### Re: Capture lists not necessary

by arnaud m /

Your message is awaiting moderation. Thank you for participating in the discussion.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Is your profile up-to-date? Please take a moment to review and update.

Note: If updating/changing your email, a validation request will be sent

Company name:
Company role:
Company size:
Country/Zone:
State/Province/Region:
You will be sent an email to validate the new email address. This pop-up will close itself in a few moments.