Really good discussion of what falls apart when these "anyone can learn to code!" tutorials leave you high and dry, and how to get past that next huge hurdle of self-sufficiency.
As someone who is currently learning how to code, the author gets it mostly right.
For me, the hardest parts of programming as a beginner - understanding OOP, data structures, etc. - didn't really 'click' until I stopped reading tutorials about them and start writing my own programs. The idea of 'objects' and 'instance variables' was mind boggingly confusing at first, but once I stopped worrying about how to make sense of them, the concepts somehow just fell into place.
I've also been trying to learn French simultaneously. The process was somewhat similar - taking a few Duolingo lessons and thinking that 'hey, I can do this!'. Then I read some actual French prose and everything seemed impossibly difficult. Things didn't 'click' until I started living and breathing French.
Yeah, that too. I have a humanities background, but I was always keen on mathematics. I know this is not true for a lot of my peers who studied the arts.
Really makes 'anyone can code' sound more like a marketing slogan than an evidence backed statement. If your math and logic game is weak, you'll have a hard time with anything beyond the most cookie cutter PHP code.
I have been coding for a long, long time. Since the 80s. But I got started with the idea that I wanted to 'build' something...I think it was a randomized dice roll or something. Having something you are trying to actually 'make' will cause you to learn what you don't know, and keep going.
It's no different than saying 'I want to build a tree house'. as opposed to 'I'd like to learn how to do construction' or 'I'd like to understand how to build with lumber'. The first statement will drive you to figure out or learn what it takes to make something tangible, the second two statements are just nice ideas, easily discarded when things get difficult.
Indeed, you can only get good at programming by doing it.
As someone who learnt programming in the 90ies, one of the difficult things nowadays seems to be that there are so many languages, libraries, frameworks, hypes, etc. Of course, if you know your CS and have experience, most of it are variations on common themes. However, I can imagine that it can be very difficult to focus on one thing and learning it well. There must be many copy & paste programmers out there who never learn anything in depth.
At the beginning of the nineties things were much simpler. If you had a home PC (obviously without internet), you could get started with QBasic, or shell out some money for a compiler and get Turbo Pascal or Turbo C++.
I did quite a bit of Turbo Pascal programming at some point and it was all very understandable. A simple language, a small standard library that's probably all that you'll have, good documentation, and an IDE (which had a very nice debugger and profiler). And you just crafted tools with that.
I actually learned HTML, CSS and JS way back when I was in 6th grade. This was pre dot-com time and there were only a handful of resources. You could understand HTML and CSS in a day because there were so few HTML tags and requirements. 'Frameworks' was something that didn't even exist.
I somehow stopped my learning process before I hit 8th grade (around the same time I discovered that the opposite sex exists). When I picked it up again recently, the sheer number and complexity of frameworks and languages itself was daunting.
I can't imagine how hard it must be for someone who hasn't had a lick of coding experience. I could at least build a good looking website in HTML, CSS and simple JS before I started learning how to code.
It's damn tough and it has given me newfound respect for top coders. I work in marketing in my day job, and honestly, you could teach someone to replace me within a few weeks
I always thought the "Desert of Despair" was the point at which you should find a mentor with professional experience, instead of waiting for the "Upswing of Awesome".
The upswing of awesome sounds like a great way to prepare yourself to build things that are 90% correct with a 10% catastrophic failure rate.
I really try to keep a more emotionally neutral stance on all of my code and my abilities. If I want to indulge in arrogance I philosophize.
In the end, it's the same thing over and over again. Symbols swapping with others symbols denoting some kind of esoterically tangible, but ultimately fleeting, meaning.
It'd be nice to not feel perpetually stuck in the desert of despair though. I used to think being there meant I was learning stuff, because I had intuitively learned from repeat failure that after failure comes success. Turns out you can think about yourself plodding along at a steady pace, with no comparison to anyone else, as long as you stop assuming that there exists a clear, coherent, ordered organization to knowledge.
There exists such a thing in school, or at least the commentary on a topological sorting would have you believe. Technology doesn't always develop and get released in school though. Sometimes it develops in webs that are can not be causally described, because thought and skill do not necessarily travel in measurable directions, nor is their instantiation completely definable/observable.
People apply too many theoretical concepts to describe, dictate, and organize reality without understanding the effect on perception.
You've made an interesting comment. I've felt the same way about some of the things you've mentioned, such as
"In the end, it's the same thing over and over again. Symbols swapping with others symbols denoting some kind of esoterically tangible, but ultimately fleeting, meaning."
I feel that way about all the different languages, new ones or old. Just different symbols that distill down to machine instructions.
My question to you, how do you approach learning? Learning new things and marking your progress?
What gives you the satisfaction that you've made progress in "learning" a given topic?
> My question to you, how do you approach learning? Learning new things and marking your progress? What gives you the satisfaction that you've made progress in "learning" a given topic?
I don't know. Right now I am learning how to not know when I am learning, because I have determined that measuring learning in any form can often be a barrier that actually prevents me from learning.
I can't remember the source, but I learned this in a management class in college about 10 years ago. It was a general statement about learning something new. You don't know what your don't know (so you are optimistic) -> You realize you know nothing (so you are negative) -> Then you get better with practice -> Mastery
Personally I find the confidence vs competence graph to reflect my feelings when learning things in general, although not necessarily for the same reasons. There's always a period of eager discovery followed by the stark realization of how far away mastery is and finally the gradual slow crawl toward success.
Having taught many non-programmers to start their programming journey, this article rings very true.
The "cliff of confusion" he describes is a function of the Dunning-Kruger effect (http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect), which indicates that you don't know how bad you are at something until you get better at it. As an educator, the challenge is to make that cliff as unscary as possible and chart a path through the "desert of despair" so that you're not pushing too much at one time.
On the other hand, as a self-learner it's really really hard to get past the point where you've learned enough to know how much you have yet to learn, or in terms of the article, when you look over the cliff and see how HUGE your journey is becoming.
To a large extent, the article is an advertisement (in more ways than one) for guided learning, expressed in a pretty clear way.
Totally unrelated to this, but I was interested to see how often the Dunning-Kruger effect is mentioned on HN, since it seems like the comments on almost anything will inevitably yield some reference to it (the opposite, impostor syndrome, comes up quite often too, but has a more obvious and less interesting name); a quick search yields 730 results for "Dunning Kruger" over all time, and half a dozen in the last week alone... which was perhaps a little less than I was expecting, but still rather a lot.
Totally unrelated to that, Algolia's HN search really is magnificent - supremely fast, accurate, and even quite attractive. Impressive.
Totally agree. Helping novice programmers through that time of "Oh my god, I know nothing, I will never be good at this" as their world is expanding is crucial. I think having a support system can make a big difference here -- and it might last months or even years until you feel confident enough to work full-time, when you'll re-enter the desert (since the tools your job uses probably include at least one thing you're not familiar with).
One thing that I think separates senior engineers from juniors is a level of confidence and willingness to tackle the unknown and learn new things, tempered by pragmatism that they don't all need to be tackled and learned right away.
The Dunning-Kruger effect pretty much sums up myself. I feel like I have a firm grasp on the structure and syntax of JS, but now I'm questioning whether I really do. I always feel awful, as I can't really implement anything, and am always frustrated when I can't get off the ground starting a project.
I just don't know how to actually _do things_ with code. So, in essence, I think I know the language, and in a sense I do insofar as I know how to write an if else statement, a while statement, declare a variable, etc., but I _don't_ actually know the language, because I can't do anything with what little I do know.
Build something, anything. Then set it aside for a while, come back to it and improve it. Reading code you wrote a couple of months ago will highlight very quickly the parts that are clear and concise and those that are not.
Pick an open source project that is interesting to you and improve the documentation. Writing clear documentation requires a depth of knowledge that surpasses just employing it.
Give a presentation on and/or tutor someone on a topic. Like writing docs, this requires being able to think clearly about the topic.
For me, by far the hardest part was finding the time. Learning to code on nights and weekends, when you've spent your most productive and focused hours at your job, is a nightmare. It wasn't until I was actually hired as a dev that I started to hit a steep learning curve, and I attribute much of that to spending 50 of my best hours/week coding, rather than maybe 20 of my worst.
From the sounds of it, you weren't at Erik Trautman's "Job Ready" point when you were hired (and weren't going to get there without being hired). How did you write your resume and handle interviews?
Very true, I had probably just entered the "Upswing of Awesome".
I had quite a bit of experience with relational databases from my previous job, which I leveraged pretty heavily on my resume. As far as interviews, I was very honest about what I did and didn't know, and passed a coding test by pulling an all-nighter (and taking a vacation day) to learn a tiny bit about Django.
The offer came from a company I had initially reached out to about an unpaid internship, which eventually manifested into a full-time job. We agreed to a three month trial period, and they kept me on afterwards.
There was no doubt plenty of luck involved in the whole process. I sent dozens of cold emails, and offered to work for free several times (thankfully never had to).
I have the same issue. I've set aside 10pm-2am every weekday to learn how to code, plus entire Saturdays and Sunday mornings. I can, at most, manage 20-25 hours, usually when I'm already bogged down.
I've been toying with the idea of quitting everything and going all-in for 3-6 months.
Would that be 100% retarded or just about 70% retarded?
You'd be an excellent candidate to get a lot out of a coding bootcamp. If you have like $10k in savings or money you can borrow, you'd be in an excellent position to try something like that.
PM me if you'd like to talk about my experience with one.
I had the option to quit to work on learning to code for 3-6 months and I chose to bite the bullet and stay employed. I woke up at 4am to get in a few hours of coding before work and kept my working hours to a minimum so I could have a few hours after work to code. Weekends were 12+ hours of coding both days. It doesn't leave a lot of room for social life or other activities, but the job search was a lot less stressful knowing I still had a paycheck coming in instead of burning through my savings. YMMV!
You'll want to account for this all-in time on your resume. (Unemployment gaps are a red flag to companies.) You could put together a company of your own, for example, and frame all your study time as product/service development.
>Would that be 100% retarded or just about 70% retarded?
I'll go with "less than 70%". Or at least I hope, because that's what I did.
Coming from a Economics background (with a minor in Statistics), I took a job as a "data analyst" at a software company out of University. It was fun, but I relied on working with a programmer to get even basic things done.
Then came the "Data Science" wave. I thought, this is right up my alley! Except I needed to learn to program. I tried doing the tutorials and academies online, but was continuously stuck in the hand-holding stage. So I did the opposite of what is often recommended around here: I quit my job and enrolled in a 2 year Computer Programming course at a college. I'll be finishing up this spring. The enforced, formal structure and discipline has been a boon.
I feel great about having done it. I still feel pretty green, but I'm probably somewhere in the middle of the "desert" now. I credit school with having got me that far.
In my experience, this graph looks similar if you get hired at the first peak, but the desert of despair doesn't dip as low as long as you have some form of mentor or reviewer for your code. You can, of course, get hired to a bad job and the desert will dip further down (and your risk of leaving the industry increases).
The hard thing about learning to program is that to create anything even vaguely useful you have to learn a million things in parallel.
Say you wanted to build the simplest of Rails apps - you're simultaneously learning not only what the terminal and a text editor is, but how unix commands work, what an MVC framework is, probably a little of HTML and CSS, database migrations (maybe some SQL), asset management/pipeline, some random Rails-specific syntax, probably git, and if the creator of the tutorial is feeling ambitious he/she may throw in some TDD and testing frameworks. And that doesn't even begin to go into Ruby -- the entire programming aspect of programming.
So you're thrown out into the middle of the ocean, and blindly writing code you don't understand (because there's no way any tutorial could fully explain everything you're learning without being 2,000 pages long). You follow the tutorial, you get your little app running, then you realize, "I have no fucking idea what I just did." There's no way on earth you could do it again.
The other approach is to bring you from the bottom up, starting with language/syntax Codecademy style. So you spend a month learning how to almost be able to write a for loop in JavaScript, and then you realize you have no idea why you would ever need to know what a for loop is, and even less of an idea of why it's useful.
I got stuck bouncing back and forth between the two for years (literally), wondering how the other programmers were possibly smart enough that they could grasp meaning from random blobs of tutorial code, or how they possibly had the patience to grind through enough JavaScript tutorials enough that they could actually create something. I finally decided to throw away the crutches and venture out on my own. I think that was the single biggest step in becoming a (decent) programmer.
The timid, "I don't know how to program" side of me said, "Wait, I have no idea how to do this yet. You need to read up on it." But I finally bit the bullet and said, "You know what, I'm building this app right now. No, I don't know how to do a lot of it, yes, my friends that are a lot smarter would probably mock my code if they saw it, but I don't care. I'm building this." I don't think you can ever truly learn to program without saying, "I don't care, I'm building this." It took a long time and more Stack Overflow than anyone should ever care to read, but things finally started clicking. I built a few apps (Rails and iOS), went back to the tutorials, and said, "Are you kidding me? That's what they were trying to teach me?"
There was no way I would have remembered that crap if there was someone guiding me through or holding my hand. Sometimes you just have to start, having no idea what you're doing, and figure it out as you go. That's a foreign concept to people who aren't used to creating things, but I'm convinced it's the only way to truly learn.
>I don't think you can ever truly learn to program without saying, "I don't care, I'm building this."
This is a great point because it's easy to get stuck in analysis paralysis. There's always a tension between needing to stretch out and build something just beyond your capabilities and then having to backfill some of the fundamental knowledge you missed along the way so next time you can reach further.
My first real, non-toy app was an Android card game. I knew the basics of Java going into it, but nothing else. Following tutorials got me to where I had an app that I could install and run on my device.
At that point, it was up to me to figure out what to do. I started with a single screen that showed some text and added a few more screens that had the same text. Then I added a button that triggered a change of that text. Then a button that displayed an image. And so on until I had a real card game that could even identify whether there were any legal moves available and if the player was stuck.
Every step along the way was not easy and I got derailed a couple times, nearly giving up. The hardest single feature to implement was dragging and dropping a card. It took a lot of cribbed code from a few useful blog posts, but the feeling when I actually got it working was indescribable. It was a Saturday morning and I was running around my house, dragging and dropping cards on my tablet like I was 8 years old and it was the greatest Christmas gift ever. That was the moment when I realized I could actually finish this if I was willing to put in the effort. The rest of that weekend was spent in blissful coding and my commitment to becoming a developer has never wavered since.
Now in my job, which I got an interview for because of the card game, I have witnessed other people with less self-guided (contrasted with CS class projects) experience than I started out with be unable to persist long enough or self-teach hard enough to solve a problem by themselves without asking for help to get over minor bumps. I won't ask for help from a more senior dev unless I have exhausted my abilities to understand the problem space and can enumerate the things I have tried. I refuse to be the person who simply "doesn't know how".
> So you spend a month learning how to almost be able to write a for loop in JavaScript, and then you realize you have no idea why you would ever need to know what a for loop is, and even less of an idea of why it's useful.
This is a carbon copy of my life as a programmer right now.
I've made the decision to just fucking do it about 50 times, but each time I get barely started and get so frustrated with myself for not understanding and not knowing what to look for that I give up. I know that's another point where I just have to sit, searching, until I find the answer, but it seems that from my profound lack of understanding of the basics of the language (JavaScript; despite doing the Codecademy course, and the CodeSchool Node.js and Express.js courses) that I will have to do that for every minute step that I take in the program. It just seems so overwhelming that I become paralyzed in my desire to push on, but feeling that I know I won't make any progress.
And then they give up and do something else, with lower self esteem this time.
Seriously. "Just code" is the worst advice that everyone gives. It's trite. You'd be better off saying nothing at all. Do you think you can sit someone down with a C compiler and come back five years later to find they've written the Linux kernel?
Don't say "just code". It's not helpful. It's disparaging. You don't tell a child "just walk". You learn to code, you're not born with it.
Of course one is not "born knowing how to code". Saying "Just code" does not mean "sit down by yourself and try to figure out the C compiler." It means, for most of the people I've met/worked with "Stop agonizing over what course to take, what book to read, what you should build first - just build." Implicit in that is that the person can ask me for help outside of some master/grasshopper relationship.. no I'm a coder and so are you. Just show me what you're working on and ask your buddy here for a hand if you need one.
I know a lot of people say something like "Just open up a git repo and start making pull requests on the back end of your gulp process after you wget the source from such-and-such repo"... Yeah, that annoys me too. I've had a lot of success just sitting people down with Chrome and have them hit Ctrl+Shift+I and show them a couple fun things with DOM maninpulation, etc. The point is, the worst thing to do that I think claims the most victims on the path to learning to code (I know I struggled with it for years) is just constantly deliberating about what is the "best way to learn" when you should just be playing, having fun and failing. That's the hump I try to nudge people over - the idea that you need to have permission or a "master" to become a developer.
I think we're way past the point where mindlessly playing around and idle curiosity can reliably teach someone how to program. That might get them interested in programming, but it's one thing to print something to a terminal or change the text on an exiting page; it's quite something else to get a GUI app going or deploy Rails to a server. And GUI/web is pretty bare-minimum when it comes to keeping people interested in programming. Not a whole lot of people want to write console applications anymore.
Here's the sticking points where beginners need your help, and might not even have enough information to actually ask what they're looking for:
What framework do I use? I see people talking about AngularJS, so I'm going to pick that one. Oh wow, it's harder than I thought bzzzt you just lost a future programmer.
How do I deploy? DigitalOcean costs money, bzzzt there goes another. I paid for DigitalOcean, but I ran into troubles installing pip, bzzt there goes another.
How do I make a GUI? Tkinter, Wx, Qt, GTK, WPF, bzzzt there goes another.
And the worst of them all... "What language should I learn?"
Yeah, a lot of programmers might not want to hear this. But there are a lot of languages. You can't blame a beginner for not being able to decide. And to be honest, there isn't really a good choice here, which is why programmers get into fights about languages and when that happens, bzzzt there goes another. Javascript sucks, but people claim its essential. Beginners get turned off by hearing "Javascript sucks but you have to learn it". The better option is to just not learn programming. Or bringing political wars into it. "Don't learn C# because M$". Beginners don't care about your politics, they want to learn. Eventually people settle on Python, so the beginner starts learning Python, then asks "what GUI framework" or "how do I deploy Django" and we start back at the top of this list.
So, in the midst of all of this confusion happening for a beginner, they're (understandably) lost and ask for a lighthouse to guide them on a path, any path, as long as they don't have to make the choices themselves. So they ask the question "how do I learn to program". And the response they get? "You don't learn how to program, you just start programming."
It's funny you use walking as an example. I never told my son to "just walk" but I may as well have. No one taught him, he never asked how. It just never occurred to him that there was any option but to keep trying until it works. As far as I know everyone learns to walk this way.
In my generation and before it, most of us learned coding the same way. (And self esteem for that matter.) Even if you do have the luxury of teachers and classes and handholding and cheerleading, the real learning is not going to happen until you sit down with a code editor and actually try to make something real.
And if the first difficulty you hit causes you to turn around and run then that's another win. It's a very fast way for you to learn this not a career or hobby for you, because dealing with those decisions and difficulties is a major part of the job. 30 years in I'm still dealing with stuff like that every day.
You taught your son to walk by walking. He learned to walk because everyone around him was walking. That's undeniably the best way to learn: being in an immersive environment. That's akin to going to hacker school.
What I'm saying is 'just write something' doesn't help people who would ask the question 'how do I learn programming', It helps the people who ask 'how do I get better at programming'. You get better at walking by walking more. You get better at coding by coding more. You start walking by learning it from someone else, or by using something to pull yourself up (like a chair or a table leg). You learn programming by asking how and following their advice.
Your son didn't ask how to walk because he didn't know the question. Beginners don't ask how to deploy because they don't know what deploy means. "Just code" doesn't answer the problem of "how do I write a GUI app". It makes it seem like it's so easy that you shouldn't have to ask. And since you don't know the answer and no one will tell you, programming must be hard, or you must be stupid. That's what a teacher or a mentor offers. Advice. Not glib remarks.
"You can make that application work but what's happening beneath the surface? Your code is duct tape and string and, worst of all, you don’t even know which parts are terrible and which are actually just fine."
I commonly get to this point after just wanting to proof out a concept and get something working. And then I realize I need to go back and do the unglamorous work of getting it right. But I learn the most then, and helps enormously on future projects.
If you don't have the motivation you'll never be able to do it. If you can't sit in front of a computer for 8 hours a day reading documentation and hunting for syntax errors you're not going to be able to do it. If re-writing algorithms doesn't give you an intrinsic satisfaction, you're not going to be able to do it. No amount of everybody can code tutorials is going to help. They should all be, "how to find the motivation to keep coding" tutorials.
Motivation can work for a while, but ultimately how I see it comes down to discipline.
Motivation will fail you when you are left with those last 10% of a project that feel like the first 90%, but now with uninteresting tasks like tweaking the hell out of a UI, fixing all those bugs resulting from code optimization in obscure cases, implementing database integrations to assure backwards compatibility with earlier versions or some such shit that is impossibly uninteresting but required to finish the project.
Then in play comes discipline, and that is something you have to learn systematically, and when you don't feel motivated at all to continue through and just wish to quit it all.
But you are correct, you have to get satisfaction from the process. Maybe the motivation is to see the end result. But still, there is that phase where all hope seems to be lost, inspiration and motivation are nowhere to seen and all that remains is just grind and decide to follow through.
This may be thinking back on things with rose tinted glasses, but I learned to code in qbasic when I was 12 or so at a Boys and Girls club after school and fell in love. It was entirely effortless and fun to me. I think the difference is at that point I wasn't trying to program to enter some lucrative career and be a startup guy (where are these "coders" going to be once the market dies down and a new industry is hot? probably trying to do that). For me it was something I loved immediately, and while obviously there are really hard problems, the coding part was effortless
I first learned on a variant of BASIC myself when I was in elementary school, and it was effortless then -- but that's a profoundly different thing from learning the professional tools/design patterns/development styles to get hired in a specific domain. As somebody who picked it up again after a long break, the whole point was not 'getting hired in some hot new lucrative industry,' but 'god, please let somebody hire me to do this thing that is so much more mentally satisfying than the last few things I've done for a living.'
From that perspective, I absolutely understand the urgency here, and appreciate how this article talks about how the moment when the tutorials break off is when the real learning begins.
I may have been to harsh in my assessment. But still, how many of these people are sitting down and working on some puzzle/problem/project they find interesting vs saying I know I need rails, and angular to make web apps and then just going through tutorial after tutorial. How many of them are actually interested in it in and of itself. I learned how to program very far away from the concept of writing an app that I could deploy to heroku.
At the time "design patterns" were somewhere in the distant future, development style was something you had rather than something you learned, and the list of professional tools was really short. I'm sure this is part of what made it incredibly fun.
I think today's students would also have a lot more fun if they ignored all the opinionated garbage about which flavor-of-the-month checkboxes they need on their resume. Figure out what you like and get really good at it. Many top employers are looking for passion, pragmatism, and adaptability rather than specific tools and libraries.
I'd always thought that programming might be interesting. Picked up BASIC for dummies and basically built my career from that moment. It's crazy how stuff like that can happen.
It's only hard once you realize the commitment required, partly due to the pace of innovation, the depth and breadth of information available and the fact you're competing with the entire world, not just people in your city/state, and there's nobody regulating the influx of competition. A significant chunk of your life will be spent looking at a screen and there's a chance you could end up with a crippling case of carpal tunnel. It's a sacrifice and most people won't make it. In the same amount of time you RTFM, you could have learned to be a brain surgeon, a rocket scientist and a lawyer. And once you have it all figured out, half of everything you learned gets flushed down the toilet because there's some new platform. If you think it's hard and you're not enjoying yourself, don't even bother, there's easier ways to make money.
C'mon, all of those things you listed (brain surgeon, rocket scientist, lawyer) are WAY harder and more expensive/time-intensive to get into than software engineering.
If you feel like your knowledge is getting flushed away with a new platform, then you've been learning the wrong things.
Those people are smart but there's a textbook to follow, a clear path to graduation. I didn't mean to start a war of the professions, I'm sure there's already a Hacker News thread for that.
My point was, you can teach yourself a half-dozen programming languages, operating systems, databases... (which is inevitable for most developers) or you could have spent that time collecting diplomas in academia. This is not really a new concept, I read it somewhere else. Any profession that demands a lot of ongoing learning, I think people will quit because the effort may not seem worth it.
I agree you have to learn the "right" things but that takes experience and strategy. That's an interesting aspect of all of this. When everybody says "iPhone" you might bet on Android. Everyone says "Google Glass" and you might bet on Unity. If you have a crystal ball, maybe you're the next Warren Buffett ;-)
Most of those other professions require ongoing learning, too. Doctors and lawyers have continuing education requirements for licensing, scientists have to constantly be reading journal articles, attending conferences and keeping up with the latest developments in their field.
I understand the point you're highlighting, but there are very few interesting jobs where you get to say "Ok, now I'm done learning and I know everything I'll ever need to know to do this job perfectly."
Really? How is being a brain surgeon more difficult than being a computer surgeon ? Understanding how a CPU completely works, on the assembler and even on hardware level is FRIGGING HARD. Computers are very complex and huge beasts of logic to really understand, and the best programmers have to understand a huge amount of technical skills and systems in order to get the wanted results.
I have no idea how much stuff a brain surgeon has to learn, but having the idea that there are people who are brain surgeons, it cannot be so much harder than being a really competent programmer.
Think John Carmack for example. That guy is a friggin beast in learning new systems and producing working code. That is really, really hard to do. It requires immensive amount of thinking and applying, and sitting in front of computers while balancing your body and health at the same time so you dont kill yourself in the process or go mentally insane and just give up.
Oh yeah, but Carmack is a rocket scientist too .. so, maybe not the best example.
But putting those jobs above really competent programmers is just stupid, if you want to be best in what you do, in any life path you are taking, it will take all of your effort, and then some more. So why compare. It's all about doing what you love.
Are there really no longer any open and relevant research issues around this topic? Is humanity's understanding of CPUs, how they work, how they should work, is it all wrapped up and complete?
Not really my field, so I truly don't know. But I'd be a little suspicious of someone who claims there's nothing new to learn here.
I don't think he means innovation which seems to be what you are implying. If you take a current working computer system, there are no "mysteries" in the existing hardware where the hardware designer just threw up their hands and decided to hope it would work. Sure when you throw in environmental factors there is certainly unpredictability in terms of hardware failure, but actually understanding what the system is doing? We know what it does. With something like the human body, it doesn't seem that we can be nearly as confident.
Sure, but I think that definition makes the difference in complexity a bit of a contrivance. You're deliberately excluding the things that make CPUs complicated and interesting, and then concluding that they aren't as complicated and interesting as something else.
The other thing is that while the brain is highly complex, that doesn't mean that people who work in it have managed to master something more complex than CPUs (or house wiring, for that matter). They may simply not really understand what they're doing to the same extent.
To me, the thesis in the original post is this "[if] there are people who are brain surgeons, it cannot be so much harder than being a really competent programmer."
I tend to agree, because I think that some types of programming push people's mental ability and sheer stubbornness past the point of human ability. In short, it will take all you have, and there will still be things you just can't understand or do.
If you define the task as "the things that we understand and can do", then by definition is is not equal in complexity to the brain, but like I said, I think the statement is a contrivance.
This, exactly. CPUs and their insides, the hardware, understanding that, and then understanding the whole software stack that runs on that hardware, I mean _really_ understanding, by definition that if one bit was off in the RAM you could completely trace it all the way from the application level to the hardware level.
Almost nobody can do that. The hardware alone is so complex, these modern CPUs have many BILLIONS of transistors packed so tight that it is impossible for us to even fix them. So we just have a vague understanding of what is going on when we program, but really, we have no clear picture. But the best programmers out there, they have this map of the computer in their heads and the systems, and the better you are, the better the map in your head is.
Think NASA level programmers. They truly have to know how the system works, and yet, they cannot most probably understand the whole stack even, down to the transistor level operation, and then below that even in some really extreme cases where the systems overheat and there is magnetic bit flipping happening and other obscure stuff.
Immense amounts of work equals to amount of commitment required, which equals hard. To be a really competent programmer that knows how to truly take advantage of the machine is really rare, and even then it is down to some very specific domain, like graphics programming, systems programming and so on. So it is very hard to achieve, and very rare.
Being a computer surgeon rarely involves much physical dexterity and typically lacks the urgency/pressure that being a brain surgeon regularly entails.
Comparing "computer surgeon" to brain surgeon is like comparing sudoku to racquetball.
I agree with you, and I think that programmers dismiss the complexity and difficulty of what they deal with far too quickly. I'm not saying that all programming is hard, but I do think that hard problems in software contain challenges that will take all the raw intelligence and hard work a person can have and then some.
There are plenty of other fields that do as well, but software absolutely belongs in the mix.
Of course, there's a bit of a difference, in that you can call yourself a programmer even if you can't program. Whereas you can't call yourself a lawyer until you've passed the bar, which almost always involves attending 3 years of law school. So it's not really an apples to apples comparison. There is really no barrier to entry to programming that sets a minimum bar. So if you're comparing something with a minimum education standard with something with no minimum standard… well then yeah.
But personally, I don't think the required training to become a lawyer is anywhere close to as rigorous as what it takes to become a brain surgeon or rocket scientist, and if you look at typical pre-law majors, they aren't as difficult or rigorous as common undergrad degrees for software developers (CS, math, engineering, physical sciences). Let's face it, people don't drop out of poly sci because physics would be an easier major with more time to party.
It was never hard for me. I started by typing BASIC game listings from magazines into a ZX Spectrum. Then learnt LOGO, BASIC and Pascal at school. And then taught myself QuickBasic in the army. Started a CS degree but dropped out after learning how depressing Z-routines in COBOL were. Got a job. Taught myself Assembly. Got a job writing tariffing engines for a cell phone billing system, learnt C, Informix and Visual Basic. Then Java, .Net, VB.Net and C#.
"... was convinced that the seemingly normal programmers I ran into were actually sociopaths who had experienced, then repressed, the trauma of learning to code."
It's true. The saddest part is that we forget who we were before we crossed over, and lose the ability to sympathise with people who haven't been through it.
I sympathize if I detect that they're genuine in their desire to learn and improve themselves. As for the others, the ones that just want to "get by", they don't get much of my sympathy. And that is after I try my best to inspire in them a sense of self-improvement when it comes to programming. Alas, not everyone has that outlook on programming, but rather just see it as a dumb-tool to muddle over some arbitrary problem someone dreamt up in some ivory room, somewhere.
What I wrote reads that way and I can see my error. There are lots of pretenders and I do not apologise for them. I intended to write that our brains get rewired to make things that were once hard easy, that we do not know what to explain.
My strategy for people who ask me to tutor them is this: work through the first five chapters of /learn python the hard way/ by yourself, and I will mentor you the rest. Those chapters are so easy, it is just a test of motivation. I have only had one starter. Also, she finished.
In my experience, one thing that can make the path feel more progressive and monotonic is having a set of problems that need to be solved, with a wide range of difficulties. This provides consistent short-term gratification while also providing long-term gratification and utility.
For me, as an earth scientist, there have always been small calculations or simulations that are quite valuable, even though they are not overly difficult or complex. This provided the motivation to learn basic Matlab. As my skills and ambition grew, and I learned new languages and techniques, the class of problems that I wanted to solve grew in scope and complexity. I also learned to recognize new problems and their probable solutions as my tools developed. Programming changed the way I look at the earth, and at statistics, personal finance and a range of other things in which quantification is enlightening.
In contrast, I have had a hard time picking up new languages or programming paradigms when I don't have an immediate need. I've spent time mucking around on various 'learn to code' websites, and read and sometimes completed tutorials on databases or Haskell or whatever, but it feels very different: meandering, non-essential, hard to gauge in scope (how much do I need to know to be useful, how deep is the water really), hard to link up to the rest of my life. Programming for me is a powerful and enjoyable means to many ends, but not something that I am inclined to do for its own sake.
I think if I had said, "I want to learn to program so I can build web apps" without actually having a simple and truly useful web app that needed to be built, I would very quickly move on. If I had said, "I want to learn to program so I can find a new job that pays more money" I would stick with it for a bit longer but it would be incredibly frustrating, because it doesn't seem like there is a very straight path without formal guidance (such as going to school of some sort).
I suspect many people feel the same, but I don't necessarily know how smaller, less formal education systems can work on that. Students always need some amount of self-motivation, and useful results are a long ways off in some areas.
When I was in college, one CS professor explained the difficulty of coding to me in terms of discreteness vs continuity. In the real world, things are continuous. If you accidentally build your structure with 9 supports instead of 10, then you only lose 10% of the strength of the structure, more or less. The strength varies continuously with the amount of support. But if you're writing a 10-line program and you forget one of the lines (or even one character), the program isn't 10% wrong, it's 100% wrong. (For example, instead of compiling and running correctly, it doesn't compile at all. Completely different results.)
Of course this logic doesn't hold up all the time. Sometimes you can remove a critical support and collapse a structure, and sometimes removing a line of code has little to no effect, but the point is that in programming, a small change can have an unboundedly large effect, which is the definition of discontinuity.
"In mathematics, a continuous function is, roughly speaking, a function for which small changes in the input result in small changes in the output." [1]
I could clarify and say that the change doesn't have to be unboundedly large in absolute terms, but rather relative to the change in input. (i.e. a jump discontinuity from 0 to 1 is not absolutely unbounded, but it is relative to an arbitrarily small change across the jump.)
Unless you're doing Rails, in which case it'll be read as a magic method and guess what you meant :-P
Seriously, that was a major sticking point for me having programmed for a long time: going from "if you have not declared that identifier, game over" to "magic happens".
That is absolutely something that irritates me. I've just inherited a large RoR application, and the amount of "magic" and things by convention is driving me crazy. There should be answers to questions like "why is this the way it is?!"
On a side note, if anyone has some great resources for RoR, I'd love to have them linked. I suspect my inexperience is the source of my problems, and I'm welcome to any assistance any one would like to give.
Convention over configuration is awesome, if you know the conventions. If you don't, it's all magic. At least with configurations, you can read them and get some pointers.
Which bits did you find were magic? The bits of convention I can think of you'd have to know about are:
DB naming conventions - these are used so that it can do joins etc easily behind the scenes, they're pretty simple so not a huge problem I find.
Rendering at the end of controller actions - it'll render the template with the same path as your route - again relatively straightforward.
Class loading - lots of things are loaded at startup time, so that you don't have to include files - I have mixed feelings about this, it feels easy and simple at first, but could leave you unsure where code comes from or which methods you can use in which files (e.g. view helpers). Definitely more magic.
One other area which does lead to real problems is that rails sites often use a lot of libraries in the form of gems - this leads to unknown, sometimes poorly maintained or inappropriate code being pulled in at runtime, and makes it far harder to reason about things like say authentication if using a gem. This is my biggest complaint with rails - lack of transparency of code paths when using gems like devise, paperclip etc but it is unfortunately quite common in web frameworks
They actually got rid of quite a few bits of method_missing madness I think recently so that magic is gone at least (all those magic find_by_ methods are deprecated or removed, not sure which as I never used them). I haven't found the conventions get in the way much as it's something you learn once and can apply anywhere, but completely understand why someone might object to some of the magic setup for helpers/rendering.
The routing system and associated view helpers can really get confusing.
For example:
link_to @story.title, @story
You have to know that rails has some automatic routing based on the class of an object. If @story is a Story class, rails basically does this underneath:
There's implicit conversion of class names going on under the hood in a few places. It's all documented but it's not easy to find the documentation when you don't know what you are looking for.
The thing that really screws up people starting with rails is not understanding the various layers (html, views, controllers, models, http, etc.) and how rails puts those together. If you don't know how to do web programming with basic html and php, rails will eat you alive with it's seemingly magical behaviors.
I have to agree - The path helpers are very opaque. It would probably do Rails well to generate a app/helpers/path_helper.rb file with the actual implementations in them.
Sure. But that still doesn't tell me exactly which arguments they take. Or give me an opportunity to debug the code when it doesn't do as I expect. I realise that it just-works (tm). It's when it doesn't, it gets problematic.
When learning Rails, I found the DB naming conventions confusing enough that I wrote a blog post summarizing how everything is supposed to be named when I figured it out, since nobody else seems to have:
Like a lot of the Rails stuff, it feels like amazing cool magic when things just work. But then when they don't work and do something weird instead of what you expected, it feels like it takes forever to figure out why, what was named wrong, and what it's supposed to be named.
Aside from the things others have mentioned, which are all really good, there are some really good books on the subject.
Jose Valim's Crafting Rails Applications[1] is a wonderful resource, since it deliberately sets out to peel back the layers of magic. A lot of the techniques are ones I probably would not use in practice (storing views in the database and rendering them!), but they serve to elucidate the operation of the entire view stack. Really good stuff.
Two other good books are Rails Antipatterns[2] and Objects on Rails[3]. Neither of them has been updated in a long time, but the general principles will still hold. The former is more practical, the latter more theoretical; precscriptive and fanciful food for thought, respectively. Both solid.
If you're not an experienced Rubyist, I'd recommend reading David Black's book The Well-Grounded Rubyist. Unlike many introductory books on programming languages that focus on making you productive in that language quickly, it focuses on building a deep understanding of the language. When I later read the book Metaprogramming Ruby, which uses parts of Rails for many of its examples, I already knew many of the techniques thanks to David.
I've been teaching myself off of online resources and 'magic' was what I hated most along the way. I can't debug magic. I've ended up digging so deep to understand things that I'm covering assembly now. It's painful, but going so far has made everything else make a lot more sense. Data structures are easier to conceptualize and will be easier to work with (for example).
But most people I know don't get this far when they self teach or do a bootcamp. They just know that, given a framework, they can build things but not how anything was really built. Sure it's effective to push out a product, but it makes diving into real programming pretty difficult. That's just my perception though.
We should start at the lower levels. It is all easy to understand if you build up from first principals: Binary, logic gates, cpus and assembly, then it splits with compilers on one branch and LISP and Smalltalk on two others and a bunch of brush and shrubs and time to retire that metaphor.
Unlike climbing Everest or understanding how the human body works the challenges in learning to program are entirely man-made! (Except for recursion, of course.)
I'm in a similar boat. Started with the training wheels of Codeacademy and such after having a basic working knowledge of HTML/CSS/JS and wanting to build database driven projects and grow my skillset.
Picked up RoR and was quickly overwhelmed with a million unfamiliar concepts as pointed out in the excellent (and very similar) article "This is Why Learning Rails is Hard."[1]. That knowledge tree they show is one I didn't formally stumble upon until later, but throughout my progress I realized "hey, this concept is really part of the much broader topic of X." Then I'd go down a rabbit hole on X.
Before I found that tree though, I had already given up on Mike Hartl's tutorial once, and decided I really needed to have a functional grasp of Ruby and core programming concepts. From there I realized "Ruby/RoR on Windows is not ideal." Then went down the whole devops path and learned about things like Vagrant/Chef/Virtualbox, etc.
I also started picking up books on much deeper computing concepts to understand the lower level mechanics of the magic. Like you I went down to first principles and even a bit of assembly. I couldn't write any to save my life and knowledge is still fuzzy, but I now grasp how the concept of data structures came to be, and more importantly WHY.
I recently tackled Mike Hartl's Rails Tutorial again. His updated version is a great improvement, and this time I actually understand the concepts he goes through. When a new one is introduced, I have enough of the underlying knowledge to at least have a sense of what/why something is, or what I need to Google to learn more.
I wish more classes online provided "deep dive" resources/links on things. Like, if CodeAcademy has an exercise on Ruby covering types, an eager student might really benefit from a deep dive sidetracking into dynamic vs. statically typed languages, and a high-level of what they should know.
My biggest gripe with the tutorials that are out there these days is that they cater to either absolute beginners or competent users. Wish they did a better job of trying to bridge the gap from absolute beginner to intermediate.
Another great example of that is the concept of design patterns. I haven't found many great beginner/intermediate resources on this, but as I've started learning more, I found myself saying "hmm, seems like lots of people do this a similar way--I wonder why." Turns out some approaches to problems are largely solved issues for a majority of use cases, hence: design patterns. This got me down the whole path of software architecture and starting to grok some of the higher-level abstractions and way of thinking in the abstract which was tremendously helpful compared to just being given specific examples with no broader context.
You need to keep in mind that "magic" is only sufficiently "advanced" (or rather obfuscated) technology, but omeone somewhere said something along the line of "Things that work as if by magic also break as if by magic" .. I've been looking for the reference ever since.
Just wondering whether a distinction should be made between learning a framework (RoR, jQuery) and a language (JavaScript, Ruby). Frameworks do magic, languages generally don't.
Wahoowa! This also explains the popularity of interactive platforms like Codecademy/CodeSchool/Treehouse, etc. Ton of handholding and pre-filled syntax. We describe them to our students as "coding on training wheels."
Cathy, a new frontend student, experienced similar struggles when starting her first real project - a simple HTML/CSS resume. She spent countless hours fixing minor typos and almost quit. It wasn't until she was reassured that this was _normal_ and "real" programming was much different from codecademy did she feel like she was truly learning. She wrote about her first month (with similar highs and lows as OP's visual) in this post: http://blog.thinkful.com/post/98829096308/my-first-month-cod....
side note: Erik (OP) is an incredible guy, we had the pleasure to share our experiences in Edtech and it's obvious that he truly cares about student outcomes.
> She spent countless hours fixing minor typos and almost quit.
it's interesting anecdote!
When i was at uni, i noticed that a large number of "beginners" tend to fall into this category too - frustrated at minor typos/language idiosyncrasies. Those who had the mental strength to endure it end up passing the class, while those that just gave up will almost inevitably change their major (and thus, stop programming i guess?).
But i think this is a result of poor educational methods, not because of an inherent property in programming.
> But if you're writing a 10-line program and you forget one of the lines (or even one character), the program isn't 10% wrong, it's 100% wrong. (For example, instead of compiling and running correctly, it doesn't compile at all. Completely different results.)
This is where the beauty/simplicity of some programming languages, namely, intepreted languages (e.g., Python), comes in: if a bad line of code never gets executed, then the program itself will run fine. In other words, if the line is never called in the program, then you'll not know that the functionality that that line presented was bad. In this case, the analogy breaks down a bit - and also shows why certain languages are easier to learn than others (e.g., Python vs. C++).
If you rely on your compiler to tell you that your code is correct, there are whole classes of bugs that are waiting to surprise you in production.
I think that many years of developing large applications in Perl were really good for me. Perl is compiled when you run it, so you get the basic-syntax check that you get with other languages. But it's also very lenient, so you learn through experience to get your logic right, test return values, and do all of the things that help make sure that a program which executes is executing correctly.
There is a difference from RELY on compile to catch 100% of bugs, vs having an awesome type system that can take whole CLASSES of bugs and make them impossible to get past a compile.
Is a statically typed language more likely than a dynamic language to work correctly in production, if both have 0 tests? Yes.
I agree with you on all points, but the parent sounded like he was relying on the compile-time checks to determine correctness. I was making the point that that is a bad idea.
> Is a statically typed language more likely than a dynamic language to work correctly in production, if both have 0 tests? Yes.
I'm not sure I agree. "Work correctly" does not just mean "compile correctly". I would want to see a lot of evidence to back up any assertion that programs written in statically typed languages are less likely to contain logic errors that compile and run just fine but don't do what the programmer (or his client) actually wanted.
I agree that neither is ideal and that adding testing can improve any code.
> I would want to see a lot of evidence to back up any assertion that programs written in statically typed languages are less likely to contain logic errors that compile and run just fine but don't do what the programmer (or his client) actually wanted.
As certain assertions related to logic can be encoded into static types (especially in a language with a type system more like Haskell's than, say, Go's), while static typing can't eliminate all logic errors, it can reduce the probability of logic errors escaping detection in the absence of testing, since compiling a statically typed program is, in effect, a form of testing (limited to those assertions about behavior which can be encoded into the type system.)
> compiling a statically typed program is, in effect, a form of testing (limited to those assertions about behavior which can be encoded into the type system.)
Fair point. (Especially if, as you say, you are using a language with a type system like Haskell's, which to me is more like a program analysis engine than just a type system.)
This is a risk that you should be aware of when using languages like this and thus use them appropriately. To continue with the building analogy, you don't want it to take an actual fire to learn that all your fire exits are dead-ends.
>This is where the beauty/simplicity of some programming languages, namely, intepreted languages (e.g., Python), comes in: if a bad line of code never gets executed, then the program itself will run fine.
That's not beautiful; that's horrendous. A program that might contain syntactic (!) errors has no claim to being a sublime mathematical construct.
I'd say it's "beautifully simple" when I can tell you with 100% confidence that my program will never, ever, ever experience errors of a certain type. Even better if I can tell you with 100% confidence that my program contains no errors at all (which is possible with proof-based languages).
Saying a Python program is beautiful because it can have hidden failure conditions is like saying that a poorly maintained gun is beautiful because it can fire when rusty (but watch out for explosions!).
I wish, when learning to program, that I'd been taught to write universally correct code instead of "mostly correct" code.
> This is where the beauty/simplicity of some programming languages, namely, intepreted languages (e.g., Python), comes in: if a bad line of code never gets executed, then the program itself will run fine. In other words, if the line is never called in the program, then you'll not know that the functionality that that line presented was bad. In this case, the analogy breaks down a bit - and also shows why certain languages are easier to learn than others (e.g., Python vs. C++).
Actually, that's one of the pitfalls of interpreted languages.
You want to Crash Early & Crash Often [1] or you'll move along, merrily ignorant of a serious problem just because it doesn't get executed.
I try to solve this shortcoming of languages like Python with proper unit testing. It gives me the confidence that there's a decent coverage of the different code paths so that I won't learn about the problem in production.
Unfortunately this is a dark hole of horrible bugs just waiting to happen not to mention the fact that interpreted languages are very liberal with silent type conversion. It is a nightmare to deal with in a large system written by careless programmers.
> This is where the beauty/simplicity of some programming languages
Simplicity? Yes, probably (at least as long as I am writing the code and not debugging it). But definitely not beauty. I find this particular behaviour the ugliest part of interpreted languages. I may make a small typo, incorrectly capitalize variable name or forget a quote and nothing will tell me that my code is wrong or where exactly it is wrong - it will silently skip the error and happily show me wrong results.
In a general sense, it can be more difficult to reason about what effect adding or removing something will have because the skill is still being developed.
Yes, but that's true of any new skill that one might try to learn. I'm talking about specifically what makes programming harder than other things to learn. When things are continuous, you can at least experiment by making small changes and be confident that those changes will only have small effects.
With respect to your CS prof at one of my favorite places (Go Cavaliers!), this is not an issue of discrete vs. continuous. If your structure can have either 9 or 10, but not 9.001, supports, it is discrete, not continuous, regardless of failure mode. And remove one of the 3 legs of your stool, and you probably wouldn't have 2/3rds of its support remaining, but whether you did or didn't would be an issue of proportionality, not continuity.
There are a lot of jumbled concepts here, most of which don't matter anyway, because what you are talking about is the phenomenon of graceful degradation. In the physical world, both natural and man-made, almost nothing at the macro scale is ever perfect, so the best designs tend to be those that remain good enough under the widest range of circumstances vs. a more common software goal of being perfect under perfectly controlled circumstances.
As software gradually moves out from the wall garden of a single mainframe to fill the world with interacting systems spanning diverse machines, sensors, communications channels, data types, etc., design for graceful degradation becomes more and more of a focus for professional software architects.
Coding in the gracefully degrading way is much harder than coding in the "if even one of your ten lines is wrong, you crash" tradition. The fact that even the latter is so hard for us humans means we will need more and more help from machines that learn what to do without being explicitly told by us.
I agree that "discrete vs continuous" is not the perfect way of expressing the difference; it's just an analogy. (But the structural support example is continuous. You could have 9.5 supports by adding a 10th support with half the strength, etc. "Amount of support" is the continuous measure.)
But it's not just an issue of graceful degradation. The fact that tiny changes in a program can have very large effects is a feature, not a bug. We grade programming languages on their ability to concisely express complex operations, and that conciseness necessarily means that very different operations are going to have similar expressions (e.g. subsetting rows vs columns of a matrix typically differ only by a small transposition of characters, but the effect is completely different).
You can write software that degrades gracefully, but one syntax error (or other "off-by-one-character" problem) is still going to kill the program. You can talk about running your program on a large set of redundant servers with no single point of failure, so that you can update them one-by-one with no downtime, and that makes you robust against even syntax errors. But that's not helping you teach novices how to write code.
there are continuous programming languages out there - DNA is one such one i guess. But i don't think the discrete vs continuous nature of a programming language is what makes it difficult. It's more that a person's mind may not conceptualize tasks algorithmically, and to switch to this frame of mind is difficult for someone who isn't already in this frame of mind.
That's a good point. DNA as a programming language has to be at least somewhat continuous, or else evolution has nothing to optimize because every change has a random effect.
DNA is a lot less discrete that you might think. There's epigenetic factors and population proportions, for example.
But even considering DNA as just a 4-letter language with discrete characters, my point is that many, even most, small sequence changes to a genome (e.g. single-nucleotide variants) have small effects or no effect at all, which gives evolution a smooth enough gradient to optimize things over time. That's what I mean by continuous in this context. The opposite would be, for example, a hash function, where any change, no matter how small, completely changes the output. Hence you couldn't "evolve" a string with a hash of all 7s by selecting for "larger proportion of 7s in the hash function", because hash functions are completely discontinuous by design. But you can evolve a bacterium that includes more of a given amino acid in its proteins by selecting for "larger proportion of that amino acid in protein extract".
Many of the coders I know (which is mostly folk in their 40s) never learned from scratch. More often, we started in support roles, and slowly worked into the code. First, learning to read it to help troubleshoot issue, then making basic changes, and slowly picking up more and more of a specific codebase. Once the basics were understood, we'd start making basic apps on our own, often while still supporting more complex apps. After a year or two, we'd be competent enough to do things from scratch, and then we'd move into a full-time coding role.
I know that few people learn like this these days. I've heard extreme negative criticism when I tell people that a few years of 2nd/3rd tier support on a large codebase is actually a good start to a coding career.
But I also never experienced the troubles described in this article. There were hard times, which would have been eased with today's online content. But it wasn't hard because of a downturn in confidence, and resulting "despair" that is described - it was a slow, but steady increase in confidence and abilities.
So are people better off today? Maybe. They certainly are coding at younger ages... but I have no complaints about my path. I still was fully competent in my early 20s, did a startup at 26, etc.
So there are many paths to developing your career. I'd recommend people keep an open mind to all options, and do what works for them personally.
I'm 37 and my first programming job after college was doing support & custom integrations for a larger product (which I wasn't allowed to change). I'd already been programming since 8 and knew BASIC, Pascal, C, C++, sh, Perl, Java, etc., but I had only taken a few CS classes and majored in English. It was a great chance to learn new things, e.g. SQL, and there was a ton of variety, autonomy, responsibility, and client interaction. Even the bad parts (Excel files, CORBA over firewalls, backwards intransigent IT departments) were great learning experiences. After maybe a year, having proven myself, I switched over to the web development wing of the company.
Amazing that there was a time that English majors could get hired for programming jobs. Nowadays your resume would be rejected by an ATS without ever passing before human eyes. You would be treated as a non-entity, incapable of offering any value.
I was lucky enough to fiddle with computers as a kid, so I kind of knew what I wanted to do, so I had years and years of "play time" in which I gently and accidentally introduced myself into programming, databases, operating systems, hardware, the web, etc. Often, things that I never thought would be useful turned out to be down the road. I also learned to be more fearless when experimenting and understanding a system - versus it takes some people years to get out of the "afraid to break things" mindset into the mindset of experimentation, trying things out, prototyping, poking things to understand them.
I think these are things that the sausage factory modality of education can't really provide, and working in the field will definitely give you this kind of thing too.
But the issue I see often is that the self taught or "graduated" (whatever that means) from support folks aren't taken as seriously as a person with a BsC in CS from a "legitimate" engineering school.
I /did/ get a formal degree, and it taught me tons (won't comment on the whole is it necessary thing) but I think it would have been way harder for me to get a programming job otherwise even though I probably had adequate skills for an entry level job in many places.
I don't think in many places today that someone would consider training a support person to do engineering, for various good and bad reasons, and we need to think hard about providing more long term learning-through-doing and on the job apprenticeships that other craftspeople do.
I was decent enough to implement basic algorithms and data-structures since high-school. I couldn't build apps of course.
Then in the first year of college I got hired for a small and shitty company doing web development, on a very low salary. My first project was to clone a popular dating website (Match.com). For me the project was overwhelming, as I knew nothing about what it meant to do real things. But I felt the pressure of delivering and I really needed the job, so my path from a near zero to somebody hirable took one month, because that was the deadline for showing something working.
So basically for me the driving force was hunger - and I'm talking about both the attraction towards CS and the need for an income.
Of course, from there to somebody that can call himself a decent software developer, well, that took another 12 years. And the kind of projects you're working on matters a lot. At some point I worked for a startup that had crazy technical challenges, crazy constraints, crazy deadlines, crazy everything. For 3 years I worked on that and learned much more than I learned in the other 9 years.
My first job was Night Operator at Transdata, a dial-up timesharing company in Phoenix, for the summer of 1969, earning $2/hour.
The fun part was that they turned off the timesharing service at night - but they didn't want to power down the Sigma 5 for fear that it might not start back up in the morning. There were occasional overnight batch jobs to run, but mostly I didn't have much to do.
I already knew BASIC, having punched programs on paper tape in high school to run on Transdata's service (which was how we got acquainted). I found a copy of the Algol-60 report at the office and thought it looked interesting, so I read it, tried out a bunch of programs, and learned Algol.
Then I found an assembly language and opcode reference for the Sigma 5, which was fascinating. There were plenty of blank cards to punch, so I learned machine language too.
I could have just sat back and done the night operator job and not much else, but man, there were such interesting things to fill in the rest of that time. And it's stayed interesting ever since.
Of course that was an unusual situation, and I suppose not one you could repeat now. After all, how often do you get a chance to have a whole computer all to yourself?
I was 8 years old in 1970. My dad was working for NCR in Waltham, Mass. He'd bring home a honkin' huge teletype and an acoustic coupler on the weekends. I taught myself BASIC and got hooked on Hamurabi [0], my first computer game vice.
How much paper did all of us go through back then?
Do you remember the first time you saw one of those newfangled "glass teletypes"? A terminal that printed out your typing and the mainframe's reply on a CRT instead of paper?
Was your first thought anything like mine: "How do I look back at what I was working on a few minutes ago? There's no roll of paper piled up behind the machine! How do I see my printouts?"
You know, I honestly can't recall my first glass teletype. I'm younger than you are so maybe it seemed like a natural evolution at the time.
I left the computer world in the late 70s when I discovered girls, music and partying. I came back to it the 80s when I learned about networked computers. Even through all of the intervening years, my coding still sucks. ; )
Yes, I used a video display terminal for the first time in a computer lab full of strange gear at MIT 40 years ago. The computer had to have its initial boot loader loaded from a strip of perforated paper tape. The terminal had characters "drawn" by the crt tube's electron beam. If there were a lot of characters on the screen the first few lines would start to fade before the e-beam was able to back to the top of the screen. By keeping the overhead room lights off, we could see almost a full 24 lines of 40 character. It seemed so advanced compared to the punch cards that I'd used for years before. Those were the days!
this is good to read. i am 7 months into a trainee developer role. the first 6 months were spent working on other peoples code and it was brilliant once they dropped me onto my first project, i didnt realise how much i was learning at the time.
did you have people readily available to ask questions to and get correct answers? it makes all the difference if you have somebody to guide you through periods of being stuck.
That's pretty much exactly my recommended approach for both training people who are new to software development and bringing an experienced developer onto an existing codebase (or language, or platform, etc) they haven't worked with before. The only difference, per individual, is how long they need to spend at each level before moving on to the next.
When you get into real-world software development, it's much easier to work with an existing codebase than to start from scratch on a new one. If the application is in production, then you know that the existing code works, so you've got a baseline. You can study it to figure out how it works, and you can compare that to requested changes in the way it should work, and then you just need to figure out how to change the code to make the behavior change. That leads you to asking the right questions, focusing on the right code. It's like the hand-holding phase, except it's real code instead of play code. Figuring out how the code works also teaches you a bunch of stuff on the side, like how to do debugging in this new codebase, how to set up and work within your development environment, the practices and patterns of your team, etc.
Learning to code is not hard. At all. Not relative to things that actually are hard. Having trained as an electronic engineer, programming is by far one of the easiest things I've ever done, by an order of magnitude. You can tell by the number of teenagers that can code, how many teenagers can design a nuclear submarine? That is much harder to learn.
I think it depends how you define "coding". Writing a compiler for C++ from scratch for instance isn't the same feat as coding a bubble sort in php. Besides, nobody designs a nuclear submarine anyway. I assume it's always a team work. It involves a lot of knowledge that not a single individual possesses.
There's also the amount of context required. To write a basic program, you don't need to know how computers actually work. Sure, it helps, but it isn't a prerequisite.
Designing a nuclear submarine, however, requires a lot of interconnected disciplines that rely on an understanding of each other.
To a lesser degree, it's similar to setting up your own ESXi cluster at home. You need to know more than just VMware--you need to understand networking, storage, flashing and configuring the host BIOS... AWS is quite a bit easier than managing your own physical environment.
Which may relate to why we see more younger people getting into coding than infrastructure/operations (regardless of the money).
I think the biggest advantage, the ease comes from the instant feedback you get while learning. Tweak something? See what it does.
Nothing's more frustrating to learn than something that comes with no feedback. i.e. relationships, getting a job, education its self
I'd disagree, except that so much of this depends on how you define "learning to code".
Digging into someone else's code base to understand it well enough to fix bugs and add features without introducing unintended side-effects is, at least for me, quite a challenge. It takes a tremendous amount of persistence, the ability to build a mental blueprint containing substantial amounts of logic, and - most importantly - the ability to swap into the mindset of whoever wrote the app, rather than the way you would have written it.
You know, a lot of us have studied tough things - I was a pure math major and I was a PhD student for a while in a very math-ish engineering department at Berkeley where most of the day was spend on proofs about stochastic systems or convexity. This sort of background isn't unusual here on HN, yet many of us would say that while code itself contains a wide range of challenges and difficulties, the field absolutely has monumental challenges that will push very smart people as far as they can go, maybe farther.
I once (about 15 years ago) got rebuked (gently) by a researcher at Sun Labs once when I dismissed a potential project as "easy." A museum was looking for someone to help build a search engine for their art collection. I said "a db search across some metadata, that's not a huge challenge." The researcher replied, with a mild smirk, "oh, I didn't realize you'd already solved all the issues in image search."
So then I backpedalled a bit and talked about the specs the museum had mentioned, "oh, well, they're just looking for search on some metadata". He replied, "well, maybe that's the only way they understand the problem, but you don't need to accept those limits".
Yes and no. From my own experience I would agree that learning to code is initially easier than hard engineering disciplines. However, the worst code I've encountered is written by EEs and MEs that overestimate their skills.
And, as mentioned elsewhere, there's a big difference between writing an application or two and being involved in a larger software engineering effort.
Your comment is both unfairly dismissive and wrong.
| Learning to code is not hard. At all.
This assertion is empirically untrue in the market for programmers (if nothing else). Why are programmers paid as skilled laborers? How many not hard (at all), highly paid, and quite frankly cushy job exists? In the Bay, hiring is the biggest problem.
| how many teenagers can design a nuclear submarine?
Why is designing a nuclear submarine the point of comparison? Is this some sort of humble brag?
| That is much harder to learn.
No one claimed programming is the hardest job in the universe. It is perfectly possible for harder jobs to exist and for programming to be hard.
Well learning if - while is like drawing a submarine on paper. How many teenagers can design an embedded software system of a nuclear submarine is a better question I think.
It's an ad. At the end: Our core program is specifically designed to bridge this whole process. ... Sign up below.
Worse, the training just creates junior web developers. There's a glut of junior web developers.
The concept of Ruby on Rails was to make the whole process of web site development a tutorial-level job from start to finish. How did that work out?
Learning to code is not so hard, but learning to code well is extremely hard - almost impossible. I have been doing software development years and years also in some well known companies and I am not sure if I have yet met a good developer.
As a self taught developer, I'm so thankful I first thought I wanted to be a designer. HTML and CSS made sense to me (the backend, even frontend js, forget it. I'd try to hack around it) and I sought deeper knowledge on the subject. Build systems and preprocessors were a gateway to command line tools and good organization skills.
Once I was thrown into full stack development, I at least had something to lean on while the backend programming caught up with the frontend. Then I started applying the things I learned programming backend applications to frontend applications (where do I keep all this state?). I think I spent a lot of time in the desert of despair wrt. certain types of programming but was never entirely there.
I think it's important to have something to feel confident in while you struggle.
I am part way through your trajectory. I was a designer first, fell in love with html/css, eventually gave in and learned js, started to really enjoy that and have now been edging my way to the back end for a while. Now I'm job hunting at the same time and definitely feeling that desert of despair. Was glad to see your post, gives me some hope!
269 comments
[ 2.6 ms ] story [ 283 ms ] threadFor me, the hardest parts of programming as a beginner - understanding OOP, data structures, etc. - didn't really 'click' until I stopped reading tutorials about them and start writing my own programs. The idea of 'objects' and 'instance variables' was mind boggingly confusing at first, but once I stopped worrying about how to make sense of them, the concepts somehow just fell into place.
I've also been trying to learn French simultaneously. The process was somewhat similar - taking a few Duolingo lessons and thinking that 'hey, I can do this!'. Then I read some actual French prose and everything seemed impossibly difficult. Things didn't 'click' until I started living and breathing French.
It's the same thing with coding.
Really makes 'anyone can code' sound more like a marketing slogan than an evidence backed statement. If your math and logic game is weak, you'll have a hard time with anything beyond the most cookie cutter PHP code.
It's no different than saying 'I want to build a tree house'. as opposed to 'I'd like to learn how to do construction' or 'I'd like to understand how to build with lumber'. The first statement will drive you to figure out or learn what it takes to make something tangible, the second two statements are just nice ideas, easily discarded when things get difficult.
Indeed, you can only get good at programming by doing it.
As someone who learnt programming in the 90ies, one of the difficult things nowadays seems to be that there are so many languages, libraries, frameworks, hypes, etc. Of course, if you know your CS and have experience, most of it are variations on common themes. However, I can imagine that it can be very difficult to focus on one thing and learning it well. There must be many copy & paste programmers out there who never learn anything in depth.
At the beginning of the nineties things were much simpler. If you had a home PC (obviously without internet), you could get started with QBasic, or shell out some money for a compiler and get Turbo Pascal or Turbo C++.
I did quite a bit of Turbo Pascal programming at some point and it was all very understandable. A simple language, a small standard library that's probably all that you'll have, good documentation, and an IDE (which had a very nice debugger and profiler). And you just crafted tools with that.
I somehow stopped my learning process before I hit 8th grade (around the same time I discovered that the opposite sex exists). When I picked it up again recently, the sheer number and complexity of frameworks and languages itself was daunting.
I can't imagine how hard it must be for someone who hasn't had a lick of coding experience. I could at least build a good looking website in HTML, CSS and simple JS before I started learning how to code.
It's damn tough and it has given me newfound respect for top coders. I work in marketing in my day job, and honestly, you could teach someone to replace me within a few weeks
I really try to keep a more emotionally neutral stance on all of my code and my abilities. If I want to indulge in arrogance I philosophize.
In the end, it's the same thing over and over again. Symbols swapping with others symbols denoting some kind of esoterically tangible, but ultimately fleeting, meaning.
It'd be nice to not feel perpetually stuck in the desert of despair though. I used to think being there meant I was learning stuff, because I had intuitively learned from repeat failure that after failure comes success. Turns out you can think about yourself plodding along at a steady pace, with no comparison to anyone else, as long as you stop assuming that there exists a clear, coherent, ordered organization to knowledge.
There exists such a thing in school, or at least the commentary on a topological sorting would have you believe. Technology doesn't always develop and get released in school though. Sometimes it develops in webs that are can not be causally described, because thought and skill do not necessarily travel in measurable directions, nor is their instantiation completely definable/observable.
People apply too many theoretical concepts to describe, dictate, and organize reality without understanding the effect on perception.
"In the end, it's the same thing over and over again. Symbols swapping with others symbols denoting some kind of esoterically tangible, but ultimately fleeting, meaning."
I feel that way about all the different languages, new ones or old. Just different symbols that distill down to machine instructions.
My question to you, how do you approach learning? Learning new things and marking your progress? What gives you the satisfaction that you've made progress in "learning" a given topic?
I don't know. Right now I am learning how to not know when I am learning, because I have determined that measuring learning in any form can often be a barrier that actually prevents me from learning.
The "cliff of confusion" he describes is a function of the Dunning-Kruger effect (http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect), which indicates that you don't know how bad you are at something until you get better at it. As an educator, the challenge is to make that cliff as unscary as possible and chart a path through the "desert of despair" so that you're not pushing too much at one time.
On the other hand, as a self-learner it's really really hard to get past the point where you've learned enough to know how much you have yet to learn, or in terms of the article, when you look over the cliff and see how HUGE your journey is becoming.
To a large extent, the article is an advertisement (in more ways than one) for guided learning, expressed in a pretty clear way.
Totally unrelated to that, Algolia's HN search really is magnificent - supremely fast, accurate, and even quite attractive. Impressive.
One thing that I think separates senior engineers from juniors is a level of confidence and willingness to tackle the unknown and learn new things, tempered by pragmatism that they don't all need to be tackled and learned right away.
I just don't know how to actually _do things_ with code. So, in essence, I think I know the language, and in a sense I do insofar as I know how to write an if else statement, a while statement, declare a variable, etc., but I _don't_ actually know the language, because I can't do anything with what little I do know.
Do you have any advice?
Build something, anything. Then set it aside for a while, come back to it and improve it. Reading code you wrote a couple of months ago will highlight very quickly the parts that are clear and concise and those that are not.
Pick an open source project that is interesting to you and improve the documentation. Writing clear documentation requires a depth of knowledge that surpasses just employing it.
Give a presentation on and/or tutor someone on a topic. Like writing docs, this requires being able to think clearly about the topic.
I had quite a bit of experience with relational databases from my previous job, which I leveraged pretty heavily on my resume. As far as interviews, I was very honest about what I did and didn't know, and passed a coding test by pulling an all-nighter (and taking a vacation day) to learn a tiny bit about Django.
The offer came from a company I had initially reached out to about an unpaid internship, which eventually manifested into a full-time job. We agreed to a three month trial period, and they kept me on afterwards.
There was no doubt plenty of luck involved in the whole process. I sent dozens of cold emails, and offered to work for free several times (thankfully never had to).
I've been toying with the idea of quitting everything and going all-in for 3-6 months.
Would that be 100% retarded or just about 70% retarded?
I can live with 70%.
PM me if you'd like to talk about my experience with one.
I'll go with "less than 70%". Or at least I hope, because that's what I did.
Coming from a Economics background (with a minor in Statistics), I took a job as a "data analyst" at a software company out of University. It was fun, but I relied on working with a programmer to get even basic things done.
Then came the "Data Science" wave. I thought, this is right up my alley! Except I needed to learn to program. I tried doing the tutorials and academies online, but was continuously stuck in the hand-holding stage. So I did the opposite of what is often recommended around here: I quit my job and enrolled in a 2 year Computer Programming course at a college. I'll be finishing up this spring. The enforced, formal structure and discipline has been a boon.
I feel great about having done it. I still feel pretty green, but I'm probably somewhere in the middle of the "desert" now. I credit school with having got me that far.
Say you wanted to build the simplest of Rails apps - you're simultaneously learning not only what the terminal and a text editor is, but how unix commands work, what an MVC framework is, probably a little of HTML and CSS, database migrations (maybe some SQL), asset management/pipeline, some random Rails-specific syntax, probably git, and if the creator of the tutorial is feeling ambitious he/she may throw in some TDD and testing frameworks. And that doesn't even begin to go into Ruby -- the entire programming aspect of programming.
So you're thrown out into the middle of the ocean, and blindly writing code you don't understand (because there's no way any tutorial could fully explain everything you're learning without being 2,000 pages long). You follow the tutorial, you get your little app running, then you realize, "I have no fucking idea what I just did." There's no way on earth you could do it again.
The other approach is to bring you from the bottom up, starting with language/syntax Codecademy style. So you spend a month learning how to almost be able to write a for loop in JavaScript, and then you realize you have no idea why you would ever need to know what a for loop is, and even less of an idea of why it's useful.
I got stuck bouncing back and forth between the two for years (literally), wondering how the other programmers were possibly smart enough that they could grasp meaning from random blobs of tutorial code, or how they possibly had the patience to grind through enough JavaScript tutorials enough that they could actually create something. I finally decided to throw away the crutches and venture out on my own. I think that was the single biggest step in becoming a (decent) programmer.
The timid, "I don't know how to program" side of me said, "Wait, I have no idea how to do this yet. You need to read up on it." But I finally bit the bullet and said, "You know what, I'm building this app right now. No, I don't know how to do a lot of it, yes, my friends that are a lot smarter would probably mock my code if they saw it, but I don't care. I'm building this." I don't think you can ever truly learn to program without saying, "I don't care, I'm building this." It took a long time and more Stack Overflow than anyone should ever care to read, but things finally started clicking. I built a few apps (Rails and iOS), went back to the tutorials, and said, "Are you kidding me? That's what they were trying to teach me?"
There was no way I would have remembered that crap if there was someone guiding me through or holding my hand. Sometimes you just have to start, having no idea what you're doing, and figure it out as you go. That's a foreign concept to people who aren't used to creating things, but I'm convinced it's the only way to truly learn.
This is a great point because it's easy to get stuck in analysis paralysis. There's always a tension between needing to stretch out and build something just beyond your capabilities and then having to backfill some of the fundamental knowledge you missed along the way so next time you can reach further.
At that point, it was up to me to figure out what to do. I started with a single screen that showed some text and added a few more screens that had the same text. Then I added a button that triggered a change of that text. Then a button that displayed an image. And so on until I had a real card game that could even identify whether there were any legal moves available and if the player was stuck.
Every step along the way was not easy and I got derailed a couple times, nearly giving up. The hardest single feature to implement was dragging and dropping a card. It took a lot of cribbed code from a few useful blog posts, but the feeling when I actually got it working was indescribable. It was a Saturday morning and I was running around my house, dragging and dropping cards on my tablet like I was 8 years old and it was the greatest Christmas gift ever. That was the moment when I realized I could actually finish this if I was willing to put in the effort. The rest of that weekend was spent in blissful coding and my commitment to becoming a developer has never wavered since.
Now in my job, which I got an interview for because of the card game, I have witnessed other people with less self-guided (contrasted with CS class projects) experience than I started out with be unable to persist long enough or self-teach hard enough to solve a problem by themselves without asking for help to get over minor bumps. I won't ask for help from a more senior dev unless I have exhausted my abilities to understand the problem space and can enumerate the things I have tried. I refuse to be the person who simply "doesn't know how".
Never ever give up.
This is a carbon copy of my life as a programmer right now.
I've made the decision to just fucking do it about 50 times, but each time I get barely started and get so frustrated with myself for not understanding and not knowing what to look for that I give up. I know that's another point where I just have to sit, searching, until I find the answer, but it seems that from my profound lack of understanding of the basics of the language (JavaScript; despite doing the Codecademy course, and the CodeSchool Node.js and Express.js courses) that I will have to do that for every minute step that I take in the program. It just seems so overwhelming that I become paralyzed in my desire to push on, but feeling that I know I won't make any progress.
Seriously. "Just code" is the worst advice that everyone gives. It's trite. You'd be better off saying nothing at all. Do you think you can sit someone down with a C compiler and come back five years later to find they've written the Linux kernel?
Don't say "just code". It's not helpful. It's disparaging. You don't tell a child "just walk". You learn to code, you're not born with it.
I know a lot of people say something like "Just open up a git repo and start making pull requests on the back end of your gulp process after you wget the source from such-and-such repo"... Yeah, that annoys me too. I've had a lot of success just sitting people down with Chrome and have them hit Ctrl+Shift+I and show them a couple fun things with DOM maninpulation, etc. The point is, the worst thing to do that I think claims the most victims on the path to learning to code (I know I struggled with it for years) is just constantly deliberating about what is the "best way to learn" when you should just be playing, having fun and failing. That's the hump I try to nudge people over - the idea that you need to have permission or a "master" to become a developer.
Here's the sticking points where beginners need your help, and might not even have enough information to actually ask what they're looking for:
What framework do I use? I see people talking about AngularJS, so I'm going to pick that one. Oh wow, it's harder than I thought bzzzt you just lost a future programmer.
How do I deploy? DigitalOcean costs money, bzzzt there goes another. I paid for DigitalOcean, but I ran into troubles installing pip, bzzt there goes another.
How do I make a GUI? Tkinter, Wx, Qt, GTK, WPF, bzzzt there goes another.
And the worst of them all... "What language should I learn?"
Yeah, a lot of programmers might not want to hear this. But there are a lot of languages. You can't blame a beginner for not being able to decide. And to be honest, there isn't really a good choice here, which is why programmers get into fights about languages and when that happens, bzzzt there goes another. Javascript sucks, but people claim its essential. Beginners get turned off by hearing "Javascript sucks but you have to learn it". The better option is to just not learn programming. Or bringing political wars into it. "Don't learn C# because M$". Beginners don't care about your politics, they want to learn. Eventually people settle on Python, so the beginner starts learning Python, then asks "what GUI framework" or "how do I deploy Django" and we start back at the top of this list.
So, in the midst of all of this confusion happening for a beginner, they're (understandably) lost and ask for a lighthouse to guide them on a path, any path, as long as they don't have to make the choices themselves. So they ask the question "how do I learn to program". And the response they get? "You don't learn how to program, you just start programming."
Bzzt, you just lost the entire next generation.
In my generation and before it, most of us learned coding the same way. (And self esteem for that matter.) Even if you do have the luxury of teachers and classes and handholding and cheerleading, the real learning is not going to happen until you sit down with a code editor and actually try to make something real.
And if the first difficulty you hit causes you to turn around and run then that's another win. It's a very fast way for you to learn this not a career or hobby for you, because dealing with those decisions and difficulties is a major part of the job. 30 years in I'm still dealing with stuff like that every day.
What I'm saying is 'just write something' doesn't help people who would ask the question 'how do I learn programming', It helps the people who ask 'how do I get better at programming'. You get better at walking by walking more. You get better at coding by coding more. You start walking by learning it from someone else, or by using something to pull yourself up (like a chair or a table leg). You learn programming by asking how and following their advice.
Your son didn't ask how to walk because he didn't know the question. Beginners don't ask how to deploy because they don't know what deploy means. "Just code" doesn't answer the problem of "how do I write a GUI app". It makes it seem like it's so easy that you shouldn't have to ask. And since you don't know the answer and no one will tell you, programming must be hard, or you must be stupid. That's what a teacher or a mentor offers. Advice. Not glib remarks.
I commonly get to this point after just wanting to proof out a concept and get something working. And then I realize I need to go back and do the unglamorous work of getting it right. But I learn the most then, and helps enormously on future projects.
If you don't have the motivation you'll never be able to do it. If you can't sit in front of a computer for 8 hours a day reading documentation and hunting for syntax errors you're not going to be able to do it. If re-writing algorithms doesn't give you an intrinsic satisfaction, you're not going to be able to do it. No amount of everybody can code tutorials is going to help. They should all be, "how to find the motivation to keep coding" tutorials.
Unrelated, but related to the article, the word sociopath get's misused a lot and this article is no exception. http://www.thefreedictionary.com/sociopath
Motivation will fail you when you are left with those last 10% of a project that feel like the first 90%, but now with uninteresting tasks like tweaking the hell out of a UI, fixing all those bugs resulting from code optimization in obscure cases, implementing database integrations to assure backwards compatibility with earlier versions or some such shit that is impossibly uninteresting but required to finish the project.
Then in play comes discipline, and that is something you have to learn systematically, and when you don't feel motivated at all to continue through and just wish to quit it all.
But you are correct, you have to get satisfaction from the process. Maybe the motivation is to see the end result. But still, there is that phase where all hope seems to be lost, inspiration and motivation are nowhere to seen and all that remains is just grind and decide to follow through.
From that perspective, I absolutely understand the urgency here, and appreciate how this article talks about how the moment when the tutorials break off is when the real learning begins.
I think today's students would also have a lot more fun if they ignored all the opinionated garbage about which flavor-of-the-month checkboxes they need on their resume. Figure out what you like and get really good at it. Many top employers are looking for passion, pragmatism, and adaptability rather than specific tools and libraries.
If you feel like your knowledge is getting flushed away with a new platform, then you've been learning the wrong things.
My point was, you can teach yourself a half-dozen programming languages, operating systems, databases... (which is inevitable for most developers) or you could have spent that time collecting diplomas in academia. This is not really a new concept, I read it somewhere else. Any profession that demands a lot of ongoing learning, I think people will quit because the effort may not seem worth it.
I agree you have to learn the "right" things but that takes experience and strategy. That's an interesting aspect of all of this. When everybody says "iPhone" you might bet on Android. Everyone says "Google Glass" and you might bet on Unity. If you have a crystal ball, maybe you're the next Warren Buffett ;-)
I understand the point you're highlighting, but there are very few interesting jobs where you get to say "Ok, now I'm done learning and I know everything I'll ever need to know to do this job perfectly."
I have no idea how much stuff a brain surgeon has to learn, but having the idea that there are people who are brain surgeons, it cannot be so much harder than being a really competent programmer.
Think John Carmack for example. That guy is a friggin beast in learning new systems and producing working code. That is really, really hard to do. It requires immensive amount of thinking and applying, and sitting in front of computers while balancing your body and health at the same time so you dont kill yourself in the process or go mentally insane and just give up.
Oh yeah, but Carmack is a rocket scientist too .. so, maybe not the best example.
But putting those jobs above really competent programmers is just stupid, if you want to be best in what you do, in any life path you are taking, it will take all of your effort, and then some more. So why compare. It's all about doing what you love.
Well, we know how everything about how a CPU works. We don't know everything about how a brain works.
Not really my field, so I truly don't know. But I'd be a little suspicious of someone who claims there's nothing new to learn here.
The other thing is that while the brain is highly complex, that doesn't mean that people who work in it have managed to master something more complex than CPUs (or house wiring, for that matter). They may simply not really understand what they're doing to the same extent.
To me, the thesis in the original post is this "[if] there are people who are brain surgeons, it cannot be so much harder than being a really competent programmer."
I tend to agree, because I think that some types of programming push people's mental ability and sheer stubbornness past the point of human ability. In short, it will take all you have, and there will still be things you just can't understand or do.
If you define the task as "the things that we understand and can do", then by definition is is not equal in complexity to the brain, but like I said, I think the statement is a contrivance.
Almost nobody can do that. The hardware alone is so complex, these modern CPUs have many BILLIONS of transistors packed so tight that it is impossible for us to even fix them. So we just have a vague understanding of what is going on when we program, but really, we have no clear picture. But the best programmers out there, they have this map of the computer in their heads and the systems, and the better you are, the better the map in your head is.
Think NASA level programmers. They truly have to know how the system works, and yet, they cannot most probably understand the whole stack even, down to the transistor level operation, and then below that even in some really extreme cases where the systems overheat and there is magnetic bit flipping happening and other obscure stuff.
Immense amounts of work equals to amount of commitment required, which equals hard. To be a really competent programmer that knows how to truly take advantage of the machine is really rare, and even then it is down to some very specific domain, like graphics programming, systems programming and so on. So it is very hard to achieve, and very rare.
Comparing "computer surgeon" to brain surgeon is like comparing sudoku to racquetball.
There are plenty of other fields that do as well, but software absolutely belongs in the mix.
Of course, there's a bit of a difference, in that you can call yourself a programmer even if you can't program. Whereas you can't call yourself a lawyer until you've passed the bar, which almost always involves attending 3 years of law school. So it's not really an apples to apples comparison. There is really no barrier to entry to programming that sets a minimum bar. So if you're comparing something with a minimum education standard with something with no minimum standard… well then yeah.
But personally, I don't think the required training to become a lawyer is anywhere close to as rigorous as what it takes to become a brain surgeon or rocket scientist, and if you look at typical pre-law majors, they aren't as difficult or rigorous as common undergrad degrees for software developers (CS, math, engineering, physical sciences). Let's face it, people don't drop out of poly sci because physics would be an easier major with more time to party.
I loved every bit of it. And still do.
It's true. The saddest part is that we forget who we were before we crossed over, and lose the ability to sympathise with people who haven't been through it.
My strategy for people who ask me to tutor them is this: work through the first five chapters of /learn python the hard way/ by yourself, and I will mentor you the rest. Those chapters are so easy, it is just a test of motivation. I have only had one starter. Also, she finished.
For me, as an earth scientist, there have always been small calculations or simulations that are quite valuable, even though they are not overly difficult or complex. This provided the motivation to learn basic Matlab. As my skills and ambition grew, and I learned new languages and techniques, the class of problems that I wanted to solve grew in scope and complexity. I also learned to recognize new problems and their probable solutions as my tools developed. Programming changed the way I look at the earth, and at statistics, personal finance and a range of other things in which quantification is enlightening.
In contrast, I have had a hard time picking up new languages or programming paradigms when I don't have an immediate need. I've spent time mucking around on various 'learn to code' websites, and read and sometimes completed tutorials on databases or Haskell or whatever, but it feels very different: meandering, non-essential, hard to gauge in scope (how much do I need to know to be useful, how deep is the water really), hard to link up to the rest of my life. Programming for me is a powerful and enjoyable means to many ends, but not something that I am inclined to do for its own sake.
I think if I had said, "I want to learn to program so I can build web apps" without actually having a simple and truly useful web app that needed to be built, I would very quickly move on. If I had said, "I want to learn to program so I can find a new job that pays more money" I would stick with it for a bit longer but it would be incredibly frustrating, because it doesn't seem like there is a very straight path without formal guidance (such as going to school of some sort).
I suspect many people feel the same, but I don't necessarily know how smaller, less formal education systems can work on that. Students always need some amount of self-motivation, and useful results are a long ways off in some areas.
I find most articles confuse 'code' (producing code) and 'program' (making programs).
I would argue the first one is relatively easy once you grasp concepts and turing-cturing-completness.
The later however takes years if not decades.
I find most articles confuse 'code' (producing code) and 'program' (making programs).
I would argue the first one is relatively easy once you grasp concepts and turing-completness.
The later however takes years if not decades.
Of course this logic doesn't hold up all the time. Sometimes you can remove a critical support and collapse a structure, and sometimes removing a line of code has little to no effect, but the point is that in programming, a small change can have an unboundedly large effect, which is the definition of discontinuity.
(I believe it was this professor, who was my teacher for discrete math: http://www.cs.virginia.edu/~jck/ )
I could clarify and say that the change doesn't have to be unboundedly large in absolute terms, but rather relative to the change in input. (i.e. a jump discontinuity from 0 to 1 is not absolutely unbounded, but it is relative to an arbitrarily small change across the jump.)
[1] http://en.wikipedia.org/wiki/Continuous_function
Seriously, that was a major sticking point for me having programmed for a long time: going from "if you have not declared that identifier, game over" to "magic happens".
On a side note, if anyone has some great resources for RoR, I'd love to have them linked. I suspect my inexperience is the source of my problems, and I'm welcome to any assistance any one would like to give.
http://guides.rubyonrails.org/
Which bits did you find were magic? The bits of convention I can think of you'd have to know about are:
DB naming conventions - these are used so that it can do joins etc easily behind the scenes, they're pretty simple so not a huge problem I find.
Rendering at the end of controller actions - it'll render the template with the same path as your route - again relatively straightforward.
Class loading - lots of things are loaded at startup time, so that you don't have to include files - I have mixed feelings about this, it feels easy and simple at first, but could leave you unsure where code comes from or which methods you can use in which files (e.g. view helpers). Definitely more magic.
One other area which does lead to real problems is that rails sites often use a lot of libraries in the form of gems - this leads to unknown, sometimes poorly maintained or inappropriate code being pulled in at runtime, and makes it far harder to reason about things like say authentication if using a gem. This is my biggest complaint with rails - lack of transparency of code paths when using gems like devise, paperclip etc but it is unfortunately quite common in web frameworks
They actually got rid of quite a few bits of method_missing madness I think recently so that magic is gone at least (all those magic find_by_ methods are deprecated or removed, not sure which as I never used them). I haven't found the conventions get in the way much as it's something you learn once and can apply anywhere, but completely understand why someone might object to some of the magic setup for helpers/rendering.
For example:
You have to know that rails has some automatic routing based on the class of an object. If @story is a Story class, rails basically does this underneath: There's implicit conversion of class names going on under the hood in a few places. It's all documented but it's not easy to find the documentation when you don't know what you are looking for.The thing that really screws up people starting with rails is not understanding the various layers (html, views, controllers, models, http, etc.) and how rails puts those together. If you don't know how to do web programming with basic html and php, rails will eat you alive with it's seemingly magical behaviors.
For:
You get In practice it doesn't cause as many problems as you think, even in large applications.https://shinynuggetsofcode.wordpress.com/2013/09/30/conventi...
Like a lot of the Rails stuff, it feels like amazing cool magic when things just work. But then when they don't work and do something weird instead of what you expected, it feels like it takes forever to figure out why, what was named wrong, and what it's supposed to be named.
http://railscasts.com/
Jose Valim's Crafting Rails Applications[1] is a wonderful resource, since it deliberately sets out to peel back the layers of magic. A lot of the techniques are ones I probably would not use in practice (storing views in the database and rendering them!), but they serve to elucidate the operation of the entire view stack. Really good stuff.
Two other good books are Rails Antipatterns[2] and Objects on Rails[3]. Neither of them has been updated in a long time, but the general principles will still hold. The former is more practical, the latter more theoretical; precscriptive and fanciful food for thought, respectively. Both solid.
1. https://pragprog.com/book/jvrails2/crafting-rails-4-applicat...
2. http://railsantipatterns.com/
3. http://objectsonrails.com/
http://www.manning.com/black2/
But most people I know don't get this far when they self teach or do a bootcamp. They just know that, given a framework, they can build things but not how anything was really built. Sure it's effective to push out a product, but it makes diving into real programming pretty difficult. That's just my perception though.
Unlike climbing Everest or understanding how the human body works the challenges in learning to program are entirely man-made! (Except for recursion, of course.)
Picked up RoR and was quickly overwhelmed with a million unfamiliar concepts as pointed out in the excellent (and very similar) article "This is Why Learning Rails is Hard."[1]. That knowledge tree they show is one I didn't formally stumble upon until later, but throughout my progress I realized "hey, this concept is really part of the much broader topic of X." Then I'd go down a rabbit hole on X.
Before I found that tree though, I had already given up on Mike Hartl's tutorial once, and decided I really needed to have a functional grasp of Ruby and core programming concepts. From there I realized "Ruby/RoR on Windows is not ideal." Then went down the whole devops path and learned about things like Vagrant/Chef/Virtualbox, etc.
I also started picking up books on much deeper computing concepts to understand the lower level mechanics of the magic. Like you I went down to first principles and even a bit of assembly. I couldn't write any to save my life and knowledge is still fuzzy, but I now grasp how the concept of data structures came to be, and more importantly WHY.
I recently tackled Mike Hartl's Rails Tutorial again. His updated version is a great improvement, and this time I actually understand the concepts he goes through. When a new one is introduced, I have enough of the underlying knowledge to at least have a sense of what/why something is, or what I need to Google to learn more.
I wish more classes online provided "deep dive" resources/links on things. Like, if CodeAcademy has an exercise on Ruby covering types, an eager student might really benefit from a deep dive sidetracking into dynamic vs. statically typed languages, and a high-level of what they should know.
My biggest gripe with the tutorials that are out there these days is that they cater to either absolute beginners or competent users. Wish they did a better job of trying to bridge the gap from absolute beginner to intermediate.
Another great example of that is the concept of design patterns. I haven't found many great beginner/intermediate resources on this, but as I've started learning more, I found myself saying "hmm, seems like lots of people do this a similar way--I wonder why." Turns out some approaches to problems are largely solved issues for a majority of use cases, hence: design patterns. This got me down the whole path of software architecture and starting to grok some of the higher-level abstractions and way of thinking in the abstract which was tremendously helpful compared to just being given specific examples with no broader context.
[1] https://www.codefellows.org/blog/this-is-why-learning-rails-...
Cathy, a new frontend student, experienced similar struggles when starting her first real project - a simple HTML/CSS resume. She spent countless hours fixing minor typos and almost quit. It wasn't until she was reassured that this was _normal_ and "real" programming was much different from codecademy did she feel like she was truly learning. She wrote about her first month (with similar highs and lows as OP's visual) in this post: http://blog.thinkful.com/post/98829096308/my-first-month-cod....
side note: Erik (OP) is an incredible guy, we had the pleasure to share our experiences in Edtech and it's obvious that he truly cares about student outcomes.
it's interesting anecdote!
When i was at uni, i noticed that a large number of "beginners" tend to fall into this category too - frustrated at minor typos/language idiosyncrasies. Those who had the mental strength to endure it end up passing the class, while those that just gave up will almost inevitably change their major (and thus, stop programming i guess?).
But i think this is a result of poor educational methods, not because of an inherent property in programming.
This is where the beauty/simplicity of some programming languages, namely, intepreted languages (e.g., Python), comes in: if a bad line of code never gets executed, then the program itself will run fine. In other words, if the line is never called in the program, then you'll not know that the functionality that that line presented was bad. In this case, the analogy breaks down a bit - and also shows why certain languages are easier to learn than others (e.g., Python vs. C++).
I think that many years of developing large applications in Perl were really good for me. Perl is compiled when you run it, so you get the basic-syntax check that you get with other languages. But it's also very lenient, so you learn through experience to get your logic right, test return values, and do all of the things that help make sure that a program which executes is executing correctly.
Is a statically typed language more likely than a dynamic language to work correctly in production, if both have 0 tests? Yes.
Is either ideal? No.
Can both be improved by adding a few tests? Yes.
I'm not sure I agree. "Work correctly" does not just mean "compile correctly". I would want to see a lot of evidence to back up any assertion that programs written in statically typed languages are less likely to contain logic errors that compile and run just fine but don't do what the programmer (or his client) actually wanted.
I agree that neither is ideal and that adding testing can improve any code.
As certain assertions related to logic can be encoded into static types (especially in a language with a type system more like Haskell's than, say, Go's), while static typing can't eliminate all logic errors, it can reduce the probability of logic errors escaping detection in the absence of testing, since compiling a statically typed program is, in effect, a form of testing (limited to those assertions about behavior which can be encoded into the type system.)
Fair point. (Especially if, as you say, you are using a language with a type system like Haskell's, which to me is more like a program analysis engine than just a type system.)
That's not beautiful; that's horrendous. A program that might contain syntactic (!) errors has no claim to being a sublime mathematical construct.
I'd say it's "beautifully simple" when I can tell you with 100% confidence that my program will never, ever, ever experience errors of a certain type. Even better if I can tell you with 100% confidence that my program contains no errors at all (which is possible with proof-based languages).
Saying a Python program is beautiful because it can have hidden failure conditions is like saying that a poorly maintained gun is beautiful because it can fire when rusty (but watch out for explosions!).
I wish, when learning to program, that I'd been taught to write universally correct code instead of "mostly correct" code.
Actually, that's one of the pitfalls of interpreted languages.
You want to Crash Early & Crash Often [1] or you'll move along, merrily ignorant of a serious problem just because it doesn't get executed.
I try to solve this shortcoming of languages like Python with proper unit testing. It gives me the confidence that there's a decent coverage of the different code paths so that I won't learn about the problem in production.
[1] - https://pragprog.com/the-pragmatic-programmer/extracts/tips
Simplicity? Yes, probably (at least as long as I am writing the code and not debugging it). But definitely not beauty. I find this particular behaviour the ugliest part of interpreted languages. I may make a small typo, incorrectly capitalize variable name or forget a quote and nothing will tell me that my code is wrong or where exactly it is wrong - it will silently skip the error and happily show me wrong results.
There are a lot of jumbled concepts here, most of which don't matter anyway, because what you are talking about is the phenomenon of graceful degradation. In the physical world, both natural and man-made, almost nothing at the macro scale is ever perfect, so the best designs tend to be those that remain good enough under the widest range of circumstances vs. a more common software goal of being perfect under perfectly controlled circumstances.
As software gradually moves out from the wall garden of a single mainframe to fill the world with interacting systems spanning diverse machines, sensors, communications channels, data types, etc., design for graceful degradation becomes more and more of a focus for professional software architects.
Coding in the gracefully degrading way is much harder than coding in the "if even one of your ten lines is wrong, you crash" tradition. The fact that even the latter is so hard for us humans means we will need more and more help from machines that learn what to do without being explicitly told by us.
But it's not just an issue of graceful degradation. The fact that tiny changes in a program can have very large effects is a feature, not a bug. We grade programming languages on their ability to concisely express complex operations, and that conciseness necessarily means that very different operations are going to have similar expressions (e.g. subsetting rows vs columns of a matrix typically differ only by a small transposition of characters, but the effect is completely different).
You can write software that degrades gracefully, but one syntax error (or other "off-by-one-character" problem) is still going to kill the program. You can talk about running your program on a large set of redundant servers with no single point of failure, so that you can update them one-by-one with no downtime, and that makes you robust against even syntax errors. But that's not helping you teach novices how to write code.
But even considering DNA as just a 4-letter language with discrete characters, my point is that many, even most, small sequence changes to a genome (e.g. single-nucleotide variants) have small effects or no effect at all, which gives evolution a smooth enough gradient to optimize things over time. That's what I mean by continuous in this context. The opposite would be, for example, a hash function, where any change, no matter how small, completely changes the output. Hence you couldn't "evolve" a string with a hash of all 7s by selecting for "larger proportion of 7s in the hash function", because hash functions are completely discontinuous by design. But you can evolve a bacterium that includes more of a given amino acid in its proteins by selecting for "larger proportion of that amino acid in protein extract".
UNIQUE ETHICAL PROBLEMS IN INFORMATION TECHNOLOGY
By Walter Maner
http://faculty.usfsp.edu/gkearns/articles_fraud/computer_eth...
I know that few people learn like this these days. I've heard extreme negative criticism when I tell people that a few years of 2nd/3rd tier support on a large codebase is actually a good start to a coding career.
But I also never experienced the troubles described in this article. There were hard times, which would have been eased with today's online content. But it wasn't hard because of a downturn in confidence, and resulting "despair" that is described - it was a slow, but steady increase in confidence and abilities.
So are people better off today? Maybe. They certainly are coding at younger ages... but I have no complaints about my path. I still was fully competent in my early 20s, did a startup at 26, etc.
So there are many paths to developing your career. I'd recommend people keep an open mind to all options, and do what works for them personally.
I was lucky enough to fiddle with computers as a kid, so I kind of knew what I wanted to do, so I had years and years of "play time" in which I gently and accidentally introduced myself into programming, databases, operating systems, hardware, the web, etc. Often, things that I never thought would be useful turned out to be down the road. I also learned to be more fearless when experimenting and understanding a system - versus it takes some people years to get out of the "afraid to break things" mindset into the mindset of experimentation, trying things out, prototyping, poking things to understand them.
I think these are things that the sausage factory modality of education can't really provide, and working in the field will definitely give you this kind of thing too.
But the issue I see often is that the self taught or "graduated" (whatever that means) from support folks aren't taken as seriously as a person with a BsC in CS from a "legitimate" engineering school.
I /did/ get a formal degree, and it taught me tons (won't comment on the whole is it necessary thing) but I think it would have been way harder for me to get a programming job otherwise even though I probably had adequate skills for an entry level job in many places.
I don't think in many places today that someone would consider training a support person to do engineering, for various good and bad reasons, and we need to think hard about providing more long term learning-through-doing and on the job apprenticeships that other craftspeople do.
I was decent enough to implement basic algorithms and data-structures since high-school. I couldn't build apps of course.
Then in the first year of college I got hired for a small and shitty company doing web development, on a very low salary. My first project was to clone a popular dating website (Match.com). For me the project was overwhelming, as I knew nothing about what it meant to do real things. But I felt the pressure of delivering and I really needed the job, so my path from a near zero to somebody hirable took one month, because that was the deadline for showing something working.
So basically for me the driving force was hunger - and I'm talking about both the attraction towards CS and the need for an income.
Of course, from there to somebody that can call himself a decent software developer, well, that took another 12 years. And the kind of projects you're working on matters a lot. At some point I worked for a startup that had crazy technical challenges, crazy constraints, crazy deadlines, crazy everything. For 3 years I worked on that and learned much more than I learned in the other 9 years.
The fun part was that they turned off the timesharing service at night - but they didn't want to power down the Sigma 5 for fear that it might not start back up in the morning. There were occasional overnight batch jobs to run, but mostly I didn't have much to do.
I already knew BASIC, having punched programs on paper tape in high school to run on Transdata's service (which was how we got acquainted). I found a copy of the Algol-60 report at the office and thought it looked interesting, so I read it, tried out a bunch of programs, and learned Algol.
Then I found an assembly language and opcode reference for the Sigma 5, which was fascinating. There were plenty of blank cards to punch, so I learned machine language too.
I could have just sat back and done the night operator job and not much else, but man, there were such interesting things to fill in the rest of that time. And it's stayed interesting ever since.
Of course that was an unusual situation, and I suppose not one you could repeat now. After all, how often do you get a chance to have a whole computer all to yourself?
How much paper did all of us go through back then?
[0] http://en.wikipedia.org/wiki/Hamurabi
Do you remember the first time you saw one of those newfangled "glass teletypes"? A terminal that printed out your typing and the mainframe's reply on a CRT instead of paper?
Was your first thought anything like mine: "How do I look back at what I was working on a few minutes ago? There's no roll of paper piled up behind the machine! How do I see my printouts?"
I left the computer world in the late 70s when I discovered girls, music and partying. I came back to it the 80s when I learned about networked computers. Even through all of the intervening years, my coding still sucks. ; )
When you get into real-world software development, it's much easier to work with an existing codebase than to start from scratch on a new one. If the application is in production, then you know that the existing code works, so you've got a baseline. You can study it to figure out how it works, and you can compare that to requested changes in the way it should work, and then you just need to figure out how to change the code to make the behavior change. That leads you to asking the right questions, focusing on the right code. It's like the hand-holding phase, except it's real code instead of play code. Figuring out how the code works also teaches you a bunch of stuff on the side, like how to do debugging in this new codebase, how to set up and work within your development environment, the practices and patterns of your team, etc.
Designing a nuclear submarine, however, requires a lot of interconnected disciplines that rely on an understanding of each other.
To a lesser degree, it's similar to setting up your own ESXi cluster at home. You need to know more than just VMware--you need to understand networking, storage, flashing and configuring the host BIOS... AWS is quite a bit easier than managing your own physical environment.
Which may relate to why we see more younger people getting into coding than infrastructure/operations (regardless of the money).
Digging into someone else's code base to understand it well enough to fix bugs and add features without introducing unintended side-effects is, at least for me, quite a challenge. It takes a tremendous amount of persistence, the ability to build a mental blueprint containing substantial amounts of logic, and - most importantly - the ability to swap into the mindset of whoever wrote the app, rather than the way you would have written it.
You know, a lot of us have studied tough things - I was a pure math major and I was a PhD student for a while in a very math-ish engineering department at Berkeley where most of the day was spend on proofs about stochastic systems or convexity. This sort of background isn't unusual here on HN, yet many of us would say that while code itself contains a wide range of challenges and difficulties, the field absolutely has monumental challenges that will push very smart people as far as they can go, maybe farther.
I once (about 15 years ago) got rebuked (gently) by a researcher at Sun Labs once when I dismissed a potential project as "easy." A museum was looking for someone to help build a search engine for their art collection. I said "a db search across some metadata, that's not a huge challenge." The researcher replied, with a mild smirk, "oh, I didn't realize you'd already solved all the issues in image search."
So then I backpedalled a bit and talked about the specs the museum had mentioned, "oh, well, they're just looking for search on some metadata". He replied, "well, maybe that's the only way they understand the problem, but you don't need to accept those limits".
And, as mentioned elsewhere, there's a big difference between writing an application or two and being involved in a larger software engineering effort.
| Learning to code is not hard. At all.
This assertion is empirically untrue in the market for programmers (if nothing else). Why are programmers paid as skilled laborers? How many not hard (at all), highly paid, and quite frankly cushy job exists? In the Bay, hiring is the biggest problem.
| how many teenagers can design a nuclear submarine?
Why is designing a nuclear submarine the point of comparison? Is this some sort of humble brag?
| That is much harder to learn.
No one claimed programming is the hardest job in the universe. It is perfectly possible for harder jobs to exist and for programming to be hard.
Just about every one I meant.
It isn't likely to work. But then I wonder how many teenagers could code a working control system for something like a nuclear submarine.
The concept of Ruby on Rails was to make the whole process of web site development a tutorial-level job from start to finish. How did that work out?
Once I was thrown into full stack development, I at least had something to lean on while the backend programming caught up with the frontend. Then I started applying the things I learned programming backend applications to frontend applications (where do I keep all this state?). I think I spent a lot of time in the desert of despair wrt. certain types of programming but was never entirely there.
I think it's important to have something to feel confident in while you struggle.