C# Compiler bug or Subtle bug, I don't know, but this is certainly a doozy!
-
I have a problem with Lambda expression, looks like a C# compiler bug to me.... This piece of code
static void Main(string[] args)
{
var names = new List<string> { "Lloyd", "Stuart", "Gabe", "Mark" };
var actions = new List<Action>();
foreach (var item in names)
actions.Add(() => Console.WriteLine(item));
foreach (var a in actions)
a();
}Will print "Mark, Mark, Mark, Mark" Instead of "Lloyd, Stuart, Gabe, Mark" as it should.... I can fix it with the slightly modified version below..
static void Main(string[] args)
{
var names = new List<string> { "Lloyd", "Stuart", "Gabe", "Mark32" };
var actions = new List<Action>();
foreach (var item in names)
{
string s = item;
actions.Add(() => Console.WriteLine(s));
}
foreach (var a in actions)
a();
}But I think it's a C# compiler bug...
A train station is where the train stops. A bus station is where the bus stops. On my desk, I have a work station.... _________________________________________________________ My programs never have bugs, they just develop random features.
-
I have a problem with Lambda expression, looks like a C# compiler bug to me.... This piece of code
static void Main(string[] args)
{
var names = new List<string> { "Lloyd", "Stuart", "Gabe", "Mark" };
var actions = new List<Action>();
foreach (var item in names)
actions.Add(() => Console.WriteLine(item));
foreach (var a in actions)
a();
}Will print "Mark, Mark, Mark, Mark" Instead of "Lloyd, Stuart, Gabe, Mark" as it should.... I can fix it with the slightly modified version below..
static void Main(string[] args)
{
var names = new List<string> { "Lloyd", "Stuart", "Gabe", "Mark32" };
var actions = new List<Action>();
foreach (var item in names)
{
string s = item;
actions.Add(() => Console.WriteLine(s));
}
foreach (var a in actions)
a();
}But I think it's a C# compiler bug...
A train station is where the train stops. A bus station is where the bus stops. On my desk, I have a work station.... _________________________________________________________ My programs never have bugs, they just develop random features.
Yeah, it should print, "Chuck Norris,Chuck Norris,Chuck Norris,Chuck Norris". :-D
-
I have a problem with Lambda expression, looks like a C# compiler bug to me.... This piece of code
static void Main(string[] args)
{
var names = new List<string> { "Lloyd", "Stuart", "Gabe", "Mark" };
var actions = new List<Action>();
foreach (var item in names)
actions.Add(() => Console.WriteLine(item));
foreach (var a in actions)
a();
}Will print "Mark, Mark, Mark, Mark" Instead of "Lloyd, Stuart, Gabe, Mark" as it should.... I can fix it with the slightly modified version below..
static void Main(string[] args)
{
var names = new List<string> { "Lloyd", "Stuart", "Gabe", "Mark32" };
var actions = new List<Action>();
foreach (var item in names)
{
string s = item;
actions.Add(() => Console.WriteLine(s));
}
foreach (var a in actions)
a();
}But I think it's a C# compiler bug...
A train station is where the train stops. A bus station is where the bus stops. On my desk, I have a work station.... _________________________________________________________ My programs never have bugs, they just develop random features.
ReSharper gives a warning about that. Let's just keep it at a feature.
-
I have a problem with Lambda expression, looks like a C# compiler bug to me.... This piece of code
static void Main(string[] args)
{
var names = new List<string> { "Lloyd", "Stuart", "Gabe", "Mark" };
var actions = new List<Action>();
foreach (var item in names)
actions.Add(() => Console.WriteLine(item));
foreach (var a in actions)
a();
}Will print "Mark, Mark, Mark, Mark" Instead of "Lloyd, Stuart, Gabe, Mark" as it should.... I can fix it with the slightly modified version below..
static void Main(string[] args)
{
var names = new List<string> { "Lloyd", "Stuart", "Gabe", "Mark32" };
var actions = new List<Action>();
foreach (var item in names)
{
string s = item;
actions.Add(() => Console.WriteLine(s));
}
foreach (var a in actions)
a();
}But I think it's a C# compiler bug...
A train station is where the train stops. A bus station is where the bus stops. On my desk, I have a work station.... _________________________________________________________ My programs never have bugs, they just develop random features.
-
The bug is in your understanding of how the C# compiler captures free variables.
xacc.ide - now with TabsToSpaces support
IronScheme - 1.0 beta 1 - out now!
((lambda (x) `((lambda (x) ,x) ',x)) '`((lambda (x) ,x) ',x))I figured that out, but I think it's subtle!.. Although, truth to tell, I didn't gave much though to that, I just thought "ho cool, like in Java" and went on...
A train station is where the train stops. A bus station is where the bus stops. On my desk, I have a work station.... _________________________________________________________ My programs never have bugs, they just develop random features.
-
The bug is in your understanding of how the C# compiler captures free variables.
xacc.ide - now with TabsToSpaces support
IronScheme - 1.0 beta 1 - out now!
((lambda (x) `((lambda (x) ,x) ',x)) '`((lambda (x) ,x) ',x)) -
SO what is the compiler doing behind the scenes?
Today's lesson is brought to you by the word "niggardly". Remember kids, don't attribute to racism what can be explained by Scandinavian language roots. -- Robert Royall
dan neely wrote:
SO what is the compiler doing behind the scenes?
It hoists the local variables used in a 'subscope' from the current scope into a 'closure' class. All references to hoisted variables even outside the 'subscope' is referenced via the closure.
xacc.ide - now with TabsToSpaces support
IronScheme - 1.0 beta 1 - out now!
((lambda (x) `((lambda (x) ,x) ',x)) '`((lambda (x) ,x) ',x)) -
The bug is in your understanding of how the C# compiler captures free variables.
xacc.ide - now with TabsToSpaces support
IronScheme - 1.0 beta 1 - out now!
((lambda (x) `((lambda (x) ,x) ',x)) '`((lambda (x) ,x) ',x))Bugs can be a lot of things, even language design and semantics can be riddled with "bugs". This is just one example of how unintuitive things can get when lambda functions are implemented the "wrong" way. The problem is that the runtime doesn't capture the dynamic environment when the lambda function "Console.WriteLine(...)" is created, which would be what I believe is the intuitive thing to do. If lambda functions had been implemented "the right way", the dynamic environment as it existed when the lambda function was defined would have been preserved.
-
Bugs can be a lot of things, even language design and semantics can be riddled with "bugs". This is just one example of how unintuitive things can get when lambda functions are implemented the "wrong" way. The problem is that the runtime doesn't capture the dynamic environment when the lambda function "Console.WriteLine(...)" is created, which would be what I believe is the intuitive thing to do. If lambda functions had been implemented "the right way", the dynamic environment as it existed when the lambda function was defined would have been preserved.
antoncl wrote:
If lambda functions had been implemented "the right way", the dynamic environment as it existed when the lambda function was defined would have been preserved.
It is being preserved, but you, the user, is modifying the value of the captured variable outside the closure. And by design the closure should see the side-effect. This is exactly the way any language with lexically scoped closures would behave, like Scheme (and probably python and ruby and F#), but NOT Common Lisp.
xacc.ide - now with TabsToSpaces support
IronScheme - 1.0 beta 1 - out now!
((lambda (x) `((lambda (x) ,x) ',x)) '`((lambda (x) ,x) ',x))