BT

The Dark Side of Closures

by Jonathan Allen on Sep 28, 2007 |

Closures are not a new concept and in LINQ have proven to be incredibly useful. But they do have a dark side when used to break encapsulation. When two seemingly independent functions are tied together, unexpected results can occur.

Closures allow functions to share their local variables with anonymous functions defined within them. These anonymous functions, often referred to as lambdas, are essential to creating the strongly typed queries exposed by LINQ.

In his experiments with LINQ, Dustin Campbell discovered that queries could be altered while they were running. That's right, by changing a local value that was closed over, the function used in the where clause is modified. If this is done while the query is running, the query may acknowledge that change and respond accordingly.

Dustin uses this trick to create a query that only returns distinct items. To start with, the where clause is set to the expression "m.Name != filter". Each time an item is returned, the value of filter is updated to be the last name returned. Under the right circumstances, this can effectively create a list of distinct items.

However, it is an incredibly fragile technique. In Dustin's case, the list had to sorted prior to applying the where clause. If done the other way around, all the filtering will occur before any items are returned and there will be no chance to alter it. This can be done in LINQ because where and order by clauses can appear in any order.

Something Dustin did not mention is that this will not work for all providers. Those that send the query to an outside engine like LINQ to SQL will also not get a chance to alter the where clause. It gets even worse if you try to use Parallel LINQ. Because it is running on multiple threads, any change to the where clause will result in a race condition.

Of course the right answer is to simply call Distinct() and be done with it. While these tricks are academically interesting, they are certain to lead to subtle bugs and are very susceptible to changes in the framework.

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

The dark side of Java by Eirik Maus

Non-private static variables can be used like global variables, breaking encapsulation, OO-principles and the like. BOOHAA! Java is probably useless until 'static' is removed.

Re: The dark side of Java by Jonathan Allen

While technically true, closures are a lot more subtle than static variables. You can always tell a static variable by looking at its definition; closures require you to read the entire method for instances of the variable. Thus more care needs to be taken with them.

Misnamed by Rafael de F. Ferreira

This entry really should have been named "The dark side of mutable state". If your procedure values only close over immutable state, this "problem" simply disappears.

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

3 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT