tag:blogger.com,1999:blog-15136575.post1464299996301677375..comments2023-10-17T12:00:16.772+01:00Comments on Code rant: What is a Closure?Mike Hadlowhttp://www.blogger.com/profile/16441901713967254504noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-15136575.post-55737409778220170422012-01-01T15:03:03.077+00:002012-01-01T15:03:03.077+00:00omg you misspelled Jon Skeet's name ;)omg you misspelled Jon Skeet's name ;)Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-81357548223769940902011-07-13T22:00:39.340+01:002011-07-13T22:00:39.340+01:00Ok, I see what you're saying. As long as actio...Ok, I see what you're saying. As long as <i>action</i> is in scope, then even if <i>x</i> is no longer in scope, by virtue of being captured by <i>action</i> it will remain accessible within <i>action</i>. In the example, without showing <i>x</i> going out of scope it wasn't obvious where the magic was happening. Jon Skeet has a good example of this over on <a href="http://stackoverflow.com/questions/428617/what-are-closures-in-net/428624#428624" rel="nofollow">SO</a>.David Clarkehttp://www.zebracrossing.co.nznoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-10415292414689227552011-07-13T15:37:35.930+01:002011-07-13T15:37:35.930+01:00Nice article, thanks.
I've written a bit more...Nice article, thanks. <br />I've written a bit more thorough one about <a href="http://blog.mostof.it/why-ruby-part-two-blocks-and-closures/" rel="nofollow">Ruby blocks and closures</a>Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-48306839756018396342011-07-13T11:45:54.674+01:002011-07-13T11:45:54.674+01:00Hi David,
"I don't think your example is...Hi David,<br /><br />"I don't think your example is a closure" - well we'll have to disagree then :)Mike Hadlowhttps://www.blogger.com/profile/16441901713967254504noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-14552274595223543502011-07-12T21:48:58.583+01:002011-07-12T21:48:58.583+01:00I don't think your example is a closure but I&...I don't think your example is a closure but I'm happy to be educated otherwise. I tend to fall back on my knowledge of closures in javascript for this. Consider (<a href="http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example" rel="nofollow">ref</a>):<br /><br />var funcs = {};<br />for (var i = 0; i < 3; i++) { // create 3 functions<br /> funcs[i] = function() { // and store them in funcs<br /> console.log("My value: " + i); // each should log value<br /> };<br />}<br />for (var j = 0; j < 3; j++) {<br /> funcs[j](); // and now run each one<br />}<br /><br />It outputs this:<br /><br /> My value: 3<br /> My value: 3<br /> My value: 3<br /><br />Want it to output:<br /><br /> My value: 0<br /> My value: 1<br /> My value: 2<br /><br />This is a fairly common mistake in javascript and crops up e.g. when trying to assign eventhandlers in a loop. One resolution is to introduce an intermediate function to capture the loop variable which will give the desired output:<br /><br />var funcs = {};<br />for (var i = 0; i < 3; i++) { /* let's create 3 functions */<br /> funcs[i] = function(k) { /* and store them in funcs */<br /> return function() {<br /> console.log("My value: " + k); /* each should log its value */<br /> }<br /> }(i);<br />}<br />for (var j = 0; j < 3; j++) {<br /> funcs[j](); /* and now let's run each one to see */<br />}David Clarkehttp://www.zebracrossing.co.nznoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-51567349734232726592011-07-12T13:43:19.958+01:002011-07-12T13:43:19.958+01:00Hi David,
What do you mean 'not convinced thi...Hi David,<br /><br />What do you mean 'not convinced this is correct'? Are not convinced that my code example does what I say it does? Or are you not convinced that what I'm showing you is a closure?<br /><br />In your first example, 12 is exactly the result you would expect. The closure has a reference to x, when x is changed, the result changes too. It's one of the common gotchas of using closures, and it's especially common for people to come unstuck when referencing some loop variable in a closure.<br /><br />I guess that's the point you wanted to make?Mike Hadlowhttps://www.blogger.com/profile/16441901713967254504noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-82320943570391093892011-07-12T00:14:57.592+01:002011-07-12T00:14:57.592+01:00Sorry, the Func declaration is incorrect because t...Sorry, the Func declaration is incorrect because the angle brackets were stripped out, should have type parameters of int, Action.David Clarkehttp://www.zebracrossing.co.nznoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-95516566159980222011-07-12T00:11:52.198+01:002011-07-12T00:11:52.198+01:00I'm not convinced this is correct. If I run th...I'm not convinced this is correct. If I run the following through LinqPad it gives result = 12, whereas I suspect the result you expect is 3 (apologies re formatting):<br /><br /> var x = 1;<br /> Action action = () =><br /> {<br /> var y = 2;<br /> var result = x + y;<br /> Console.Out.WriteLine("result = {0}", result);<br /> };<br /><br /> x = 10;<br /> action();<br /><br />I think this is the closure you're looking for, which "closes" the scope and returns a result of 3:<br /><br /> var x = 1;<br /> Func CreateAdder = z => () =><br /> {<br /> var y = 2;<br /> var result = z + y;<br /> Console.Out.WriteLine("result = {0}", result);<br /> };<br /><br /> var action = CreateAdder(x);<br /> x = 10;<br /> action();David Clarkehttp://www.zebracrossing.co.nznoreply@blogger.com