Uncategorized
Raising all boats
It’s easy to complain about PHP. For instance, why didn’t they choose ☃ as their namespace resolution operator?! As a developer with lofty opinions, I’m not a big fan of PHP. To me, it’s an argument against allowing accretion to determine the design of a system. I don’t think it’s controversial to call the PHP language, core library, and ecosystem “inconsistent” and “a matter of curious histories”. A language feature here, a library function there, year over year, and you’ve got a “quaint” design. Yes, those are scare-quotes.
Whenever I feel a big rant about PHP shortcomings approaching, I try remember a few important facets of its success:
- PHP made programming web applications accessible to lot of people for whom writing CGIs with Perl, Python or Java servlets was overwhelming. Myself included!
- You still can’t beat the simplicity of PHP’s deployment model: acquire commodity web hosting, upload source files, and done.
- Due to its accessibility and ease of deployment, a whole new kind of person started building stuff with code. Jason Kottke called part of this Liberal Arts 2.0. Less mathy programming, more craftsy.
Fast forward to today. PHP is still doing fine, though lots of people switched to Ruby or Python many moons ago, depending on personality type. And lots of those have since moved on to other things. The technology hype curve is an overlapping, ongoing thing.
Of those that switched, many ended up with JavaScript, in the guise of browser-side frameworks or server-side Node (and its ilk). I think there’s a huge opportunity here. JS is not without flaws, like PHP. But its sort of backed into really broad reach. Embedded, games, applications, mobile, probably more that I don’t even know about. That could make it compelling for an even less math-y demographic of people building stuff with computers.
And yet, there is no single JS community. There’s browser people, there’s server people. The future may hold mobile, gaming, and device people. That creates dissonance and some uphill battles.
But maybe that’s the really cool part. The JavaScript communities will have to slog uphill a bit to make accessible the previously intimidating domains of mobile apps, games, and embedded software. And that could raise the boat for people who aren’t building web apps but could be building software.
Functions about nothing
The tricky thing about decomposing code into abstractions is you end up with “functions about nothing”. You’ve probably seen on of these: a method or function with really vague names glommed into a utility or enumerations junk drawer. It’s probably innocuous, but as you’re reading code, it takes you out of your flow and forces you to think in the abstract instead of the concrete.
It’s easy to guess how these things happen. Successive refactoring iterations end up pulling business logic into a pile of predicates and side-effects and separate pile of abstractions. We feel pretty good ourselves at the end of the refactoring and write a fancy blog post about it!
The rub is when we come back to read the code later. Its easy to find the abstraction first and get side-tracked by figuring out why it exists, the context in which it was created, and when we might use it again. This is better than predicates and side-effects interwoven. But it’s still a problem.
I don’t have a salve for this. I just wanted to put the phrase “functions about nothing” on the internet. [SLAP BASS OUTRO RIFF PLAYS HERE]
It's not your fault if your tools confuse you
I. Pet Peeve #43: Complaining About Frameworks
The whole point of a framework is that you trade one or more axes of freedom in how you structure your program so that you can move faster writing the meaningful (unique) part of that program. To wit, the first definition I learned of a framework goes something like:
A framework is a library that takes over the main()
function of your program and provides a higher-level entry point for calling your code.
Most programs would have a boring main()
anyway, so this is a great tradeoff in most cases.
And yet:
- Some programs aren’t boring.
- Some programs demand more control.
- Some developers crave choice and accept the burden of picking each library and choosing how to wire them together.
- There’s a bit of a hero complex about rolling your own framework from libraries.
Where we end up is that I notice people complaining about frameworks. I think most of these are proxy complaints about someone else choosing a framework they have to live with. To their credit, some complainers are actively trying to make a better thing too. Kudos to them. To the idle complainers: cut it out.
2. I complain about a framework
RSpec and minitest are both frameworks in the sense that your entry point is a special class with special methods. RSpec is more frameworky in that you don’t actually write classes or methods. You use a language-y DSL to define test cases that share some aspect of scope. You can go pretty crazy in this manner. Or you can not go crazy, RSpec accomodates either style.
Lately I’ve been wrestling with test cases written using at least three kinds of RSpec scope and it’s driving me a little crazy. They look something like this:
describe "POST /something" do
before do
@thingy = somethings(:alices)
post :something, thingy: thingy
end
it { expects(assigns[:something].attributes).to eq(@thingy) }
it { is_expected.to render(:created) }
it { is_expected.to respond_with(:json) }
end
If scoping is about answering the question “what methods are available to me on this line of code”, this code seems to have four kinds of scope:
- Inside the
describe
block, we can call RSpec methods - Inside the
before
block we can call RSpec expectations and rspec-rails controller methods (but that is implicit!) - Inside the
it
blocks we can call RSpec expectations - When we call
is_expected
, we can reference…I’m not sure at all
It is at this point I try and take my own medicine and make a constructive observation rather than yelling “this sucks and someone should feel bad about it!” into the wind (i.e. Twitter).
3. What’s an RSpec for?
I didn’t like RSpec at first (circa 2008), then I really liked it (circa 2010), and now I’m sort of ambivalent. The question of what RSpec exists to solve has evolved too. At first it was “hey, BDD!” and then it was a less underscore-y way to build tests and now I think it’s a tool for writing tests in a style that some prefer and some don’t. In short, the Ruby community is figuring this out and kind of storming through the awkward parts.
That awkward part is how I think my example test came to be so unclear. Without doing a deep archaeological dig on the code, I’m guessing this code had three phases:
- Originally written according to the RSpec vogue at the time, which was to use
it
one-liners as forcing function on the constraint that tests should have only one assertion (Which in retrospect I think is a rule about the functionality of the method under test and not a guideline about how to write tests. This isn’t the first time developers have adhered to the letter of the rule and missed the spirit entirely). - Use the amazingly great
transpec
tool to translate RSpec 2.x style to RSpec 3.x style without having to spend months carefully transitioning a large test suite from one API to another. Mostly this works out great, but you get some awkward translation, like theis_expected
part. - Use the newer RSpec 3.x style
expect
syntax for assertions, introducing two ways to say the same thing with the intended long-term benefit of using the clearerexpect
style everywhere.
I don’t blame RSpec for any of these phases. You can easily swap out the names of libraries and concepts for any other language or library and find a similar story buried in any chunk of code that’s been around for more than a year and worked on by more than one person. It’s a thing that happens to code. I’m not even sure people should feel bad about it. Mindful of cleaning it up over time, yes. Throw it all in the bin and start over, no.
My first temptation is to say that using it
one-liners is a smell. They are nice to scan through but tricky to write and trickier still to change. But I can see where a series of well-intentioned code changes compresses many structurally similar test cases down to nearly-declarative (nearly!) one-liners without much duplicate typing. I can imagine a high-functioning team writing their own matchers, carefully using one-liners, and succeeding. So this one is a word of warning and not a smell.
The real smell, I think, is that its really easy to have very different scopes adjacent to each other in an RSpec test file. Further, not all scope-introducing constructs look the same! describe/context
introduce one kind of scope, it
introdues another kind of scope, let/subject/before
introduce three similar but different kinds of scope, and expects/is_expected
look the same but have different scopes as well.
Even smellier is that I’m making this list from an empirical understanding and not by examining the implementation or experimenting with reduced test cases.
What are you gonna do about it?
I’m probably going to leave that code alone. Wait for a muse to strike at the same time I need to make wholesale changes.
People who use RSpec should feel fine about themselves. People who contributed to RSpec should feel great about themselves. People who struggle with figuring out scope in RSpec should take solace that the best of us find this stuff confusing and frustrating at times. Developers not in one of these camps should take my advice, globals are bad but a bunch of weird scoping is not great either. Everyone else can smile and nod.
Organize your Gemfile by function and coupling
Most Gemfiles I see are either unordered (just throw new gems in, wherever!) or alphabetically ordered. A while back, I reordered the Sifter Gemfile, ordering by difficulty of removing the dependency and grouping by functional area. Thus organized, it came out a bit like this:
- Framework: Rails, Rack, the mysql2 driver, JSON, Rake. We will basically use these forever.
- Gems for our vendors: Postmark, Braintree, Skylight, Bugsnag. We'll use these as long as we're using their respective service.
- Partner integratons: GitHub, OmniAuth, etc. Most of these aren't maintained by the partner, and we'd have to drop the integration to drop the gem.
- Extensions: jquery-rails, delayed-job, will_paginate, etc. We could stop using these if we cared a lot, but we're pretty committed to them.
- File uploading: carrierwave, fog, wand, rmagick. We'd have to overhaul our file attachment support if we wanted to remove these.
- Sphinx support: thinking-sphinx and ts-delayed-delta. We'd have to overhaul our search to remove these.
- Admin: bootstrap, etc. Things we could easily remove next time we overhaul our admin, which isn't really a big deal if we decide to.
- Gems for building assets: jquery-ui-rails, therubyracer, execjs, coffee-rails, sass, compass, etc. We'd have to remove uses of the underlying tool (CoffeeScript, SCSS, etc.) if we wanted to drop one of these.
- Development gems: pry, ffaker, byebug, better_errors, spring, rack-mini-profiler. We can switch these out if we want.
- Testing gems: rspec-rails, capybara, etc. Again, if we change tools we can change these.
- Deployment: capistrano. This could go in the framework section, seems unlikely we'd overhaul our deploy scripts away from Capistrano.
This organization makes it easy to know where to add a new dependency. More importantly, we can better understand how much we depend on a gem and the level of effort to remove it if we need to.
Programming advice for a younger me
How to get better at programming without even programming:
- Accept, in your heart and mind, that the languages, libraries, and tools that you use to write programs may not be good for other people, other teams, or other problems.
- Search for deeper understanding of approaches to programming that seem strange or incorrect to you. Don't look for wrongness in what someone else is doing or what you're thinking.
- You will come across scenarios that challenge principles 1) and 2). When you do, say what you can to help but err on the side of not making things worse; let go of what you can't control.
Bonus: be a kind person.
Leadership, pick a size
Like fast food or coffee at Starbucks, maybe team leadership comes in three sizes.
Extra large leadership. “This is what you’re doing. Make it happen, let me know when it’s done.” The old school, top-down approach. This is what I thought all management was like many moons ago. In my experience this is only useful when people need to think only about what they’re doing, not why they’re doing it or how they do it. Leadership sets the work, lays out the exact process for doing that work, and closely monitors the work as its done. See also: Taylorism.
Large leadership. “Here are some things that need doing. Do one of them, keep me posted.” This is where I think cohesive teams of knowledge workers should aim to be. Leadership lays out the tasks to be done, makes the work to do clear, and gets out of the way. Luckily this is a lot more frequent lately, but probably not so much in part-time labor. Leadership still monitors the flow of work, but not overtly as in Taylorism.
Medium leadership. “Do what you think is most important. Let me know how to remove obstacles.” I suspect most leaders really want to get here, but are constrained, imagined or in reality, by some organizational detail. It’s definitely where I want to be in leadership style. High trust in the team, high trust in the leadership. Lots of unicorn dust.
Oddly enough, I think some teams and projects require large leadership and some require medium leadership. Some people want a little structure to their work, some projects require well-defined milestones to rally around. Other people can effectively guide themselves to useful outcomes, other projects are less about the milestone and more about the journey.
Pick one novelty per project
My pal Brandon Hays and I are fond of noting that projects have a very limited tolerance for the risk of picking a novel technology or approach. Thus, they should intentionally choose one thing to break ground on: database, language, domain model, testing methodology, design paradigm, etc.
Turns out, that’s sort of a thing in social psychology too:
Idiosyncrasy credit is a concept in social psychology that describes an individual’s capacity to acceptably deviate from group expectations. Idiosyncrasy credits are increased (earned) each time an individual conforms to a group’s expectations, and decreased (spent) each time an individual deviates from a group’s expectations.
Turns out this is strongly related to leadership, group expectations, and conformism. That explains a lot of my experience. Those most interested in trying novel approaches are often those who let expectations and conformism take a backseat to trying something new or breaking the mold.
I don’t think this is necessarily good or bad; it’s fine and healthy for a project to choose to vary from the norm in some way. Even better, manage those variances so if things don’t go to plan, you can back them out and keep rolling. But, it doesn’t hurt to consider varying in ways that are likely to yield more “credits” amongst your team.
Teach people to magnify their mind, not write code
Coding is not the new literacy:
When we say that coding is the new literacy, we're arguing that wielding a pencil and paper is the old one. Coding, like writing, is a mechanical act. All we've done is upgrade the storage medium. Writing if statements and for loops is straightforward to teach people, but it doesn't make them any more capable. Just like writing, we have to know how to solidify our thoughts and get them out of our head. In the case of programming though, if we manage to do that in a certain way, a computer can do more than just store them. It can compute with them.
That is, it’s not enough to write a loop in Ruby, a class in Java, or use a channel in Go. You’ve got to learn way more “material” than that: how to run your code in an application server, how to store rows in a database, how to deploy all your code to another machine. And then: how to have good taste, how to correct oversight, how to avoid bugs! And then, worst of all: knowing all the little miniutae like platform bugs, slow code paths, unstable code, dependency hell.
We shouldn’t put that upon people just because that’s how most programmers interact with computers. We should keep looking to help folks leverage systems as part of their work, not learn how to build systems to leverage systems to do their work.
Hence, the ending:
Alan Kay did a talk at OOPSLA in 1997 titled "The computer revolution hasn't happened yet," in which he argued that we haven't realized the potential that computers can provide for us. Eighteen years later, I still agree with him - it hasn't happened yet. And teaching people how to loop over a list won't make it happen either. To realize the potential of computers, we have to focus on the fundamental skills that allow us to harness external computation. We have to create a new generation of tools that allow us to express our models without switching professions and a new generation of modelers who wield them.
We’ve succeeded in magnifying our voices with computers. I like forward to standing back and looking with wonder at how much we’ve magnified our minds.
When software loses its hair
This is interesting, because the mechanism of growing a comb-over applies to software development. A comb-over is the accumulation of years of deciding that today is not the day to change things. A comb-over is the result of years of procrastination, years of decisions that seem right when you’re in a hurry to get ready for work but in retrospect one of those days should have included a trip to the barber and a bold decision to accept your baldness or take some other action as you saw fit.
A comb-over is a local maximum for improving baldness. You can’t really escape baldness of your head. You can escape a local maximum in your software, if you’re thoughtful about managing tradeoffs between product progress and technical progress.
It would have been better if you hadn’t gone bald in the first place though. Same with software!
(Analogies are just great. Thanks for this one, Reginald.)
Dining at the source code buffet
Let me start with a quote from wonderful person James Edward Gray II:
One of my favorite techniques for really learning a new language is to read the core API like a good novel. I’m a hit at parties!
I’ve had great success with this approach as well. I probably read the majority of Rails, the source of every RubyGem I used, and chunks of Ruby’s standard library in my first few years of working with Ruby. I picked up new tricks, figured out how things worked, and got myself out of a lot of tricky corners by reading code.
That we can do this is, to me, the real wonder of working with an open source stack. If I’m curious, I can dig into the framework, language, database, compiler, and operating system I’m using. If something goes weird, I can dig into it. I probably won’t end up changing or fixing anything below my app in the stack, but the ability to peel back the layers is a huge deal.
Given the choice of digging into why software sometimes goes weird and complaining or giving up, always chose digging into the source to see what’s going on.
When you work with open source software, you can always chose to figure out what’s going on around your app. Eating at the source code buffet is awesome!
Sam Stephenson, understated and excellent
I’ve enjoyed Sam Stephenson’s work for a long time. Even before “sheesh”, the most polite dismantling of an over-privileged open source user, Sam’s work has been top notch. Prototype is the library that made JavaScript palatable and learnable for me. pow and rbenv, in concert with ruby-build, are a lovely simplification of the weird problem of maintaining Ruby development environments.
The thing that pulls it all together, I think, is how well suited his solutions to diverse problems are. There aren’t a bunch of moving parts. Prototype was very much a library, and not a framework. His code is very much of the tool, playing well in the environment, be it Ruby, CoffeeScript, or even shell scripts. rbenv, ruby-build, and pow all play to the strength of bash and Node rather than trying to extend them to become something they’re not.
I was tempted to say his work is minimalistic. On second thought, I think it’s understated. Look at his website or photostream. The quality of just enough, but not too much, isn’t luck. It’s Sam Stephenson’s calling card. I love it.
How to succeed at Rails by trying
I think most teams, probably 90% of them, should start and stick with Rails conventions. Intelligently apply design principles, watch out for coupling that’s not worthwhile, carefully add dependencies when you must, sure. But don’t worry too much about erecting a wall between your app and Rails, building microservices, or whatever fashion dictates when you run rails new
.
That said, I don’t think strict adherence to Rails’ opinions is the only way to succeed when using Ruby to build for the web. You can adopt the principles of Rails’ opinions, e.g. use code over configuration to fight boilerplate or reduce the number of choices developers need to make by curating some libraries. You could document those principles and invest in new teammates by mentoring them up on your framework and tools.
Actually, you should do that anyway! But there are reasons you may not be able to do that: the team is too junior, time is tight, you need to explore new technical ground in other areas of the project. If that sounds like your team, you will benefit a lot from letting Rails do much of the tool-building, principle-seeking, and training for you.
The wolf moves fast...
The Wolf moves fast because he or she is able to avoid the encumbering necessities of a group of people building at scale. This avoidance of most things process related combined with exceptional engineering ability allows them to move at speed which makes them unusually productive. It’s this productivity that the rest of the team can… smell. It’s this scent of pure productivity that allows them to further skirt documentation, meetings, and annual reviews.
See also, The Grinder.
Well-tuned judgement
Lessons From A Lifetime Of Being A Programmer:
Never stop learning, the technology steamroller is right behind you waiting for you to stop.
I’ve taken this one seriously in the past, almost aways tinkering with languages, databases, frameworks, etc. I think it’s served me up to a point, expanding my mind and learning different ways to do to things.
The problem is I’ve reached the point of diminishing returns. I could go learn a stack-based language like Factor, or bend my brain around a oddly shaped database like Datomic. I’m not sure it would make me much better as a developer and leader of software teams.
Instead, the steamroller I think I need to keep ahead of is practice. Given a problem, what are three different solutions? What are their tradeoffs? Which approaches seem nice on paper, or in a blog post, but don’t work out a few hours down the road?
To wit:
This isn’t obvious to everyone, but the ability to see something new, or see what others are doing, or to compare multiple ways of doing something and then pick the best option for you, your team, your project or even your company is incredibly valuable. Most people I’ve seen are not very good at this. Most leaders are really terrible at this. It’s easy to just do what someone tells you you should do or something you read in a blog or just do what everyone else is doing. It’s much more difficult to look at things from all sides and your needs and pick something that seems to be best at that point. Of course you have to make some decision, people are often paralyzed by having to evaluate which often leads to picking something random or following the herd.
Well-tuned judgement is where I’m hoping to go next. Part of that is experience, knowing the forces and tradeoffs that apply to the possible solutions. Part of that is the ability to communicate it with teammates, sometimes face-to-face and sometimes asychronously. The really challenging part is letting your teammates run with the result of that judgement and collaboration.
A good developer makes good decisions for their own implementation; a great developer helps the whole team implement good decisions.
Conservation of complexity
You can’t fight the Law of conservation of complexity:
The law of conservation of complexity in human–computer interaction states that every application has an inherent amount of complexity that cannot be removed or hidden. Instead, it must be dealt with, either in product development or in user interaction.
Turns out one of my criticisms of microservices and microlibraries is a law. A LAW PEOPLE, YOUR ARGUMENT IS INVALID. Hilarious narcissism aside, keep an eye out for practices whose tradeoffs don't fit inside the depth of reasoning a blog post (like this one!) afford. Turning monoliths into services begets operational challenges. Microlibraries beget choices and wiring things up. Maybe the former is your thing, maybe it's the latter. Tradeoffs happen!
Executables deciphered
What's inside a compiled Hello, World program? Julia Evans is on that. How to read an executable:
Executable file formats are regular file formats that you can understand. I’ll explain some simple tools to start! We’ll working on Linux, with ELF binaries. (binaries are kind of the definition of platform-specific, so this is all platform-specific.)
I thought I had a rough grasp of how executables worked, and I still learned things. I love this format too. Julia Evans writes these fearless, curious posts about the deeply mysterious underpinnings of our computers and I learn a lot every time. More like this, please!
Microservices for grumpy old men and women
Microservices? I’m not entirely sure what they are. The term seems to exist on all parts of the hype cycle simultaneously. It’s on the ascent of excitement, the descent of disillusionment, and the plateau of productivity for different people, simultaneously. Some folks know exactly what it means, others know entirely nothing about what it means. Weirdness ensues. People talk past each other.
It’s a mess. Grumpy old man mode is in full force. (FWIW, I am the grumpy old man in this metaphor. I can not speak to the stature of Fowler or Feathers at this time.)
If I’m pessimistic, I nod along with Michael Feathers. He’s on to something when he observes the use of microservices as a blunt weapon against failures of encapsulation. Microservices become SOLID principles using units of deployment and even teams as a barrier between concerns. I feel that’s rather draconian.
If I’m optimistic, I cite Martin Fowler. To his credit, Fowler is doing the best work sifting through the noise and sensibly organizing what microservices might, in fact, be about. They’re probably not distributed objects, if you do it right. But you should understand the details, lest you get swallowed by the novelty and forget to realize the benefits. Make sure you’re tall enough for the ride your operations team is about to endure.
I get the feeling that radical approaches to working with Rails and microservices are tilting at the same windmill. You won’t fix the human tendency to build complicated structures with more software. Employing more buckets, or smaller buckets, in which to put your software doesn’t solve it either. You need a human factor to jump in and say “Hey, this is complicated! It might even be essentially complex. Let’s manage that complexity.” If you’re actively managing complexity, microservices or monoliths, Rails way or your own way, microservices and decoupling are a lot more of a detail than a foundational principle.
Thought + Quality
Oliver Reichenstein, Putting Thought Into Things:
Quality — as in “fitness for purpose” — lives in the structure of a product. A lack of quality is a lack of structure, and a lack of structure is, ultimately, a lack of thought. One does not find a solid structure by following some simple method. We deepen the structure by deepening our thought on the product. Our role as designers is to put thought into things.
I've noticed I do the worst, as a developer, when I'm using tools and methodology to avoid thinking. Not entirely sure how to solve this problem, write some tests and commit whatever makes them green. Troubleshoot by tinkering with commenting code out, trying different incantations, pasting snippets found on the internet.
Each advance in how I build software is lead by finding some way I defer or avoid thinking and correcting that shortcoming. In doing so, I find myself a little more opinionated, a little more specific about what really matters in making software and what is dressing.
Put more thought into what I build. Always think about what constitutes The Quality for the kind of software I want to build. Seek to avoid the tech vogue in search of deeper quality and thought. I’m far from mastering any of these disciplines, but the results so far are promising.
When Developers Design
I see lots of “should designers code?” articles and introductions to coding for designers. I see far less interest in the converse. So what’s a designer think? Cap Watkins, a designer; Should Engineers Design?:
If you think design is 100% about creating “design artifacts”, I’d say your scope is too narrow and has the potential to stunt your personal and professional growth.
There’s so much to designing that isn’t about choosing colors, fonts, producing icons, or drawing. Developers can, and should, get involved in how the applications works, how copy guides the user through workflows, when to prompt about invalid data and when to fix it automatically, and how to help users through interactions. That’s design!
To wit:
Throughout my entire career I’ve had engineering partners deep in the design process with me. I show them sketches, bounce ideas off of them, have whiteboarding sessions to figure out what we’re going to do. I trust engineers I work with to let me know when something seems confusing, when there’s an edge case I haven’t thought of and to push on my ideas to find where they break and help me make them even better.
Developers often don’t even realize they’re designing when they’re building libraries and tools for other developers. Writing a good README so developers know why your project is awesome and how to use it? That’s design. Sweating the details of an OO or REST API? That’s design. Opting to remove a feature or solve two problems with one feature? That’s design!
The design was in us the whole time, and we didn’t even know it!
I leave you with this excellent wisdom:
When you look at design as a process and not an artifact, everyone on your team becomes a designer. We have different areas of expertise and skill, no doubt, but the product experience belongs to every member of the team. The more familiar you are with each other’s responsibilities, the more you’re able to participate with and help each other out when needed.
Here’s a fun thing I do that you should try: when you read articles about design, squint a little bit and pretend it’s about designing programs. You might find something you want to try the next time you sit down to work on some code.
How Rails fits into the front-end
Is Rails well positioned for where the web (on all devices) is going? Pal Dave Copeland asked that on Twitter. Turns out I had plenty of opinions!
- I buy into the notion that the majority of applications don’t need much special in the way of browser-side functionality. SJR, a little bit of CoffeeScript, and SCSS will do you fine.
- For the rare team building ambitious applications, an opinionated framework like Rails is probably the last thing you want. Ambitious applications, perhaps by definition, are going to cut against the grain in one or more places. An opinionated framework is only going to get in the way of the opinions that make the application ambitious in the first place.
- The web is in a weird place. I think it’s a somewhat risky environment to build for browsers right now. The combinatorial explosion of devices and browsers means that you’re almost certainly giving some non-trivial class of user a suboptimal or buggy experience. Choosing where to spend your effort seems like a non-fun process.
- There isn’t a high-quality, well supported, well conceived ecosystem that currently exists for browsers. Rails and iOS both succeeded with a combination of smart conception, (mostly) excellent execution, and supportive communities or vendors. Front-end technologies are deeply splintered right now.
- I suspect there’s no opportunity for Rails to crown a winner in this space until the Cambrian explosion of JavaScript and CSS practice coalesce into something coherent that most developers can relate to and execute.
- But, if I had to wager, my money is on Rails choosing Ember as a default choice. This would happen on the trailing edge of fashion though, in the same way that jQuery didn’t become the default for Rails until long after jQuery became the go-to choice for most front-end developers.
- Even if the Rails core team could pick a winner on the leading edge of fashion, I don’t think it would work out. The Rails core team has much less experience with the front-end than the back-end. Historically, the choices have been OK (CoffeeScript turned out well, Prototype+Scriptaculous was an excellent early choice) with a recent trend towards provoking wild disagreement (e.g. CoffeeScript and Turbolinks).
- I think a lot of this comes down to Sprockets’ ability to gracefully grow to support front-end practice. It already does a pretty good job. Adding better support for browser components (e.g. Bower) would be good, as well as keeping up with SVG, web fonts and other somewhat special asset types.
If, tomorrow, I did have to build a Rails app whose web experience was crucial, I’d be as conservative as possible with my library choices. I’d stick with the oldest, boring-est, best-tested JS and CSS tools until it wasn’t feasible anymore.