Maintenance and feature work has been almost entirely done by people other than us, in the process of building real apps.
3,527 karma · joined April 18, 2010
Maintenance and feature work has been almost entirely done by people other than us, in the process of building real apps.
Additionally, the Addepar guys put this together in a few weeks. I'm unsure where your claim that this was difficult is coming from.
There are still some tickets available here: https://tito.io/tilde/ember-camp-2013
Probably my favorite thing about Ember is that it isn't built by academics toiling away in an ivory tower; it's driven by real-world problems that web developers are facing.
Our goal is to provide a set of tools that allow developers to build apps and not have to solve the same problem over and over. Displaying large sets of data is one of those problems, so this dovetails nicely with the mission of Ember.js. Thanks guys!
Google is in an interesting position. Of all of the major Silicon Valley tech companies, I think Google is the one most seen as the "web" company, and yet they've staked a lot of their future on Android. Android, instead of making the web a first-class citizen, has in fact set the mobile web back by years. While they should have worked to bring all of the strengths of the web to mobile devices, they decided to play the app game on Apple's terms and, IMO, have lost.
Surely someone at Google realizes that killing the open web also kills the company's cash cow--search and related advertising--but based on their behavior it doesn't seem like it.
My hope is that the Android wakes up and decides to make the web a priority again. In league with the Chrome team (some of the smartest people I've ever met), they could do wonders to make developing for the mobile web a joy instead of the disaster that it currently is. Google needs focus, and it needs its focus to be on the mobile web. Having great, unified documentation about building sophisticated web apps that competes with Apple's Developer Centers is a good start to doing so.
I think the shift first started with the ascendancy of native mobile apps. Now, developers had to seriously start considering their HTTP APIs as first-class citizens and not nice-to-haves. Once that happened, it's not a big leap to realize that treating your web application as somehow different from any of your native clients is a bit, well, insane. You can either choose to write a server that is a mix of JSON API and rendered HTML, with conditionals all about trying to figure out the right thing to render, or you can pull all of that logic out into a stand-alone JavaScript application, with better responsiveness to boot.
I think this approach is a winner. The server guys can focus on building a kick-ass server, and the front-end guys can build an awesome UI without having to muck about in the server bits.
One thing that still blows my mind is how hard it still is to get data from the server to the client. Everyone is writing custom code specific to their app. As the article says:
There's no reason for us to all separately think about these problems and solve them in a million different ways every time we're confronted with them. Aside from the years of wasted time this involves, we've also got a bunch of non-standard and sub-standard APIs to interact with, so all the client code needs to be custom as well and nothing is reusable.
I think this is a huge problem, and Yehuda and I are doing our part to try to solve it. Our Ember Data framework (http://github.com/emberjs/data), by default, assumes certain things, such as the names of your routes and how associations should be loaded. We want to enable people to start building apps right now instead of writing hundreds of lines of JavaScript that are custom to their application, and do it in a sufficiently comprehensive way that you very rarely need to drop down "to the metal." For example, we handle things like mutating associations on the client-side even before a guid has been assigned to a record.
Personally, I'm excited for how this is going to all shake out. I think Rails will continue to be an important piece in the toolchain, but it will no longer be the primary one, and I can't wait to see how it evolves to fill that role.
For the past few months, we've prioritized creating an API that is friendly, conceptually simple, and correct. Our view implementation, for example, handles many edge cases that other frameworks might punt on.
We believe that nailing the API first is important for a number of reasons. We can increase performance without you having to change your app; the same is not true if we spend time making it fast, then require you to change the API once we realize it is not a good one.
The cool thing about declarative systems is that once you express your intent in a way the framework understands, we can apply heuristics and optimizations that every app developer gets for free.
Some people pooh-pooh the idea that better abstractions require a "sufficiently advanced compiler," but I think the history of the field has proved that it's the case. V8 and LLVM are examples of projects where we continue to eke out performance increases well past what I think the average person would have expected. I saw the same thing in Handlebars-- a lot of people criticize Handlebars for being separated into multiple steps, as it increases the size of the library somewhat, but being able to reason about each of the steps in the compilation pipeline has given contributors the ability to reason about possible slowdowns and turned it into one of the fastest template libraries around.
So, all of that being said, I would never recommend using bindings for animation. I'm not aware of any framework or library that recommends this. Bindings were designed for infrequently changing values that need to be displayed to the user. Since the smoothness of animation is critical to the user experience, it's hard to argue that any optimization is premature optimization. All of the animation we've done in our Ember apps is done via either CSS transitions, or using requestAnimationFrame and modifying the DOM element directly.
While Ember.js will presumably always be technically slower than Backbone, slower doesn't have to mean slow. That being said, there are obvious performance gains to be made here, and I'm glad we've got Jeremy to keep us on our toes. :P
Luckily, providing a widget library is, and will always be, outside the scope of Ember.js. While we'd be quite pleased to see someone else develop a widget library on top of Ember, it's not something that we're personally interested in doing.
The goal of Ember.js is to roll up common patterns web developers are using into the framework so that they can write less boilerplate. In fact, part of the reason we renamed SproutCore 2.0 to Ember.js was to emphasize the point that our value proposition is in the architecture, not the library of controls.
As a veteran of the SproutCore project, keeping things lean and focused is my top priority. And, if it helps, we're all extremely allergic to anything that feels "enterprisey." :P
These types of articles that synthesize a few anecdotes from a particular group into a grand vision of the inner workings of the company are getting pretty tired. Apple is a great company, but the day-to-day really doesn't differ that much from most other companies.
This is also known as the principle of abstraction, because it means that it is easy to refactor common code into methods that take a block.
I can attest that quickly refactoring code in Ruby is much more straightforward than in JavaScript. In practice, a small reduction in cognitive load means that it's easy to just do it now, instead of putting it off (to the point it never gets done).
Isn't that the reason developers choose libraries like Backbone, Ember, Knockout, et al.? I think most web developers have realized that code spaghetti doesn't scale very well. Part of the reason the iOS ecosystem is so vibrant is because Cocoa is just as opinionated about architecture as it is about "specific functionality."
They both seemed to miss out really basic functionality that I run into all the time building these type of applications, the example here shows one of the problems, when I am not looking at the recent tweets, I dont want to be polling the data source, I havent seen a good example in either of how to properly setup and tear down views, I came up with something incredibly simple that helps, I will try and blog about it soon.
I'd love to read your blog post. In my opinion, it sounds like you might be approaching the problem from the wrong direction. Views being in charge of when the server is polled is a layering violation. Instead, I'd have a controller that is in charge of knowing when a given view is rendered to the screen. When it is, it tells the model layer to start polling. When it hides the view, it turns off the polling.
Also I find the general tone of the article pretty rude and condescending.
Thomas is an incredibly nice guy and has experience with many different MVC frameworks. I'm sorry the post came off this way to you, but it didn't to me. Personally, I think Backbone is an incredibly important part of the ecosystem and am very glad it exists. I think Thomas feels the same way too.
I'm curious: what about the Backbone version feels "cleaner" to you?
Additionally, specifying the property as a string allows you to implement "unknown property" handlers, which is another extremely powerful idiom.
For example, imagine you have an Store object that saves the tax rate:
Store = SC.Object.create({
taxRate: 0.0895
});
Since this is a static value, I don't technically have to use an accessor. But imagine my state implements a tax holiday, and so for one day per year, the tax rate is different. In Amber, this is a simple change: taxRate: function() {
if (this.get('isTaxHoliday')) {
return 0;
}
return 0.0895;
}.property()
Instead of trawling my codebase to references for this property and changing them to method invocations, because everything goes through get(), I know the change will be transparent. It's this transparency that leads to very maintainable web apps.Some people object to the extra method invocation, but I think the expressiveness it gets you is worth it. As soon as proxies land in JavaScript, we'll add support for them so you can use the dot notation and still get the same functionality.
Items in lists don't have to be objects with fields; you can display primitives like strings and numbers by using {{this}}:
{{#each tags}}
<li><a href="tags.html#{{this}}">{{this}}</a></li>
{{/each}}
Shadowing properties from parent context objects isn't a problem. Handlebars allows you to reach parent contexts with a '../' notation: {{#each comments}}
<h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2>
<div>{{body}}</div>
{{/each}}
Regarding looping and conditional branching, Handlebars has an {{#if}} helper that does not evaluate to true for empty arrays: {{#if authors}}
{{#each authors}}
{{firstName}} {{lastName}}
{{/each}}
{{else}}
No authors to display.
{{/if}}
I don't fully understand the complaint about recursive data structures. I usually just register a helper that can invoke itself recursively.SproutCore 2.0 alpha was released on May 25th of this year, so Alex didn't have time to cover it. My hope is that a second edition would hopefully at least mention it, now that it is much more competitive with things like Backbone and Knockout, et al. :)
The social incentives in the JavaScript community are structured so that you get recognition for rolling your own library because you disagree with a naming choice. Forking or rolling your own should be a last ditch effort, not the first tool in your toolbelt.
Competition is great, but it must be balanced with collaboration. And I think that's what's out of whack in the JavaScript community.
Even more important than in Rails-style server-side MVC, though, is using state management in stateful client-side MVC, like Mac, iOS/Android, and web applications. (See http://gmoeck.github.com/2011/03/10/sproutcore-mvc-vs-rails-... to understand the difference.)
At least with Rails, the flow through your application is pipelined M->C->V and the debugging is significantly easier. If you think about an iOS application, for example, your application is starting off in a different state every time, and is constantly being modified by the user. If you ever get into bad state, it can be very hard for the user to recover; especially if that bad state gets persisted to the file system.
One problem with state machines is that they grow in complexity very quickly, and the tools that were given to most people in their CS curriculum don't help you manage this fast growth. However, applications that are mission-critical still need the robustness of formalized state management.
David Harel, while working on software for fighter jets, came up with Harel statecharts, which describe a formalism for parent and child states. These are also very popular in embedded systems, such as pacemakers, where users could die if the system fails:
http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Stat...
We've been preaching statecharts pretty hard in the SproutCore community, although largely internally at Apple, and included a built-in statechart library in our 1.5 release. Mike Cohen, the maintainer of the SC library, has a ton of great resources on his blog:
https://frozencanuck.wordpress.com/category/statecharts/
I think especially in the arena of web applications, we need to start spreading the word about the benefits of statecharts, not least of which is the easy ability to regenerate state from URLs. It requires discipline and effort upfront, but so does unit testing, and I think that's a battle that the development community has largely won.
For critical infrastructure like package management, these kind of changes can be difficult to deal with. We're switching all of our projects to SlimGems, and are going to be contributing code for improving its use as a library for other software to build on.