BT

C# Futures: Closure Annotations

| by Jonathan Allen Follow 576 Followers on May 04, 2015. Estimated reading time: 2 minutes |

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.

Rate this Article

Adoption Stage
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.

Tell us what you think

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

Email me replies to any of my messages in this thread

Capture lists not necessary by Jules Jacobs

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

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

Email me replies to any of my messages in this thread

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

Email me replies to any of my messages in this thread

2 Discuss

Login to InfoQ to interact with what matters most to you.


Recover your password...

Follow

Follow your favorite topics and editors

Quick overview of most important highlights in the industry and on the site.

Like

More signal, less noise

Build your own feed by choosing topics you want to read about and editors you want to hear from.

Notifications

Stay up-to-date

Set up your notifications and don't miss out on content that matters to you

BT