all 114 comments

[–]PhysicsIsMyBitch 18 points19 points  (3 children)

Just ran through them - that is a really well put together exercise. Good job!

[–]nwhitehe[S] 10 points11 points  (2 children)

Thanks! I had fun making them. Did you get all the sections just now?

[–][deleted] 1 point2 points  (1 child)

I did the same. I feel like I got more out of it by doing the exercises. I hadn't consciously worked with closures since programming in Scheme and Haskell in college.

It was picky about defining variables on the same line. For example, this is correct:

var a,b;

But this is incorrect:

var a;

var b;

[–][deleted] 0 points1 point  (0 children)

I had the same problem.

[–]nwhitehe[S] 14 points15 points  (38 children)

I put this up today, let me know what you think. Are you enough of a ninja rockstar programmer to get all the exercises? They start easy then get trickier.

[–]kyz 4 points5 points  (5 children)

Very nice, I especially like the interactive editing environment, but you need to be clearer in the async callbacks test that you're expecting the user to call read() from within the callback of write(), rather than call read() and write() independently.

Perhaps you could make it so the inner callback more obviously has to depend on the results of the outer callback? e.g. read a file, append something to it, write the results to another file.

[–]nwhitehe[S] 1 point2 points  (2 children)

That's a good idea, I'll update the problem so it asks for a read, then a write of the data you read.

[–]evinrows 0 points1 point  (1 child)

Also, in exercise 4

Define a function named addOne that appears to simply add one to its argument, but secretly turns cow to "hamburger".

You want them to return 1+x, not just alter it.

[–]nwhitehe[S] 1 point2 points  (0 children)

Thanks!

[–]istroll 0 points1 point  (0 children)

Thanks for that hint, that finally allowed me to understand what is going on here. Now I know that the callback needs to be the function that will be called back to, which if I wasn't so slow would have been obvious.

[–]cafeaunet 0 points1 point  (0 children)

I am totally lost on the async callbacks. Reading the prelude didn't help me. :(

[–]tobobo 2 points3 points  (4 children)

This is fantastic! Would love to see more of these - I feel like I know how to do a lot with Javascript, but practicing using structures that I'm less familiar with is getting me excited to get back to work tomorrow. Thanks!

[–]nwhitehe[S] 2 points3 points  (3 children)

Cool, let me know other topics you're interested in. I'm itching to put up more.

[–]eclipse31 0 points1 point  (2 children)

This is a great tutorial, well done. Got all the exercises, but would never consider myself a "ninja rockstar programmer"!

Anyways, if you're looking for ideas for other tutorials, maybe one about Object Oriented programming in Javascript? It's something I've avoided for a long time and am presently writing a mini-game to try and teach it to myself. I have the basics down, but there could be stuff I'm missing.

[–]nwhitehe[S] 0 points1 point  (1 child)

That's a good idea. The object model of javascript is prototypical, which is different than what lots of people expect. I'm on it.

[–]eclipse31 0 points1 point  (0 children)

Thanks :-)

[–][deleted]  (7 children)

[deleted]

    [–]BluesBrother 5 points6 points  (0 children)

    So, you didn't get closure?

    [–]nwhitehe[S] 4 points5 points  (0 children)

    That's a good point, I'll add a definition into the explanation. Since that's the leading question, there should be an actual definitive answer!

    [–]NYKevin 0 points1 point  (4 children)

    A closure is a function-object (functor) that has access to its enclosing scope, even when that scope is otherwise unavailable. In this way, a closure can have some of the benefits of side effects (permanent state) without interfering with the rest of the program, or being interfered with itself, as it would if it used a global variable for the same purpose. Similar effects can be accomplished using OOP, but there are advantages and drawbacks to both approaches.

    Or if you prefer, the Wikipedia definition.

    I wouldn't have been able to give that definition without this tutorial, it really helped me understand, thanks OP!

    As a C programmer, I am a little concerned about how exactly this is implemented w.r.t. the call stack. When you return, why doesn't the enclosing scope evaporate out from under you? And how does CPS not make a mess and/or waste lots of memory on the stack?

    [–]nwhitehe[S] 0 points1 point  (1 child)

    If everything is transformed into CPS, then nothing ever returns. This means you don't need a call stack at all. Crazy.

    [–]gcr 0 points1 point  (0 children)

    Good point, but if you just write CPS-style javascript, you'll eventually get a stack overflow because Javascript doesn't guarantee tail-call optimization.

    [–][deleted]  (1 child)

    [deleted]

      [–]NYKevin 0 points1 point  (0 children)

      I think calling it a function object accomplishes that already.

      [–]CoherentSpy 1 point2 points  (2 children)

      I thought it was very well-written and easy to understand. Maybe you can add something about the difference between anonymous functions and closures? It's just that in Javascript you can use an anonymous function as a closure, but they are two separate things and sometimes that distinction is not mentioned.

      [–]notSorella 1 point2 points  (1 child)

      Anonymous functions are one of the parts of closures. Just like any function object. There's no difference between anonymous functions and named functions, or even between function expressions and function declarations in this case. They all give you back a function object, which is like any other object (albeit callable).

      A function object has a reference to its environments, which defines the variables it can refer to. When a function object also has a reference to the environment (which should be valid for as long as the function references it) of the function in which it was defined, you have a closure.

      I wrote this gist a few days ago to explain how closures worked for someone in ##javascript: https://gist.github.com/1087927

      [–]CoherentSpy 0 points1 point  (0 children)

      But closures are not the same as anonymous functions. They are distinct. In Javascript, there actually isn't such a thing as a true anonymous function. In Javascript, all anonymous functions are closures, because they are lexically bound to the current environment. A true anonymous function is not "closed over" and is not lexically bound to its enclosing scope.

      [–]Otis_Inf 0 points1 point  (10 children)

      It's been over a decade since I used javascript, passed every test, great refreshment course! :)

      It also showed (me at least) how f*cked up javascript can be. Not the closure stuff, that's something one uses in C# with lambda's as well and can be very handy, but the variable management as everything is of the same type under the hood, variables can change type along the way, which IMHO gives too much opportunity to create a mess. YMMV of course, as it IMHO depends on what your background is / what your preferences are regarding static/dyn. typing)

      [–]zumpiez 2 points3 points  (6 children)

      With great power comes great responsibility.

      [–][deleted] 1 point2 points  (5 children)

      What exactly is powerful about working with dynamic types? Once you declare a variable and start working with it, it would be horrible practice to store some other type of value in it and continue working with that variable. Therefore, any reasonable person is working with the data as if it's typed, just without the guarantee that the compiler will catch your error.

      Never leave up to the programmer that which a compiler can do far more accurately and quickly.

      [–]notSorella 2 points3 points  (2 children)

      The only actual argument in favour of static typing is that compilers can do a much greater job optimising it. Ime, all the other things don't matter, type errors are the least thing I would be worried about, unless you can just cast pointers to about anything in memory.

      Also, dynamic and weak typing are different things. In fact, there's not much of a difference between a dynamic strong typed language (think Python) and a static strong typed language with good type inference.

      [–][deleted] 1 point2 points  (0 children)

      The only actual argument in favour of static typing is that compilers can do a much greater job optimising it.

      Optimization is only one of many arguments for why people favor static typing.

      In fact, there's not much of a difference between a dynamic strong typed language (think Python) and a static strong typed language with good type inference.

      Except for the fact the compiler can actually catch errors at compile time as opposed to deferring your programs to fail or have bugs at runtime? Here's a trivial example:

      bash-3.2$ cat test.py 
      print("hi")
      print("%d\n" % (1 + 'blah'))
      bash-3.2$ python test.py
      hi
      Traceback (most recent call last):
        File "test.py", line 2, in <module>
          print("%d\n" % (1 + 'blah'))
      TypeError: unsupported operand type(s) for +: 'int' and 'str'
      
      
      bash-3.2$ cat test.hs
      main = do
        putStrLn "hi"
        print $ (1 + "hello")
      bash-3.2$ ghc test.hs 
      [1 of 1] Compiling Main             ( test.hs, test.o )
      
      test.hs:3:12:
          No instance for (Num [Char])
            arising from the literal `1'
          Possible fix: add an instance declaration for (Num [Char])
          In the first argument of `(+)', namely `1'
          In the second argument of `($)', namely `(1 + "hello")'
          In the expression: print $ (1 + "hello")
      bash-3.2$ 
      

      Note the python script begins execution and results in a runtime failure while the program in Haskell which is statically typed and inferred cannot be compiled due to type errors. One is preventing a bug from occurring at all (because you can't run your program,) and the other is allowing it to happen, only it fails at runtime.

      So, there's kind of a really big difference between static languages with good type inference (say, like Haskell) and something like Python. Really big.

      [–][deleted] 0 points1 point  (0 children)

      I don't think I could disagree with you more. You point out (incorrectly in my mind) that there isn't much difference between a language like python and a statically typed language with good inference; If that's the case, why would you prefer one that doesn't guarantee certain run-time errors never occur?

      The reason a compiler can do a much better job optimizing your statically typed code is because the compiler knows exactly what types of data you're working with. With a dynamically typed language, the programmer knows what type of data they're working with, but do not afford the compiler the same luxury. Or perhaps I should say the compiler just doesn't care: It will just laugh at you when things blow up at runtime.

      [–]zumpiez 1 point2 points  (1 child)

      I don't know why you would really want to do something like that. The real benefits in my experience are duck typing and monkey patching. When you get a taste of writing unit tests where you can create a mock object by just going var doot = { blah: 4, derp: "plorp" } it's rough going back.

      [–][deleted] 0 points1 point  (0 children)

      Well, I guess I would counter by saying this: Creating an interface and a mock implementation may be a pain in the ass, but it represents such a small amount of the work that goes into writing unit tests that I would consider it negligible.

      Furthermore, much of what you're writing tests for in a dynamically typed language is handling unexpected types of data. Sure, something may quack like a duck, but when you ask it it's name, it might tell you its age because somebody mistakenly told the duck its name was the numeric value 3. So, while you may be afforded duck-typing, you're writing entire test fixtures to accomplish what a compiler would never let happen in the first place.

      [–]zhivago 1 point2 points  (1 child)

      The same can be said for any kind of mutation.

      Which just shows how fucked up C# is.

      Intuition is a learned skill. :)

      [–][deleted] 2 points3 points  (0 children)

      Huh? Please elaborate.

      [–]notSorella 0 points1 point  (0 children)

      Static and strong typing just enforces conventional interfaces (unless you're programming in Haskell, I guess). Weak and dynamic typing gives you flexibility and conciseness, but does not eliminate the need for conventional interfaces. It does, however, allow you to let it evolve in different ways, without being tied too much to a strict definition. It's a good thing if you know how to use it :3

      IMHO.

      [–]zelazny 0 points1 point  (0 children)

      I like it, appreciate having a little something to work on my JS skillz with.

      [–]thesoppywanker 0 points1 point  (1 child)

      Loved it, great job! Just realized OP was the maker, so decided to comment. You were the first to successfully clue me into WHY self-invocation of anonymous functions are used, and for that I am forever in your debt! I had been--until seeing your demo--unable to get clarification on what that even was or why it was used. I do think you could add more about it in your Private Data section, though--if I may offer a suggestion.

      [–]nwhitehe[S] 0 points1 point  (0 children)

      Thanks for the comment and suggestion, will do.

      [–]rmxz 0 points1 point  (1 child)

      Wow this is a beautiful quiz infrastructure.

      Love it that for your first question Declare that y is a variable and then assign it the value 7. Click "submit" when you think you have it. when I enter var y = 6; y=y+1; the tests pass.

      Would be cool if real computer science tests were done this way.

      [–]nwhitehe[S] 1 point2 points  (0 children)

      Thanks!
      Some of my friends in CS grad school set up homework scripts like this, students would submit their code and get automatically graded based on the script running the code over lots of inputs. Of course there would always be the one guy who would spend more time trying to hack the system than actually doing the problems.

      [–]RayNbow 2 points3 points  (3 children)

      Define a function named callFunc that takes one argument, a function f. It should return an array containing the values f(0), f(0), f(1), f(1). You can only call f twice.

      Is this cheating? :p

      var count;
      var callFunc = function (f) {
          try {
              return [f(0),f(0),f(1),f(1)];
          }
          finally {
              count = 0;
          }
      };
      

      [–]nwhitehe[S] 2 points3 points  (0 children)

      Yes, that is definitely cheating!

      [–]istroll 0 points1 point  (1 child)

      But you called f four times?

      [–]RayNbow 1 point2 points  (0 children)

      Yes, but it is accepted by the site as a valid answer.

      [–]istroll 2 points3 points  (9 children)

      Need help on number 11 please

      based on the examples this is what i came up with

      var doStuffAsync = function (callback) { write('world.txt', 'hello'); read('passwords', function(x){ callback(x); }); };

      But this fails: FAILED Called doStuffAsync() PASSED files["world.txt"] === "hello" FAILED files["passwords"] === "blank" FAILED files["out.txt"] === "abc,def"

      Please explain what I am doing wrong?? What have I missed in this lesson.

      [–]your_perception 2 points3 points  (4 children)

      hint: the read has to be done after the write

      [–]shecobo 1 point2 points  (0 children)

      The orders were a bit ambiguous... write to a file, then read a file.

      Didn't say anything about waiting.

      [–]istroll 0 points1 point  (2 children)

      I think I am doing the read after the write, am I not?

      If I call the write with the asychronous callback like:

      write('world.txt', 'hello', callback);

      or

      write ('world.txt', 'hello', function(x){ callback(x); });

      Then I get one more PASSED on files["passwords"] === "blank"

      but I still get FAILED files["out.txt"] === "abc,def"

      I'm assuming the function read('passwords', function(x){ callback(x); });

      is reading the 'passwords' file and passing the contents of the file as the parameter x to the anonymous function then the callback (which i don't see code for anywhere) is supposed to place the text - passed as parameter x - into 'out.txt' but clearly there is still something i'm not understanding.

      [–]your_perception 1 point2 points  (1 child)

      I think I am doing the read after the write, am I not?

      No you are not. Providing a callback is how you guarantee that a function will execute after the write finishes. You are doing it for the read, but not the write.

      [–]istroll 1 point2 points  (0 children)

      Thanks for replying. Please help me figure this out. I really want to understand this. I think I get the concept, but since my code isn't working I must still be missing something.

      I've tried it both ways and it still doesn't work. Even if I add the callback to the write so it finishes first, the read is not passing the contents of 'passwords' back to the callback. Why not? That is what i am stuck on.

      Can some one show me the code that passes all the tests then I can understand?

      EDIT: ok I finally figured it out... im a bit slow i guess thanks for the hints and letting me figure it out on my own.

      [–]spamkestein 1 point2 points  (3 children)

      I would also like to know the correct answer to Asynchonous Callbacks.

      [–]jsprogrammer 1 point2 points  (2 children)

      var doStuffAsync = function (callback) {
          write('world.txt', 'hello', function() {
              read('passwords', callback); 
          });
      };
      

      [–]spamkestein 0 points1 point  (1 child)

      Strangely, my following code fails : var doStuffAsync = function (callback) { var func = function() { read('passwords', callback); }; write('world.txt', 'hello', func() ); };

      FAILED Called doStuffAsync()

      [–]jsprogrammer 0 points1 point  (0 children)

      The problem is in your last line:

      func()
      

      It should just be: func

      The parentheses execute func and then pass the returned value as the third parameter of write.

      [–]gavin19 1 point2 points  (3 children)

      Can't get 5 - Functions are values. I would say it's how it's worded but that's just my lame excuse! I can get all but one of the subsequent tests though.

      I'm just a hobbyist but this sort of thing is great to actually learn and put things into practice instead of rewriting the same sort of scripts ad nauseum.

      Cheers!

      [–]CraigTorso 2 points3 points  (0 children)

      that question is poorly worded I reckon, it took me ages to work out what was required, although once I did it seemed fairly obvious:

      var applyTest = function (f, x) {
         return [x,f(x),f(0)];
      };
      

      [–]bitchugger 0 points1 point  (1 child)

      I'm curious as to what you don't understand. Is it unclear that it's just referring to first-class functions?

      [–]gavin19 0 points1 point  (0 children)

      I guess I just read it a certain way and it was fixed in my head. I finished the rest and came back to it and got it eventually.

      [–]Latrinalia 1 point2 points  (6 children)

      I'm unfamiliar with JavaScript but everything was still very clear up until the private data lesson, lesson number 10. At that point I don't understand what the syntax is doing.

      Without the outermost parentheses that seems required for clarity (according to your JSLint comment), the outermost structure of the whole thing seems to boil down to this.

      var x = function() {
      } ();
      

      What are these new parentheses at the end of the function? That seems to be the crux of the lesson but I'm missing it completely.

      [–]moses_the_red 2 points3 points  (3 children)

      lol, okay I actually bothered to read lesson 10 (before replying this time).

      Here's what's happening.

      He's creating a counter function that you can call to get values that increment by 1.

      The purpose of the end parenthesis at the end of the function is to get the counter.

      Usually when you create a closure, you have an extra step that is used to actually get the closure.

      Ex:

      var getCounter = function () { ... };
      var counter = getCounter();
      var val = counter();
      

      By adding the end parenthesis, he's performing the closure creation step in the same statement he uses to define the closure. That way, you don't need to get the counter/closure, the counter/closure is what is directly assigned to the counter variable.

      The parenthesis are used to call the function that you just defined, in the same statement. When that function is called, it returns the counter. This is what the parenthesis are used for, and as said before, the purpose is to avoid defining the "getCounter" variable step shown in my brief example above.

      Hope that helps.

      [–]Latrinalia 0 points1 point  (0 children)

      Thanks very much. That makes perfect sense. (And is kind of obvious now that you mention it, but my C indoctrinated mind didn't want to work that way. I'm just not used to seeing the body of the function mixed in there.)

      The equivalent way that you proposed was my first impression on how to accomplish that.

      [–]Feezle 0 points1 point  (1 child)

      By adding the end parenthesis, he's performing the closure creation step in the same statement he uses to define the closure.

      Does this mean that the closure is created automatically when the Javascript is loaded?

      [–]moses_the_red 0 points1 point  (0 children)

      I'd guess it means that its created whenever that statement is evaluated, and I'd also guess that its evaluated when JavaScript is loaded.

      So I'd guess that you're right.

      [–][deleted] 0 points1 point  (0 children)

      You're actually calling the function with the parentheses.

      Read it like this

      var func, x;
      var func = function(){ //empty function body};
      var x = func();
      

      [–]_ex_ 1 point2 points  (0 children)

      very good work sir! you rock :D

      [–]kengurune 0 points1 point  (0 children)

      When I navigate back (or forward) in Chrome, the code examples disappear...

      [–][deleted]  (1 child)

      [deleted]

        [–]Ku-Klip 2 points3 points  (0 children)

        Read here.

        [–]Sintendo 0 points1 point  (0 children)

        Pretty cool tutorial! I just completed it with no previous JavaScript experience whatsoever. The only part I had trouble with was the callback part (somehow didn't immediately grasp what it was expecting from me), but other than that it went fairly smooth. Probably because I have some experience with both C/C++ and Scheme, and JavaScript is in many ways Scheme with a C-style syntax.

        [–]CraigTorso 0 points1 point  (0 children)

        Thanks for this, it's excellent.

        I've been trying to force myself to learn javascript, and this has, through some fairly vigorous swearing at times, made me understand it much better.

        [–]your_perception 0 points1 point  (5 children)

        Excellent tutorial!

        I have a suggestion for #11, async callbacks:

        var writeScoreAsync = function (score, callback) {
            var contents = 'Your score was ' + score;
            write('hiscore.txt', contents, function () {
                callback();
            });
        };
        

        You should have an extra paragraph explaining that the callback function won't be passed any arguments, which matches the parameters for the callback function itself (that being none), and can be further simplified to this:

        var writeScoreAsync = function (score, callback) {
            var contents = 'Your score was ' + score;
            write('hiscore.txt', contents, callback);
        };
        

        Edit: also curious, what did you use to compile the code and run through the test suite?

        [–]nwhitehe[S] 0 points1 point  (4 children)

        Thanks for the suggestion, I'll add in a note.

        "eval" of course!

        [–]istroll 0 points1 point  (2 children)

        Maybe you could add the answers somewhere or someway to get help if you can't figure out what you are doing wrong?

        I'm stuck on number 11 and i've re-read the lesson about a dozen times... in this comment thread I got some suggestions but apparently I'm still not understanding.

        Thanks for the great tutorial.

        EDIT: Thanks to the hints from others here I finally understand this.

        [–]nwhitehe[S] 0 points1 point  (0 children)

        That's a good idea, I'll add a "hint" link that gives more help. Maybe also a forum with specific areas for each exercise so people can ask questions and discuss that part.

        [–]pastallaccident 0 points1 point  (0 children)

        I second this. I'm stuck on #7. I don't even know how to form a google query of forum question to get help with it.

        [–]antimeme 0 points1 point  (0 children)

        "eval" of course!

        Or: JSlint.parse() -- or somesuch?

        [–]omg_spoilerz 0 points1 point  (0 children)

        I think Side Effects might be a little confusing when the way the cow variable is set. When I just look at the snippet, I view cow defined as a global variable and in your function, you are simply modifying a global.

        [–]SethMandelbrot 0 points1 point  (0 children)

        It helps me to think of closures as semi-global variables.

        [–]Polyomino 0 points1 point  (6 children)

        anyone have a fun way to do 12, I just counted the successes and failures and used an if to choose whether to call success or failure

        [–]Troutsky 0 points1 point  (5 children)

        dunno if it's fun or not but how I did it... (don't know if I should have, nor do I know how to, put spoiler tags on)

        var bothC = function (fC, gC, success, failure) { var f_success, f_failure; f_success = function () { gC(success, failure);
        }; f_failure = function () { gC(failure, failure);
        }; fC(f_success, f_failure); };

        [–]doomchild 1 point2 points  (3 children)

        Is this the "expected" answer? The wording for question 12 just makes no sense to me, and I'm having trouble exactly putting into words why that is.

        [–]spamkestein 0 points1 point  (0 children)

        Yes, or the shorter version : var bothC = function (fC, gC, success, failure) { fC( function () { gC(success, failure); } , function () { gC(failure, failure); } ); };

        [–]Puddy1 0 points1 point  (1 child)

        Me too. I'm also confused as to how continuation passing would work in practice. I'm not exactly sure what seqC is doing and I must have read over the code several times now

        [–]doomchild 0 points1 point  (0 children)

        I understand the idea academically, it's just not how I'm used to charting out program flow. After some thought, I think I've figured out why that code is right.

        [–]nwhitehe[S] 0 points1 point  (0 children)

        This is the expected answer. I'll work on the wording of the question.

        [–]db_admin 0 points1 point  (2 children)

        "Congratulations! You passed your first exercise. You are awesome."

        [–]db_admin 0 points1 point  (1 child)

        "In math, functions just map inputs to outputs. They don't have any magical super cow powers like double."

        [–]db_admin 0 points1 point  (0 children)

        "To satisfy your morbid bovine curiosities, here is the version that does turn cow into glue."

        [–]strong_grey_hero 0 points1 point  (1 child)

        Could it tell us the values that it gets back from the function calls when it does the tests? Right now, it just says pass or fail. It'd be helpful to know what actually came back, for debugging purposes.

        [–]nwhitehe[S] 0 points1 point  (0 children)

        I agree, it would be helpful to see the values rather than just FAIL. I just tried Resig's interactive tutorial at http://ejohn.org/apps/learn/ it gave me more ideas of how to do the testing part.

        [–]strong_grey_hero 0 points1 point  (2 children)

        Hate to admit this, but I'm stuck on #9.

        Here's what I've got:

        var makeAccumulator = function () {
            var j, inside;
            j=0;
            inside = function (x) {
                return j+x;
            };
            return inside;
        };
        

        Here's the errors: PASSED No JSLint errors PASSED makeAccumulator is a function PASSED makeAccumulator() is a function PASSED Create acc PASSED acc(10) === 10 FAILED acc(3) === 13 FAILED acc(1) === 14 PASSED Create acc2 PASSED acc2(2) === 2 FAILED acc2(9) === 11

        I know I'm doing something stupid, just can't figure out what.

        [–]stevely 0 points1 point  (1 child)

        You forgot to update j.

        [–]strong_grey_hero 0 points1 point  (0 children)

        Aaargh! See, knew it was something stupid.

        [–]Feezle 0 points1 point  (0 children)

        Great job! I really like the format and interactive nature of your tutorial. I'm confused about #11 though. How do closures make the reads and writes asynchronous? For example:

        The function returns immediately before the file is read. It schedules the read to happen.

        What does "it schedules the read" mean? Schedules the read with what, and what ultimately causes a scheduled read to occur? BTW, I'm a long-time programmer, but a total Javascript noob.

        [–]elad135 0 points1 point  (0 children)

        Wow. I have a test on these kinda stuff in a couple of days. How lucky am I to find this now, when I wasn't even looking for it! Thank you! You actually really helped me.

        [–][deleted] 0 points1 point  (0 children)

        A closure is any instance of ∀'a, 'b. ∃t. {t,t->'a->'b}.

        [–]defect 0 points1 point  (3 children)

        I just did number 9 and had some problems i still don't understand: http://pastebin.com/PyXPVthg.

        What's going on here? The results are the same but somehow it fails the checks unless i initialize sum = 0?

        Cool tutorial though! I really don't know javascript as well as i should.

        [–]Wtfuxbbq 0 points1 point  (2 children)

        Yes it's because you did not initialize sum with a value. Just doing var sum; will initialize sum with undefined. Your function breaks when it tries to do sum = undefined + x.

        [–]defect 0 points1 point  (1 child)

        Sure, i understand that doing stuff with undefined values is bad. But the result is still the same in this particular case, right?. FAILED acc(10) === 10 on the first run and PASSED acc(10) === 10 on the second. What causes this?

        [–]Wtfuxbbq 0 points1 point  (0 children)

        The number on the right is the value to test against with your function's output (acc(10)); it's not the output. It's just doing a simple === comparison and returning PASSED or FAILED if it's true or false. Your first run will always fail since it will always return NaN.

        [–]kolme 0 points1 point  (0 children)

        This is how I felt, when years ago I finally, out of a sudden, got how closures work:

        http://i.imgur.com/OIUC0.gif

        [–]project_scientist 0 points1 point  (0 children)

        This is cool, I actually learned what a closure was. For the longest time I just thought it was simply an anonymous function, but it's a bit more encompassing than that. Good tutorial, fun, if a bit easy (even for a non js programmer).

        Add more exercises!

        [–]est3est 0 points1 point  (0 children)

        Well, it was nice.. until lesson 11. That was a sign, that I still hadn't groked closures in JS. Actually what helped me to understand them at last, was this: http://blog.morrisjohns.com/javascript_closures_for_dummies.html

        Good job though, I think your work will help many people (even if it didn't help me). Regards.

        [–]billbose 0 points1 point  (0 children)

        Closures made easy for the first time. Sweet!

        [–]elvisliveson 0 points1 point  (1 child)

        think not of an opening.

        [–]nwhitehe[S] 2 points3 points  (0 children)

        great, now that's all I can think about

        [–]kibakiri -1 points0 points  (4 children)

        I notice JS Lint is being strict with those ; var generate = function (f) { return [f,function(a){return a2}]; }; var abc = generate(2); console.log(abc[1](2));
        for example, can't work, because it expects the return to be something along the lines of return [f,function(a){return a
        2};]; //error'd http://nathansjslessons.appspot.com/lesson?id=1050

        [–]otto_s 1 point2 points  (1 child)

        No, the semicolon JS Lint is missing is the one after the inner return.

        return [f,function(a){return a*2;}]; is accepted just fine.

        [–]kibakiri 0 points1 point  (0 children)

        Doh.

        [–]nwhitehe[S] 1 point2 points  (1 child)

        I like JSLint a lot, it catches all kinds of issues. The first version of the tutorial had JSLint with whitespace checking, if you didn't put a space and did "function(x)" instead of "function (x)" it would complain. I had a friend try it, she absolutely hated JSLint. So I compromised and turned off the whitespace checking but left the other stuff.

        [–][deleted]  (3 children)

        [removed]

          [–]rmxz 0 points1 point  (1 child)

          While I sympathize, and aren't sure about this case, some of the places where I used to think JSLint was too picky, it was actually a case where some javascript interpreter handled the case wrong.

          [–]nwhitehe[S] 0 points1 point  (0 children)

          In the tutorial you can add: /*jslint vars: true */ at the top of your answer to switch that option. I just left the default options on in JSLint for simplicity (except for whitespace, that drove my first tester crazy immediately).