Ask HN: As an experienced dev, how do you learn a language/framework quickly?
My challenges with existing tools:
- Books are pretty verbose and don't do a great job covering popular libraries (e.g., the top NPM/CocoaPods/Gems that are part of so many startup products)
- A ton of articles + samples online are designed for novice programmers approaching a language
- Online videos are super slow moving (even when you speed up playback)
- Progressively more difficult sample code would be great - but it's hard to find the right progression and most are missing the annotation that explain the vagaries of the language or framework
- Perusing reference docs for the purposes of learning is too 'exhaustive search' (e.g., why isn't there a doc for say underscore.js that rank orders functions by incidence of use)
I'd love to hear what the HN community does - with a focus on learning a language + framework by experienced engineers for the purpose of building startup products (i.e., not simply for the purpose of becoming a language/framework expert but rather to build something as quickly as possible).
1) Type into Google: "Package manager for Ruby/Nodejs/PHP/Python/etc"
2) Find a site that lists packages for that language in order of downloads per day or week.
3) Look at the top packages to see what the most popular frameworks are. Generally the top 5 - 10 packages will be all you need to develop 95% of basic projects.
4) Look into the repos for each of the top projects and look for an "examples" folder. Most top projects will have basic examples that will not only bring you up to speed on common language patterns, but also help you learn the most common and most useful methods of that framework.
5) Import any packages you need for your own project, copy a relevant example from one of the packages to start it off, and begin customizing.
Personally I learn best by example, and I find that the examples in the top frameworks and packages for any language are all I need to get up to speed in a day or two.
As to how I'd go about building an internal tool, like say a dashboard for my SaaS app but this time written in Golang? I would blow up Google with a series of queries for [golang web framework], [golang mysql adapter], [golang Stripe library], and keep Googling every time I hit a roadblock. (I suppose there could theoretically be planning at some point but the nice thing about internal tools is if you create a creaking Frankensystem then what is the worst that happens? It takes 800ms to load instead of 300ms and you have to keep it behind the firewall, where you were going to put it already?)
Another nice thing about internal tools: if you find yourself banging your head against e.g. image generation for too long you can always just wire up a trivial internal service written in a stack you're more familiar with to call out to your usual image generation solution, and then just consume that service with the new app. Then make a note "Note to self for rainy day project: Figure out how to do image generation in Golang."
My approach is actually fairly consistent across languages/etc., and it usually gets me up to speed/gets me to a point where I know enough to work with something, but certainly doesn't make me an expert in the language or framework.
I start by doing a hello-world equivalent, usually with some sort of input and output. (E.x. "What's your name?"->"Dave"->"Hello Dave!")
Then, I usually go through some sort of basic program to get an idea of how the language features work and how things are done in the language. Exactly what depends on the framework or language; but usually of comparable difficulty to a dynamically resizeable array with basic algorithms like 'sort' (merge, quick, etc.) in C. The idea is to write something you're fully capable of knocking off in less than two or three hours, and is <1000 lines of code but isn't trivial. My reasoning for this intermediate step is that a large project needs to have some sort of structure, and if I don't have at least a rudimentary understanding of how things work in the language, then I'm going to have a bad time.
After I've done that, I get started on the actual program or project: I start by constructing a rough framework of how I want to structure the program and then slowly add in the parts that I want, restructuring if it's necessary.
Throughout the process, I look at websites/books/documentation/code examples/etc., particularly if I don't know how to do something or think there's a better way than what occurred to me.
2. Read tutorials.
3. Devise some useful side project I could build with the language. Don't just go try to build them.
4. Build a couple of tiny utilities in the language.
5. Build something ambitious --- as in, something that would be ambitious even in my wheelhouse languages.
6. Reread online material about style, refactoring, libraries, &c --- I can't appreciate these fully or retain them until I've completed the preceding steps.
So, for Golang, I did:
1. Slurp up all the "what makes Golang awesome" stuff, read HN threads, &c.
2. Read Effective Go.
3. Decide "this would be great for building a large-scale web crawler backend"; gears start turning on how the different parts of the language would mesh for me.
4. Build a TLS proxy, a simple hex-dumping plugboard proxy, a CA library to do on-demand certificate generation.
5. Build an emulator for the TI MSP430 CPU and bootstrap it to the point where I can compile mspgcc code and run it on the emulator.
6. Read every blog post on the Golang site, start paying attention to Golang threads on HN and chiming in.
Step #6 is the step I'd want to be at before asking questions on the project's IRC channel.
I could break out Ruby, Python, Tcl, and C++ into the same set of steps over the past 10 years (my "native tongue" is C).
This is just how I do things, not necessarily the best way to do it. Also: when I'm learning, I favor a sharply NIH style --- I actually try to avoid fancy libraries, especially for stuff like Golang and (at the time I learned) Ruby, where the language is "hot" and the ecosystem is full of stuff that might not last. I'm worried about doing what Jamis Buck did and introducing dependency injection into Ruby, and then having to waste time undoing that.
I have in the back of my head 3-4 fairly ambitious projects I've queued up for the purpose of learning, say, Clojure or F#.
-Localization (amazing how many web frameworks suck at this, specially, client-side frameworks)
-Learning curve
-Authentication / Authorization
-CRUD, REST, TDD, LoC
-Template language
-Fragments/Tiles/Panels support
-Deployment (i.e. grails WARs are amazingly big)
Over time I've made this webapp in Grails, Play, CakePHP, RoR, Django, Flask, Wicket, SpringMVC, Struts1-2, Hibernate, jOOQ, Angular (ugh!), ExtJS, Express and Meteor.
What I like about this is that I don't have to think about how the product will work, no design, and I can reuse most of the HTML structure (header, footer, menu, etc) and I can compare and reach a conclusion about the framework pretty fast. If I can't make the freaking thing work after two days, the framework sucks or I'm simply too stupid to use it.
Most programming languages use ideas that already exist in other languages, so the more languages you learn, provided they cover the breadth of the major paradigms, the easier it is to pick up new ones. Alternatively, if you can't take a course or don't want to, make the effort to become competent in a number of languages that cover the spectrum described above. C++ developer? Learn python for the dynamic \ functional aspects. Then learn Haskel to force you to think pure functional. Or OCaml. Learning js, due to the way it implements objects, also taught me a lot about object oriented programming, as you are forced to use closures to get private variables, and it's object model is primitive so learning to work with that can be educational.
For me it works well to solve the little problems like routing, templates, etc. on simple/dumb things and add complexity over time.
Like, build a blog or twitter type app that maybe does basic CRUD type things, and has some kind of data listing etc.
For example, when I was trying to learn about React.js, I spent a day or two of research to write this, which is the kind of documentation I wish had existed in the first place: http://blog.reverberate.org/2014/02/react-demystified.html
Maybe Its just because I know the backend well enough, a switch from Perl to Python was quite effortless, but making the same jump to javascript, I find a lot more difficult.
It only takes a few hours to go through these basics and get a tour of the language. I try to sit next to someone who is using the language if possible - they often have tips and tricks that they have found through trial and error, and can cut time off your learning.
I can generally become productive in a few hours. That affords me time to learn the deeper structures of the framework as I go along. Having that initial core understanding really reduces issues down the road.
This way, you're focused on learning the framework and how something is achieved within that framework without bothering to think about architecture, features, etc.
This is how I learned Symfony (I came from Zend) and it served me well!
I always start out getting a book, which I then don't read the majority of (although that is a luxury of moving from web language to web language instead of something more drastically different). I'll read how to get the project setup, and skim basic framework object structure (this is where having a book you can easily skim back-and-forth in is handy). Then I'll just start. Most simple stuff (syntax to traverse a collection), I'll just Google quickly. Inevitably I hit a framework aspect that's unique or in-depth enough to merit study, and then I'll read that section of the book completely.
If you're using a third-party library with source, stepping through some of the logic is generally something you end up doing anyway, but it's pretty useful to do right away to get an idea of some of the optimal structural tricks the more familiar devs use. Maybe follow a couple of API calls for a step or two to see how they arrange things.
Once you've done enough to feel comfortable (maybe the first couple chunks of complete functionality in the bag), it's good to Google around for things like "Common Mistakes/Pitfalls in X". You'll probably have run afoul of a couple of those, and will now be familiar enough to understand and remember them. You can go back and clean up the little bit of code you did then.
I also try to understand the motivations behind making it, and what they were trying to accomplish as a goal. I have to try to make sure I don't force paradigms from another framework/language on this one.
Generally this involves following whatever basic "getting started" procedure is available - this typically covers the big-picture details of repo structure, package management, general philosophy etc. - as an experienced developer, you've probably had enough exposure to various processes, tools and paradigms to easily understand how you would approach building whatever you're trying to.
I often come up against things that I'm not clear on the canonical implementation of - but a quick search usually clears that up. I think of it much like learning a human language, and imagine it's much better if you're immersed in it, than it does if you try to learn it from a book. It does mean you're more likely to make mistakes, but so long as you leave a little buffer for rearchitecting things when you've done them wrong, that's all part of the learning process.
I've especially tended to avoid books and longer-form articles—they often seem to be really out-of-date and different from the current best-practice, particularly for newer stacks.
However...sometimes I'll just copy an example...the manual typing-out of code, for whatever psychological thing in my brain, really stimulates an extra sense of observation in me...I think part of it is that when I just read code, my brain is thinking "OK OK, get on to the point!"...but when I slow myself down enough to type out the code, my brain thinks "OK, while we're waiting for the typing to finish, let's think about this code".
If that's too easy for me, sometimes I'll make the exercise tricky for myself by coding in a different style. This can involve rewriting the original thing, even altering the functional design and interface...or, with JavaScript, re-writing a JS-framework-example in CoffeeScript (which kills too learning-birds with one exercise)
I have a suspicion that this works well for certain kinds of learners, though not all. I'm probably in the former camp (very visual/tactile focused).
- Most online stuff is decent for the first 2-3 weeks.
- Meat of the learning is done in the trenches with the manual of the system ready-to-hand (i.e., google).
- choose a small and stupid project for using it in anger. I favor one of these:
These represent a slice of common & standard tasks involving libraries, string handling, interfacing with other tools and data structures. Most of my work generally involves one of these 3.Too often "studying" can be procrastination. Find a kernel of the language that's "just enough" and run with it.
I used to try to read books, but I find for me it's much easier to use books as reference than as introduction. You find the corner cases in a language very quickly if you just move fast and break things.
2. Play around a bit. See if you can get the basic tools (compiler, IDE, emacs extensions, whatever toys fit in your own sandbox). Write a "hello world". Get something built and running quickly. Even if it's just a loop that counts to 100.
3. Once you've played a little, go read a little more code. That's your scaffold for learning.
4. Come back and play some more.
5. Add to resume and see if someone will pay for you to learn some more. If not, repeat 3-4-5 until you've got a contract where you will be compelled to master the language, or...
6. Once you're doing something in production with the code, evaluate against other technologies you've used to get there. Does the new language work well? Does it play a role for you? Or is it flawed at scale? Maybe it's good for prototyping. Maybe you find it's really not good for anything and teaches bad habits. Add this knowledge to your base, and...
7. Go back to step 1 again. Repeat for entire career.
It's worked for me. I've had a lot of fun engineering. And when I get to step 6, I keep coming back to Java, over and over, as much as I'd like to move on. But that's a topic for another day.
A real project will get you used to doing real stuff, and if it's sufficiently non-trivial, will serve as a great drill for the basics (e.g. string concatenation). It will also help you get very familiar with the documentation, and the community around the language/framework. In the case of Go, you'll also learn to always search for "golang [problem]" rather than "go [problem" ;)
As an exercise in learning Golang, I built a really tiny service for something I wanted (an app that would read Hacker News to me with TTS). It took about 15 hours over the course of a week, and most of that was in debugging/reading/debugging mode, trying to figure out why I couldn't just unmarshall this JSON blob into a struct (turned out the struct fields needed to be string pointers, not strings).
For instance once I was building a recipe search engine on a new platform in python, my process went like this:
1) Make 1 table in the database, for recipes, with the constraints that I needed. (Learned Model Representation)
2) Build a lame page which would pull a single recipe and show it. (Learned Basic View and Controller)
3) Build a page where I can type in a query and get some recipes back. (Learned how forms are handled)
4) Added way more DB Tables to cover most of the data schema. (Learned more advanced DB operations)
5) Built better looking Web pages which would be more responsive. (Caching, Static file handling, more advanced controllers)
6) Built actual search code
Although this is a specific example, I find using a method such as this, where I start with very basic problems of the larger picture, allows me to get moving very quickly. Furthermore, as I start knocking off the easier stuff I feel more confident and I learn the best places to find answers for my questions for that framework.
See source. See source build. See source Run. Three very, very important steps. Each step requires patience and much verisimilitude in the face of extreme danger, fear, uncertainty and .. doubt. What you don't doubt, you don't really know. Doubt, always, whether you understand something properly, even if you've been using it for a while. You can always learn more, but the first step starts with just a little doubt .. or question .. or intrigue .. about how something may or may not work. Guess about it, if you don't like doubting so much. Guessing how much something you doubt, works, will reward you when you stop all the psychology and just get on with: See source. See source build. See source run.
Never forget, you'll never use all of the power of the computer, ever. Its not the power that matters. The only thing that matters to a computer is the user. Nothing else is interesting; getting the user to the computer is what development is all about. Develop until done.
I just got a program in racket up and running, and not knowing the program or Racket, I hooked up http://docs.racket-lang.org/reference/debugging.html and started to map out the transform and flow of data through the system.
Example: http://ycombinator.com/arc/tut.txt
There's a really good one for Python but couldn't find it.
I like those tutorials because they explain the high-level vision of the language with low-level syntax and practical stuff. Once I "get" a language, it's easier for me to just look up what I'm missing when I need it.
I usually do:
And in term of "hacking something", I usually create an IRC bot. Why? Mostly because it brings great memory as it's how I learned to develop when I was a kid. But also because it's very practical. You need to work with existing libraries to manipulate strings and sockets while doing non-trivial stuff. I used to know the IRC protocol by heart so I just had to focus on the syntax of the language.Latest example I was messing around with Sails knowing nothing about Node. We had one semi-experienced Sails user in the room and within 30min everyone was running Sails and we had created some pages and routes for everyone to screw around with easily.
Maybe that's the lesson. Find some other experienced people and one who is experienced in the exact tools. You will generate the same noob problems from multiple angles while having the experienced person to keep the stupid in check.
You can find these people. Go to an event where everyone's required to hack something that weekend and put together a pile of engineers. You don't have total control over what you get, but in my case, I got to mess with some Node. It wasn't mind blowing, but I know that it has a strong ecosystem for real-time clients.
The nice thing about this is I can spend as much or as little time on it as I need. Even figuring out how to set up and build a project in a new language or environment can teach you a lot. Often my first step is to jump in and change a bit of text, since that's usually easy to find (grep). Sometimes even this simple of a change will open up a can of worms (in other words, a path to great learning).
Then, I come up with a simple project and build it. Often, I will use a new technology when prototyping.
But be careful, there's a big gap between getting to the point where you can get something to work with a bit of persistence, versus knowing the "right" way to do it in that language or api.
You say you could probably learn to build an ios app in a week or two given your background, and you're probably right. I have a similar background and it took me about six weeks, working on evenings and weekends, to put together my first iOS app from not knowing any Obj-C. But now I've been building iOS apps for years, and when I looked back on that first app I cringed. I've actually rewritten most of it by now.
So, I'd suggest 1. Get enough from whatever source you like - books, online tutorials to get started on your own project. 2. Start working on your project. Google for best practices, libraries whenever in doubt. Post questions on SO when you can't figure something out. When you need to go in-depth into a topic, find good documentation on it and take time to read it through.
Rather than trying to learn a thing inside out I like to pick stuff that can be immediately useful to me and build some small stuff with it.
For instance I am learning lua (and open resty) at the moment now lua is itself a very small language but I am new to it none the less. I tried reading a programming book but I got bored quickly as it repeated almost the same stuff that I have gone through many times before(operator precedence etc).Instead I created small utility apps that were useful to me immediately.
Like I created a lua script that cd-ed into a directory and started an elastic search server. Another one that abstracts couchdb api into quick command line options (I got tired of typing long curl http requests into the terminal) and does other things like replication pushing design docs etc.
I use books as reference, something to come back to, unless there is a book like learn you some erlang which I read cover to cover :)
One is where you know what you want to learn (iOS, say). The question is, how do you efficiently learn it (or at least the bits that you are most concerned about learning). There are several good comments here along the lines of "download the tools, read the basics, start building something, look for help when you get blocked."
The second scenario is when you don't know what you want to learn. Should the next thing you learn be iOS? Android? Ruby? Haskell? And if you're not just going to go by which set of fanboys is loudest, you need to learn a bit about the candidates so that you can decide which is the one to dive into and really learn. The problem is that there are more candidates than there is time (especially if you count not just languages but frameworks and tools).
I don't have a good answer for how to find out enough to decide whether a particular language or framework has enough substance that it's going to pay back learning it.
1. If the framework or language contains paradigms that are new to you, start by getting a learn-by-doing book like a pragmatic programmer guide, and work your way all the way through it.
2. Start doing little projects that are personally relevant to you. These can be anything: little math problems from projecteuler, data analysis problems, technical interview questions. Which projects you choose are less important than you being motivated to sit down and actually finish them, solving both the easy and fun parts and the annoying "shovel work" parts.
3. Sign up to teach someone (friend, coworker, meetup group) what you just learned. The pressure of the impending performance will force you to deepen your understand of the new topics. This is also known as the "Richard Feynman method of learning"
Unfortunately with iOS and Android, you are stuck with what Apple and Google offer you.
Tutorials are nice, but ultimately very hand-holding, and leave too many questions left unanswered (i.e. "why the hell is this here?"). If you can build something where the answers aren't immediate, then that requires you to actively seek out the answers and make beginners mistakes that can only be fixed by knowing the quirks of the language/framework. If it takes effort to learn something, then you generally won't forget it.
When I started working on my circuit sim in javascript, I had only the faintest idea how javascript worked by running snippets of it directly embedded into my html. Now, I'm pretty familiar with the gotchas, especially the painful ones.
Find the koan collection for each language. Pretty good for syntax and peculiar idea demonstrations. Not so good at project design.
"build it as quickly as possible" and when you hit a roadblock start googling to find out how someone else got past it. Thats a PITA, surely there exists a library for that?
Also blog posts / podcasts by devs for devs and read between the lines a bit. Not so much what are they specifically talking about but more generally. Nobody talks about XYZ and nobody mentions solutions to ABC, but everyone's got an opinion about DEF and GHI.
2. Read up on the best practice idiomatic approaches for such problems in this particular language/framework. This will usually be significantly different than doing stuff according to the pre-existing habits.
3. Solve problems as they arrive, by judicious use of [parts of] tutorials relevant to implementing that part, finding appropriate libraries and learning all the surrounding ecosystem of tools, libraries and related projects.
For mobile programming I recommend watching the Google I/O and WWDC videos. They are verbose but it is the real deal.
Otherwise I like to do small tech demos or do tutorials from books.
Learn the IDEs better right away too. option-click stuff in Xcode and learn whatever Android Studio is supposed to do(I kid).
Learn to Read the Source, Luke | http://blog.codinghorror.com/learn-to-read-the-source-luke/
The great books will sometimes be bought outright, but by then I know well what I'm getting.
Once you have gone through the course do a small project. I like something more involved than a "TODO" application.
Two summers ago, I had a Ruby/Rails internship, and before the internship I'd never touched Ruby or Rails. Since I needed to learn on the job, I built myself tiny applications in Sinatra, then Rails — and then could apply it at work.
The key, I think, is trying to build something specific with your tools.
Eventually things just start to click for me.
2. Make something trivial or extend the example code
3. Read the documentation while doing so
I'm not a massive fan of frameworks, even though I helped develop one myself http://were.cat-v.org
https://giveit100.com/@marbemac/9r2pkz
Conceptual overviews (if one is available) -> tutorials -> exercises -> make a small thing -> make a bigger thing