For an unbiased overview of Meteor, including what it offers and how it differs from typical JavaScript frameworks (like Angular.js and Backbone.js) and ecosystems (like Mean.js and Yeoman), read this article:
http://javascriptissexy.com/learn-meteor-js-properly/
I am the author, and I will try to address some of the comments:
1. First, if you buy and read the book, your writing will definitely improve. You will write better than you ever have. I am confident you will. Those tiny grammar books on amazon.com wouldn't help much because many don't cover the crucial topics for writing well. I read nearly all of them.
2. Language is instinctual, so arguing about grammatical rules is pointless. Take this passage from my book: "I agree with Steven Pinker, as he describes in his book "The Language Instinct," that humans have an instinct to learn and use language, and some nonstandard grammars and dialects perceived to be unsophisticated and ungrammatical (Appalachian English Vernacular and Black English Vernacular, for example) do, in fact, follow sophisticated grammatical rules.
I will not hurl even a pebble of criticism to anyone who uses English grammar to his or her own inclination. Instead, this book helps people who want to improve their Standard American English and Standard British English grammar. By “standard,” I mean the form used in academia, mainstream businesses and books, and formal and informal writing aimed at the general public or educated readers.
3. For the first bullet, I combined two similar bullets into one, hence the possible oddity. I constructed it for brevity, not for eloquence. No need to niggle over a bullet; it's a peccadillo. Incidentally, I wrote an entire chapter on how to write eloquent prose.
4. Ztratar, I presume you would agree that books are not useless. While anyone can probably learn anything online, books are still usually more organized and better researched than disparate articles and blog posts spread across hundreds of websites. In fact, to my knowledge, about half of the content in my book cannot be found online. I have devised some new grammatical constructions and techniques for writing skillfully.
5. Icambron, you should definitely read my book. You will learn a lot. For example, you will learn that all those things you pointed out are actually grammar myths (aka superstitions). I have an entire section on myths that many people believe are legitimate rules of grammar. Many such myths abound even in schools, including college. You should read the following article, a section from my book; you may find some of the cool sentence constructions quite different from the prosaic and formulaic constructions taught in schools:
https://grammarandwritingforcreators.com/Creative_Powerful_W...
5. Seanmcdirmid, I wrote an entire section on the rhythm and euphony of sentences, another topic rarely found in grammar books. You can read this new figure of speech that I have devised (unrelated to rhythm, but all the examples employ rhythm):
https://grammarandwritingforcreators.com/Conceal_Reveal_Arti...
I read through you new figure of speech, and I don't see why you class it as a figure of speech. Wikipedia defines a figure of speech as "A figure of speech is the use of a word or a phrase, which transcends its literal interpretation. It can be a special repetition, arrangement or omission of words with literal meaning, or a phrase with a specialized meaning not based on the literal meaning of the words in it, as in idiom, metaphor, simile, hyperbole, personification, or synecdoche." From what I read in your explanation of your idea, you've just creates a phrase with a literal meaning. Would you care to explain further why you regard it as a figure of speech?
>> TL;DR -- all closures created within a function are retained even if only one closure is ever referenced. This is really interesting, and potentially devastating for certain coding styles. <<
This is not devastating, it is how closures and scope chain work in JavaScript. See my detailed explanation below.
The crux of the matter is that the closure still references the outer function's scope chain, even after the outer function has returned. And the outer functions's scope chain is referenced by the closure until the closure is destroyed or returns.
Here is a technical explanation of why there is a memory leak and how to fix the problem.
The scope chain of Closures (in JavaScript) contains the outer function(s) activation object. The activation object of a function contains all the variables that the function has access to, and it is part of a function’s scope chain.
This means the inner function (the closure) has access (a reference) to the outer function’s scope chain, including the global object. And even after the outer function has returned, the closure still has access to the outer function’s variables.
Therefore, the activation object of the outer function cannot be destroyed (for garbage collection) after it has returned, because the closure still references its variables.
When the outer function returns, its own scope chain for execution (its execution object) is destroyed, but its activation object is still referenced by the closure, so its variables will not be destroyed until the closure is destroyed.
The execution context of a function is associated with the functions’ activation object, but while the execution object is used for its own execution and is destroyed when it returns, its activation object is referenced by closures—its inner functions.
Now, as to the specific example in question:
The reason the str variable is never destroyed is because it is referenced buy the logIt function because the logIt function's execution object references the entire scope chain of the run function, and the logIt function is never destroyed, so the str variable remains in memory.
As the original author (OP) suggested, be sure to dereference any local variable in the outer function that the closure is using, once the closure is done with it or once the outer function is done with it.
Also, simply setting the logIt function to null (when it completes execution—returns) will allow the str variable and the entire scope of chain of both the logIt and the containing run function to be destroyed and ready for garbage collection.
nknighthb,
I am just wondering. Did you downvote me because you think one part of my explanation was not specific enough?
First, you are correct that I specifically mentioned the logIf function when I discuss the specific example.But that does not take away from my thorough explanation of the main reason for the problem. In fact, everything I said about the logIt function applies to the doSomethingWithStr function, since they are both closures, so my explanation stands as is.
If you read my explanation again, you will see that I clearly explained that closures still have access to the outer function's scope, so both the logIt and the doSomethingWithStr functions have access to the outer function's scope chain even after the outer function or any of the other closures returns.
It is not until both all closures are destroyed or returns that the outer function's scope activation object is destroyed.
If your explanation were all there was to it, then 'str' would not be destroyed when logIt alone were present. But it is.
logIt alone -> str is garbage collected
logIt + doSomethingWithStr -> str is not garbage collected
Your explanation could explain the latter behavior, but it does not explain the former.
Edit: To put it another way, you are addressing only one of the scenarios presented in the article, and you are assuming that scenario results in a behavior the article specifically says does not occur in empirical testing. This is a key point in the article, and your "explanations" are ignoring it.
Are you saying my explanation does not explain the following?
"logIt alone -> str is garbage collected"
I don't see why you don't understand why I am saying. My first post explains in detail how closures work and why the issue is not a JS bug, though it is indeed a memory leak. All I can say is that I have explained the overall inner workings of closures in JS, and my explanation covers all the scenarios outlined in the blog post.
This is the crux of the matter of the entire blog post:
"...str is only referenced in the main body of run, and in doSomethingWithStr. doSomethingWithStr itself gets cleaned up once run ends… the only thing from run that escapes is the second closure, logIt. And logIt doesn’t refer to str at all!
So even though there’s no way for any code to ever refer to str again, it never gets garbage collected!"
And I explained why that problem is observed and why closures work the way they do.
PS. I will humbly agree to disagree: I think that I have explained all the scenarios outlined in the blog post and you disagree with me. This is not a problem; there is nothing wrong with disagreeing.
Good question:
I take it you are referring to the code below. The reason str is garbage collected is because of the modern implementation of the JS compiler in Chrome. Such modern JS compilers look specifically for such unused variables in closures, even when the variable is in the execution context of the closure.
To clarify, it is Chrome's decision to garbage collect the str variable in that context that resulted in str being garbage collected. It is not a result of a JavaScript bug.
Moreover, different browsers have different implementations for how they garbage collect variables in closures' scope chain. Heck, browsers do their own thing when it comes to many aspects of JavaScript.
On second thought (from our previous back and forth), you are correct that I did not explicitly discuss this specific issue in my earlier post. So you win :) and I have up-voted your two comments accordingly.
Here is the code I think you are referring to:
var run = function () {
var str = new Array(1000000).join('*');
var logIt = function () {
console.log('interval');
};
setInterval(logIt, 100);
};
setInterval(run, 1000);
The confusing part of your posts has been that you seem to have been portraying the retention of 'str' as a necessary behavior. Nobody disagrees that it's a permitted implementation, only that it's the one correct or best implementation, and it's made worse by the inconsistency between the two cases, which itself invites confusion.
I have read the beta release of the book in its entirety. I do not know the book's authors personally, so I can give an unbiased assessment of the book and answer specific questions about the book.
The Crux of the Matter:
Coming from Node.js/Backbone.js/Express.js, I was pleasantly shocked and surprisingly inspired by how pleasurable and productive it is to develop with Meteor. I am not sure I feel this way about any other web-dev technology besides jQuery. Meteor is so awesome that it makes the book easy to get through and fun to learn from (the book is a web app, a book, and a tutorial in one; it is more than just a book, hence my use of the word “use” instead of “read”).
The book covers most of the big Meteor concepts with example code and it guides you along as you build the Microscope web app—a "real world" application you can deploy and actually use. You will learn so much and get through the book so quickly that you will want to develop your own web app with Meteor in an instant. Be warned: You will be giddy with excitement at how easy it is to get stuff done with Meteor. Using Meteor is analogous to using an iPhone for the first time after using one of those "smartphones" [1] that were available prior to the launch of the iPhone.
The alternative to using this book is to learn Meteor by painstakingly browsing and reading the thorough (but not necessarily logically organized for structured learning) Meteor docs. Forget finding a proper "Getting Started with Meteor" tutorial; they are outdated and lack depth. The book summarizes some of the important Meteor concepts in a logical, succinct, and exemplary manner, with hands-on implementation.
There are some specific Meteor core concepts that the book either doesn't cover or only discusses briefly, like eJSON, Deps, Custom Reactivity, and cursor.observe (similar to Backbone's model.on events). But fortunately, Chris Maher does an excellent job covering these topics in depth on EventedMind.com [2]. Therefore, I highly recommend the book along with frequent visits to EventedMind.com to get a thorough understanding of Meteor.js, so you can confidently start building Meteor apps straightaway.
It is worth noting that the book's format (a web app with comments, videos, frequent updates, and the main Microscope tutorial, in addition to PDF and eBook copies of the book) is groundbreaking and must be celebrated. Every book on any web development topic should be published in this manner. Authors take note.
Background: I am the dude blogging at http://javascriptissexy.com/ and I am a Frontend Developer (JavaScript Guru). Incidentally, I will likely write a detailed blog post about Meteor ("How to Learn Meteor Properly," perhaps) in a few weeks, after I develop my first Meteor app.
I, too, was lucky enough to get in on the preview and read most of the book. I've read a couple of these books and this one takes the cake. It's huge, very thorough, and incredibly easy to follow along.
If you're thinking about getting into Meteor, you should definitely grab a copy. It's a really easy read that teaches you a lot.
Oh, and Meteor is sexy, I'm glad you're a fan Richard. I'm a big fan of your site and can't wait to see you get engulf in the Meteor hysteria. :)
I am glad to hear you are a fan of the blog, Cory.
I am somewhat surprised you are all over Meteor already :), and you probably think the same thing of me :)
There will be Meteor hysteria for sure, but I don't know if it will happen so soon, although this book will help quite a bit.
Another huge fan of your blog, Richard. Your blog represents one of the single best locations on the web for excellent road maps for learning web development. It is immensely helpful to go through the material that you've already vetted rather than waste time and energy finding and trying the plethora of books, tutorials, videos, sites, etc. For beginners it's incredibly overwhelming but your site helps show us the path and put us on it. It's still a lot of work, but at least we feel that as long as we follow your recommendations we'll make steady progress toward our goal of becoming Web Engineers. I can't wait to read your upcoming post about Meteor!
Man, you guys are making me feel warm and fuzzy. I had no idea some followers of my blog are HN regulars.
Thanks for the wonderful compliment and encouragement, laughfactory. I am very happy that my blog is making a difference. Good luck with your learning.
I'm still on your "How to Learn Javascript Properly" track, but I've being hearing about Meteor in passing quite a bit lately.
Your recommendation for this book is all that I needed to convince me to take the leap (once I've got the fundamentals down, of course). Thanks for your recommendation and guidance. You've done a great deal to make me feel like I'm meaningfully progressing to a state of professional competency.
I am happy to hear from readers who are following my blog, and most importantly, to hear of their progress. So thanks for your comment, loupeabody.
It appears that you have the passion and determination to follow through with learning JS and then Meteor. You can skip Node.js/Express.js/Backbone.js and go straight to Meteor, if your goal is to develop modern web applications with JS soon (without the lengthy time needed to learn all the libraries and frameworks needed to put a full Node.js app together).
Meteor uses Fibers. And you can do any of the async stuff in Meteor, like you would in Node.js with async.js, with the exception that you will most likely use Futures, and the code style will look synchronous (not the lengthy callback chains we are used to in Node.js). For more on Async execution in Meteor.js, see this link:
https://gist.github.com/possibilities/3443021
Sometimes you have to do a little configuration work to get off the shelf NPM packages settled nicely with Fibers; but its not a huge deal and almost every day someone else will turn npm-somePackage into meteor-somePackage.
That is strange indeed. I think what might have flagged the previous comment was: I initially posted the comment in reply to the wrong person. So I deleted it and reposted it in response to the correct person.
Oh! well if you post the same comment twice, the second is automatically deaded. You have to delete the first one before you can repost it somewhere else.
Yep, skip those pesky IE compatibility issues, except, if you expect to target IE <= 8, you should definitely get the shim library at the link below. It provides compatible IE functions for all the common native JS methods and functions that missing in IE <= 8. Then you never have to worry about IE again.
https://github.com/kriskowal/es5-shim
Author here. What I meant is that as of now, all Meteor sites have a fairly substantial loading delay (generally a couple seconds) due to the way Meteor works.
So for sites or apps where loading speed has a direct impact on your bottom line and that don't really benefit from real-time features (such as an e-commerce site) I don't think Meteor is a good match, at least for now.
I also don't think Meteor is needed for purely static content sites. For example, for our own book site we're using Jekyll.
(And yes, I know speed is important for every type of site. But in most cases, I feel there's enough other benefits to building Meteor apps that you can ignore this downside for now).
When a template subscribes to data in a server collection, there is a delay between the moment the subscription begins and the moment the client displays the data it receives from the server. On page load you really notice the delay because there is nothing else for the user to see while the client waits to receive the data from the publish action. The way around this is to show something else on the page so that the user doesn't notice the delay. One way to do that is to show only static assets during that time, another way is to use local (client-only) collections.
Presumably he doesn't specifically mean e-commerce sites, just sites that are required to be highly responsive - where you don't want to send the JavaScript, then the JSON, then do the rendering. You want to start with the static, rendered HTML then decorate that with JavaScript for subsequent interactions.
I am also building an application that could use this service. So I tested TextRazor and the results were not good on two random articles I processed with the service.
I really want this to work out, because my application needs this kind of technology to be reliable and accurate. I just processed the article at the link below, and the word "Tesla" was not captured as one of the topics.
http://www.teslamotors.com/blog/most-peculiar-test-drive-fol...
I just tried it again and it worked this time. That is interesting: I don't know if they tweaked it a bit or not :), but I am feeling a bit better now, because my application really needs a reliable, accurate service like this.
No tweaking, promise :) It's possible you hit an inconsistent server first time around, I'll have a dig on our end. Let me know if you have any other problems - toby@textrazor.com.