Ask HN: What did the really successful programmers do differently?

219 points by BadassFractal ↗ HN
This is a follow-up to the lengthy "Do you want to be doing this at 50" discussion that we've been having here on HN for the past week. For those of you who might have missed it:

http://news.ycombinator.com/item?id=4611337 http://news.ycombinator.com/item?id=4620276 http://news.ycombinator.com/item?id=4616635

As someone who is definitely on the path to be developing software for the rest of his life, I'm somewhat concerned. There are many anecdotes of programmers in their 50s having a pretty bad time, and yet there are real examples out there of programmers who have done phenomenally well: they've made a difference, they're well known and respected AND they've been financially successful as well.

I'm thinking of (contemporary) programmers of the caliber of John Carmack, Rich Hickey, Peter Norvig, Jeff Dean.. I'm trying to understand what it is that they did differently from everybody else that set them apart. I understand that many have been successful through their ventures (see Bill Joy or Eric Schmidt), is that perhaps the only route?

I think this is an interesting and valuable discussion for every developer out there.

177 comments

[ 3.9 ms ] story [ 129 ms ] thread
- Highly Driven - Highly focus
Yes, to say the least... I do not know what paved the way for all aforementioned programmers put after reading about Carmacks work in "Masters of Doom" I'd say focus is extremely important... And at least myself is extremely bad at it - there is always 10-ich projects going on... If you want success today I think being extremely specialized is a must.
It's not only about specializing yourself.

It's about knowing where you want to go, what you want to achieve, and be able to focus enough to go there. Vision + Execution.

For me focus is at the same time "fast and slow".

You have the focus on the long term vision of your career, products etc. That means, yeah, probably choose between your 10 projects. But again, it depends the goal you set yourself concerning those 10 projects. If you're a pragmatic OSS commiter ("I commit the changes to this lib' I really need for my main product"), then 10 projects is okay.

Then You have to focus, during your day to day work. Where do I head with this feature? What do I want to achieve? What problem am I trying to solve here? Did I think about all the edgy cases? Did I test everything? Is the code better now than before? etc.

It's hard work.

Be Driven, Be focus.

My guess is that they didn't waste energy by paying too much attention to blogging coder's rants.
They got lucky - they picked the right career and made the right choice enough times to still enjoy what they do decades later.
This is partly true, but mostly unhelpful.
Sure, but it's a generally unhelpful question I think. Most people aren't going to stay passionate about the same job, career, wife, husband, problems, solutions, whatever, for 50 years.

There is nothing you can do that will make you remain interested and excited and passionate about something for decades.

> I'm trying to understand what exactly they did from everybody else that set them apart.

Because I'm one of the success stories, I'm in a position to answer. A successful programmer is not just a programmer, he is also a personal representative, a salesman and a contract negotiator.

I originally wrote what became Apple Writer (http://en.wikipedia.org/wiki/Apple_Writer) because I was writing a technical magazine article that was difficult to organize. I finally realized I could use my newly acquired Apple II to organize my disorganized notes and help in editing. So I divided my time between writing the article (about Special Relativity) and programming my Apple II to help with the writing task. This meant I was the first user of my program, and I was a demanding customer, a factor that helped the project along.

Eventually Apple heard about my program (originally called LexiCalc, a name meant to remind people of VisiCalc) and, having far too few programs for their computer, asked to see my program. After a lengthy negotiation in which I demanded and secured a 25% royalty rate, we had a deal.

The bottom line -- Apple Writer didn't become a success only because of my programming skills. It became a success and a household name because I was able to negotiate a royalty marketing deal with Apple that served both our needs. The fact that a 25% royalty rate was excessive, was unknown to either me or Apple at the time of the original negotiation, and by the time we both realized it, I was unwilling to change the terms.

To reiterate, programmers that become successful do it by having skills beyond programming -- they know how to present themselves, they know how to negotiate, and they earn a reputation for reliability.

I think this is a common theme - technical people who also have business skills are more likely to succeed; business people who have technical skills are similarly more likely to succeed.
> business people who have technical skills are similarly more likely to succeed.

Yes, and business people and managers who have technical skill and knowledge possess the advantage that they can detect when programmers are lying to them or exaggerating, and they can schedule realistic programming project times. Nothing is worse than a manager in charge of programming projects who doesn't understand programming.

Absolutely. This is true in many fields, but I think particularly for the software industry. There are so many people in management positions who are clueless about what engineers and software can and can't do.
Or more generally: it's much easier to excel in the intersection of two (or three) disciplines than to excel in a single discipline.

Programming + Biology. Programming + Economics. Business + Comic book writing. Programming + Business. Cooking + fluency in Japanese & English. You get the idea.

This is a good point. I was thinking in terms of people in specialised roles having broader knowledge, but you are right that there are good opportunities in blended roles. Either way, it's great to have depth in multiple fields.
I think this is a common theme - technical people who also have business skills are more likely to succeed; business people who have technical skills are similarly more likely to succeed.

Exactly. I was fortunate enough to realize this early on in college. Since that realization I've always made the effort to straddle the tech and business side. Programmers, even average ones, have the ability to multiply business effort by orders of magnitude. Look around in any business and even today it's easy to find places were software can help.

> To reiterate, programmers that become successful do it by having skills beyond programming -- they know how to present themselves, they know how to negotiate, and they earn a reputation for reliability.

Apart from those, being able to build the right app at the right time helps too.

Very interesting, and thank you for sharing!

I think one could make several distinctions about "being successful" though:

* You're good at it, and you're still employed at 50.

* You strike it rich, so you can do whatever you want at 50.

From what you write here, you're in the second category. Given the odds of striking it rich though, I hope people post about type #1 programmers too.

Programmers in the first category should still be able to get a job if they can communicate their skill. Listing both old and new stuff (punch cards, Cobol, C systems programming, Java, Ruby, Python) always commands respect from me for a seasoned programmer. If they contribute to a current open-source project or have some free app on, it should be a no-brainer.
Yes, A perfect programmer is the one who can put himself at the end user level to demand features and the hero to deliver it on the other hand
One thing that I would like to point out is, being financially successful and extremely competent programmer are two different things. An example Zed Shaw is an extremely good programmer, but if you read his legendary rant "rails is ghetto" you come to know besides being an extremely great programmer he had to struggle financially.

So being a good programmer is not synonymous to having your bank accounts with decent zeroes following some non zero number.

Incidentally, yesterday I was talking to a programmer who had been coding for 17 years, he codes bots for games in C++ when not coding other stuff. He did not take his degree seriously, and today is looking for an MNC to hire him, so that he gets married, for the chic wants a secure life.

What did the good programmers do differently? Its a difficult question to answer. Having said that, couple of things are:

1. starting early

2. getting lucky

3. focus and hardwork

4. marketed themselves properly

5. surrounded themselves with better programmers, to get better at it.

6. capitalized on the opportunity of solving a tough and challenging problem.

ending on a pragmatic quote: passion burns out, what sustains is greed. (taken from "Do you want to be doing this at 50")

"Starting early", super important! "Getting lucky", yes - both in time and in income - striking gold is not much worth if you can not step up on the possibility - and sadly, for many, having kids or a ill parent, or loosing a steady income is to big a obstacle to tacle... Meaning, you might not have that many a year to live that, wild, frivolous, entreprenourish life...
Great post. I think there's a huge selection bias when someone drops the kind of names the OA did. All those guys had hugely visible successes, but it's hard to know how replicable any of that is. Given equal skill to Carmack or Hickey, I don't see a brilliant guy having a reasonable chance at writing the next Quake or Clojure. Those successes are black swans.

There are a lot of guys making $250k or more working on some obscure B2B product or enterprise team somewhere. Just because we don't hear about them doesn't mean they aren't just as happy or find as much meaning in their work, and it's certainly a lot easier to optimize for if that's what you want.

That said, I think programming is a bit like a professional athlete in that you can't have a great lifelong career by sticking purely to the technical aspects. You need to be learning how your skills apply to real businesses and building your network. Fortunately I think these things happen naturally to some extent, but it can't hurt to think about them.

> being financially successful and extremely competent programmer are two different things

I'm going far than this and say are two OPPOSITE things. Being good a 1 thing is hard. Good at 2 things? 3 things? Rare. That is way is easy to have Teslas, but not Bells...

I know a lot of developers in the latin america community, and mi city (www.clubdelphi.com). Here, is VERY rare to find the super-rich, mega-startup anomaly (yes, it is). We can do the hard work, have competent skills and still survive. I don't see highly tech people being good at the art of make money (the lack of social skills hurt a lot!), and the time necessary to code + doing business is a big drag.

I have a partner that help in the sales side. Without him, I can't see how I can code and get client in a steady way (the economic realities here are differente to USA: Have FACE TO FACE is DAMM IMPORTANT!, internet-only business? close to impossible), and I'm lucky for that. A lot of my peers are code monkeys, even the good ones...

I think great programmers are very much like other great people. To quote a cliche.. they stay hungry and foolish.
Many of those people have very individual approaches to development and are in a sense making massive contributions to the industry.

I'm not sure if you've heard about the concepts of Structure and Agency [0] in sociology? Consider the importance of: (1) being able to go off the beaten path to chase a new way of thinking/working or an idea which can improve many other people's lives, and (2) being in a company or position which gives an increase in high-value opportunities.

In any case, forget about just being a standard developer if you want to reach this level of impact. You own neither the platform on which you can reach a large group of people; nor the intellectual skill, anti-authoritarian outlook or vision required to create at a standard that sets you apart from your peers. There is something qualitatively different here from the careers of normal developers.

By the way, the ease of defining these qualities actually means it's not so hard to go about reaching them. If you can engineer software, you can engineer your career.

[0] http://en.wikipedia.org/wiki/Structure_and_agency

I am not talking about Linus Torvalds, Larry Walls etc of the world. But I am going to talk about other developers who often make it big. I am talking of people who solve difficult problems, add value and make money.

Great folks I've met are high on productivity, they are quick in discovering things and generally maintain an aura of self confidence around them. Many of them start off because they a 'lucky break' somewhere but they build on it, they work hard and make their own space.

When we are talking of successful guys out there. We are ideally talking of guys who are >40 now. I know a relative of mine highly successful 40+ guy. Some of the things that I've noticed is, he is insanely hardworking, nearing 50 he can give any 20 year old run for his money. He is productive, doesn't blog much, not very active on social media. Doesn't go gaga on small wins, he has great focus on picking and solving tough problems. I mean problems that can add real great value.

A few things that I've noticed is he is agnostic to tool religion. He goes by what helps him, rather than our usual religious tool affiliations. He is also very well organized.

So to add it up:

1. Work really hard, I mean I literally. No excuses on this point.

2. Focus on solving tough problems, adding value and things that matter. Learn and master things that can help you solve problems. But there is no such a thing called 'permanent' technology. You have to learn to move on, because tools help you solve the problems. They are not your problems you would want to solve. Unless selling tools is your business.

3. Technology matters, but that is only a enabler.

4. Be a little disciplined and organized.

5. Celebrate big wins, write and talk about them. Network with people just like you and surround yourself with smart people.

6. Work hard on opportunities and always keep a tab on your next move. The more opportunities you convert to finished work the more you get next.

> When we are talking of successful guys out there. We are ideally talking of guys who are >40 now. I know a relative of mine highly successful 40+ guy.

I like your post and this isn't meant as criticism, but ... could we not say "guy" so much? Women are often terrific programmers, and there should be more of them. But that goal is thwarted by a certain common assumption about who programmers are.

I don't post this with any sarcasm or to draw any inferences about your intended meaning, but just to bring to your attention that the point you've now raised struck me independently upon reading:

> A successful programmer is not just a programmer, he is also a personal representative, a salesman and a contract negotiator.

Yes, fair enough -- in that case, I had to either choose a gender for one word or go with one of those malaprops like "they".
That wouldn't have been a malaprop. A malaprop is a misused word that sounds like the correct word.
So it seems. I should perhaps have said "compromise word" or "PC word", alluding to the reason for the usage.
> 3. Technology matters, but that is only a enabler.

Yes! Just do things with the right tools.

I'd like to place myself in this category, even though I'm only 34. My claim to being successful is that I make much more money than I can spend (though we're not talking millions here) doing things I enjoy doing. I largely agree with you, but have some comments:

1. I think my best quality is that I'm lazy. Extremely lazy. Yet still very productive. I achieve this by thinking more about problems before I do anything, which usually greatly reduces the amount of work I actually have to do, because I come up with a better way of doing it. I'm extremely serious here; on a normal working day I'll likely spend more than 50% slacking. My clients don't care, they get charged only for the effective hours. And I love it, because the effective hours become so much more productive that I can charge a lot for them.

4. This matters a lot, especially in communicating to other stakeholders. Nothing is more annoying than someone who promises to do something by date X, only to not hear anything by then.

6. Extremely true. I talk to a lot of people to find work, and generally have a ratio of 10:1 for possible opportunities to things that actually lead to real work. I don't think I can improve this ratio much, because really interesting work is not that readily available.

I'm also not very active in the blogosphere and social media, mostly because that's simply not where my work comes from. My work comes mostly from business people and they care much more about recommendations, being able to talk to them in language they understand, etc.

Another question: How much luck was involved beyond making the necessary good choices? You can look at John Carmack or Peter Norvig and say that they made good choices X and Y and so on, but how much will this tell you about the prospects of a programmer who hasn't hit it big yet and who is doing all of X and Y? Worst case is, even though everyone who makes it to the top needs to have some qualities, successfully cultivating the qualities might still just get you from a 0 % chance to a 1 % chance at ending up successful.

I'm sure it's far from being that bad for programming, particularly if your main goal is to not end up miserable. Still, for every one John Carmack, I'm sure there are a 100 or a 1000 people as skilled and as hardworking, but who don't have the same amount of recognition.

They might have rather cushy jobs at some obscure R&D lab though. Which suggests a third question: What kind of people without widespread name recognition should we also be asking the "what did they do right" question about? It's easier to start thinking about John Carmack instead of Joe Q. Senior Systems Development Fellow, but that primes you for the somewhat wrong goal of trying to get massive name recognition in addition to the not ending up a miserable programmer one.

I like to think that successful people of all professions owe it to their methods (and then there is pure "luck" too). E.g., Seinfeld has been known to improve his skills on a daily basis, and is still able to deliver highly successful products (e.g., he wrote "Bee Movie", a surprise hit movie). Might be that his daily improvement has nothing to do with it, but you can never make much of anecdotes anyway. There is an app for that which I like to use: http://itunes.apple.com/us/app/commit/id473527073?mt=8

Einstein said something like "I owe many of my achievements to my persistence, not letting go of my goal until I achieve it" (Nash proved later that keeping to a strategy [= persistence] increases chances of winning a game), and Feynman has been known as a big advocate of the scientific method per se. Again, hard to say whether they owe their Nobel prizes to these methods, but I like to think that they helped.

Methods are actions gone habits. If you force yourself to think "Is this really right?" before coming to a conclusion, you will soon do it automatically. As a programmer, you could build up the habit of understanding the system you are currently operating in, before fixing or enhancing a part of it. Or you could write a pseudo-code script using your API (or testcases ;)) before implementing it, to get a grasp of what your users will actually use it for. You can make it a habit to blank out program areas in your mind which you don't currently need, to reduce cognitive load and turn a greater focus on the problem at hand (which will also enforce modularization automatically).

There are many such methods (also including getting more focus out of your worktime etc.), and they can become habits if you execute them for long enough. Habits are everywhere, and the (IMO) most crucial ones are hidden in how we think, and our thoughts eventually ensue our actions.

Practice is a good habit. I like to warm up in the mornings with a code-kata problem before I start my day. Just take a trivial problem and write a program to solve it. Take the same problem on another day and solve it a different way. Contrast the results of the two approaches. Think about which approach felt more natural, which one was most efficient, in what real-world cases would you choose one approach over the other... in other words, reflect. Practice without reflection is meaningless repetition.
I think that a big part of it is the quality of work you get. If you work on business apps that aren't very well appreciated and most of your time is spent maintaining projects where the decisions were already made, you're never going to get to that level. A couple scut projects early in your career can teach you things about maintenance and just why code quality is so important, but eventually, you need to graduate beyond that sort of thing and move to projects where you can learn from your own decisions.

Working with software is like poker. If you aren't playing with real money, it gets boring quickly. Programming is fun if you have "skin in the game"-- a decision where you want to see if it was the right one, a problem you want to solve-- and it's mind-numbingly boring if not.

You need, somehow, to ensure a reliable stream of high-quality work. You need to become that guy who moves from machine learning to self-driving cars to new language development while the unlucky saps are trying to swing from an HR app led by a Manager II to an HR app led by Manager III.

I don't want to trivialize this, because getting high-quality work is really fucking hard. There just isn't much of a budget for it, and usually getting the best work involves manipulating the politics, especially when you're young and not "obviously" qualified for it yet. Good work tends to be R&D stuff where up-or-out business people who will be promoted or gone in 4 years can't see the payoff. You often have to take a mercenary attitude toward transfers and job changes and, if your boss isn't personally interested in your career growth, balance out the universe by stealing an education. Most people learned how to program by doing something other than what they were supposed to do. This doesn't change when you become a professional programmer. Good programmers tend to put their own development over business goals-- "optimizing for learning"-- because otherwise, they wouldn't have become any good.

People talk about "5:01 developers", but I've started to think of myself as a "1/21 developer". I expect to grow the value of my programming skill set (and indirectly, my earning potential) by 1% every 21 days. It doesn't have to be coding only. Improving social skills or business knowledge can easily account for such an improvement. I make that rate of growth (more as metaphor and guideline than hard lower bound, because it's impossible to measure such a quantity precisely) an almost inflexible primary constraint, as important as (a) getting done what I'm told to do, (b) showing up on time, and (c) not being offensive at work. None of these get slack except in extreme circumstances, so why should my learning rate?

1 percent every 21 days might not seem like much-- it's incremental change as opposed to get-rich-quick bullshit-- but that's a doubling every 4 years, or a factor of 32 in two decades.

What I think is getting much harder is consistently putting yourself forward as a person who deserves the best projects. As the number of frameworks and languages increases, we're getting curse-of-dimensionality problems. Being seen as a good programmer (which is increasingly different from being one) is an artifact of terrain knowledge, these days, more than general competence. This makes political battles around tooling a lot nastier, because the stakes are so high.

I think the way out is, for now, to establish a credibility in something other than engineering-- statistics, business, design. Hence the X-Who-Programs vs. Just-A-Programmer phenomenon: http://michaelochurch.wordpress.com/2012/08/26/xwp-vs-jap/ . If you're a software engineer and nothing else, your place in the pecking order is unsafe because of tool-sensitivity, so you need to diversify into other areas of knowledge.

How do you quantify the 1% per 21 days improvment? There are no easy-to-get-at brain weight scales yet. I agree with your incremental change mindset, I just find it hard to measure.

An addition to your proposition that you needs make your decisions in order to improve: You also need to actively learn from your failures. Many people just go like "That sucks, it did not work out" without ever asking the Why. That's not enough to learn, and one could even learn the wrong lesson from a failure.

How do you quantify the 1% per 21 days improvment? There are no easy-to-get-at brain weight scales yet. I agree with your incremental change mindset, I just find it hard to measure.

Agreed. 21 days is a good audit point. If you can make the case to yourself that you've improved the total value of your skill set by 1 percent, then proceed normally.

This is equivalent to 19% per year. That's measurable if you pay attention to market trends. Keep in mind that if you stick with one job, you're likely to bank only half of that increment. You probably won't get 20% pay increases unless you work for yourself (in which case your expectancy might go up by 20%, but you have a lot of volatility). You'll get 6 to 10 percent per year. It might still be worth it to stay in the same job, if you feel like you're learning a lot. Part of the reason why the pay improvement is slower is that the best engineers tend to prefer more interesting work (and stability, as they get older) over aggressive salary growth.

Here's a scale for software engineering: http://michaelochurch.wordpress.com/2012/01/26/the-trajector... . Each 0.1 increment seems to be about a 26% increase in abstract business value (or a 10-fold increase per 1.0) and about an 8-15% increase in salary. You should be aiming for 0.1 every 18 months, which is hard but doable, although it usually requires pushing back at work sometimes.

An addition to your proposition that you needs make your decisions in order to improve: You also need to actively learn from your failures. Many people just go like "That sucks, it did not work out" without ever asking the Why. That's not enough to learn, and one could even learn the wrong lesson from a failure.

Absolutely. No disagreement there.

There are no really successful programmers. In a general sense: There are no really successful wage-earners. The only really successful people are business-people. That applies to just about every industry. No one is going to give you a billion dollars (or even a million) to sit at home or in an office and write code. No matter how beautiful and optimised and whatever other qualities you think code should have.

Unless you want to define "really successful" as really good (which is subjective) or popular and then the answer is obviously to be really good and make something popular. Oh and try to make sure to get the timing right. ;)

Break down what "success" means for you, then figure out how to achieve the really important parts of that formula.

For example, my cursory read of your list of programming success stories plus "they've made a difference, they're well known and respected" suggests that you might care about your status among geeks in particular. There's nothing wrong with that, but it would counsel very different career moves than if you cared about your status among "the typical person who reads the New York Times." You might, for example, aim your moves towards a high-status industry that skews geeky (like, say, videogames, which is across almost any other axis a terrible place to work), startups, advertising firms which employ anomalously high number of PhDs and get disproportionate love from geeks, etc etc, and away from where many extraordinarily talented programmers are likely to work (in a dark hole writing important code that the world will never know or care about even though it keeps their planes in the sky, moves their food to their table, makes sure that when they call 911 a phone actually rings, etc).

In terms of being financially successful? There are many, many approaches to it. Most of them boil down to figuring out how programming solves a problem for a business, quantifying that value, and then shaking the money tree.

I think HNers sometimes have an unnecessarily narrow view of the solution set: for values of financially successful which include "I don't need to be a billionaire but I'd sort of like to earn, I dunno, doctor money rather than marketing manager money" it includes things like "Run a small boutique consulting firm", "Become an individual specialist in a few very valuable things and just charge market rates for them", "Use your programming expertise to found a non-tech business and ROFLstomp on one core area of operations due to your unfair advantage", etc etc etc.

Pardon me for asking, what are your programming achievements, besides writing a long-length comments and blog posts?) Where could we see your code?
You're asking the wrong question. A better question would be "what have you achieved while being a programmer?".

Possible answer: Learning a skill that most programmers shy away from, are afraid of, or down-right scorn, thus giving me (him) an almost unfair advantage over virtually every other programmer out there.

Turning strings into strings, quoth the Turing machine.
You're showing your bias in that question. In the spectrum outlined in the post you're replying to, from valuing "really really good at writing code" to valuing "makes a ton of money as a result of applying a little bit of coding skill in the right direction", you appear to value the "good at coding" side of the equation.

If you read the comment you're replying to again, you might notice it to be written by somebody who lies towards the other end of the spectrum. As such, you might as well be asking him how much he bench presses, as it is equally relevant (as in, not at all so) to the utility of the advice he's giving.

He lives from selling his own software... isn't that quite an achievement in itself? Unfortunately, his software isn't open source so I don't think we'll get a chance to take a peek.
Patio11 makes some of his software, A/Bingo, available as open source. A/Bingo is a Ruby on Rails A/B testing framework, available at his Bingo card site.
The question you should be asking yourself is, why did patio11 make A/Bingo available as open source.

Clues:

1. It's called A/Bingo

2. It's hosted on his bingo card creator site, not on github or kalzumeus.com (his personal site)

3. People tend to link to interesting open source projects

4. The text they use in the link is usually the title of the project

5. Google uses the number of links and the link text to rank sites on keywords

This is what he means by using his coding skill against his competition in ways orthogonal to programming.

Ooh, that's clever.

And a little more greyhat than I've come to expect from patio11

Naming a project "A/Bingo" and hosting it on his own site is "grey hat"?
Naming it "A/Bingo" and hosting it on his own site?

Nah.

Naming it "A/Bingo" and hosting it on his own site for the intent of garnering linkjuice while at the same time presenting the name choice as simply a guileless, clever pun (as he does in his announcement of the project [1]) and within the context of his normal policy of broad disclosure?

A little bit. Perhaps "grey hat" is too strong a word. Swap in "a little discomfiting".

[1] http://www.kalzumeus.com/2009/08/15/introducing-abingo-rails...

(To clarify, my discomfort is due to the tying together of two orthogonal axes, ie, the quality of Bingo Card Creator as a result for the keyword "Bingo" and the quality of Bingo Card Creator as a source for an A/B testing framework.)

Um, "(The name sort of popped into my head and wouldn’t leave.  It is a pun, it relates to my business and personal brand, and it gives the impression of Hitting the Target that successful testing should give you. "

Please name a salesperson more open and honest than Patrick. Tell us who he should emulate. If people don't emulate Patrick's style, maybe they should follow Marc Pincus or Coffeefool instead?

I think perhaps Patrick didn't intentionally name it A/Bingo for the SEO, but he did understand the value OSS and link juice. If I thought of it, he certainly did -- but the name A/Bingo totally stands on its own as a really good name for this software in many ways.

http://www.jcdrepair.com/blog/your-business-has-more-to-offe...

Another example, and the one that inspired me, was one of the bloggers mentioned earlier. Patrick McKenzie runs a small, online business selling bingo cards to teachers (he sold over $45,000 worth of bingo cards in 2011). One thing Patrick does really well is search engine optimization (SEO). One of his techniques for getting people to link to his site (a big part of a high Google ranking), involves open source software. “What!?” That might be your reaction right now. What does open source software have to do with bingo cards for 1st graders?

The answer is nothing. However, Patrick is a software developer that wrote the code for his bingo card website. He recognized that some of the code he wrote was valuable all on its own. So he turned part of it into an open source Ruby on Rails project, put the code up on his site along with instructions on using it, and then told the world about it. What happened? All sorts of software developers, with no interest in bingo cards but a huge interest in his software, started linking to the portion of Patrick’s website that hosted this open source project. More links to his website meant a better ranking on Google which meant more sales of his bingo card creator. So while he didn’t directly sell his offering the way Amazon sold their’s, he did use it in a way that created more business for him.

You just asked a non-sequitur question. Patrick said, "consider carefully what you mean by success; one measure is geek status ranking, another is financial success". You responded by saying "show me your code" --- in other words, by implying that there is only geek status ranking, which makes no sense as a response.

When you grok what Patrick is doing, the programming angle on it makes more sense. On HN, he's best known for Bingo Card Creator (that's the work he has the easiest time talking about). Here is the right way to think about Bingo Card Creator: it is an experiment in how much engineering effort you can apply to marketing as opposed to product features and what the payoff on that is. The engineering in BCC is invisible to users; the product itself is "hello world", hooked up to a random number generator. The result of the experiment: he matched his salary with it, and then left his full-time development job, because 5-10 hours a week of effort was paying him better than the 60 he spent as a salaryman.

Also: get past the idea that you can gauge people's skills from their Github profiles. Nerds are in love with that idea because it sure would be nice if it were true. I've been a professional developer, mostly in C, since I was ~17 years old. Only a tiny fraction of the lines of code I've written --- and virtually none of my favorite lines --- are publishable on a site like Github.

It is not, of course, about github. It is much simpler. When some scientist met, say, mathematicians, it is very normal to ask - show me what you have done. Or the same thing with writers - Oh, you're writer? What did you wrote.

This thread was about programming, and the given comment was mere a self-assertion. So, it is OK to assert oneself if one wants to. But, show us, then, what you have done.

No. It is desirable that people contribute their answers to questions. It is undesirable for people to respond to those questions not by challenging the substance of the answer, but by questioning the respondent's standing to provide the answer. There is no "but, show us then". You have no status to demand that of anyone here.

I you have lots to say, for instance about modeling natural language as s-expressions, you too can write lots of long comments and blog posts, and we will enjoy reading them. Unlike the short, nasty one you wrote above.

Sure, I have no status, and I have no demands. What I like to do is to distinguish between people who can program and people who just can talk, to form my opinion on what I'm reading. Words are cheap.
Words are cheap if you quote someone else. Probably as you are doing Linus here. Not when they come from genuine experience of being in the wild. I think, we with a fair bit of experience can make a good judgment when we hear someone who doesn’t really knows what he’s saying.

Rest assured these guys here: http://news.ycombinator.com/leaders wouldn’t be there if they could not code. Most of them have detailed profiles for you to check out first, instead of asking them ‘show me the code’ on their every comment on HN.

Writers of novelists have their works publicly available. What about someone who writes documentation for the launch code for nuclear submarines? While I will probably never ever see that documentation, it's really important that it is done well.

A corporate lawyer may produce a whole bunch of excellent work that the outside world never sees. Yet he keeps the company complaint with regulations.

If we were to do "show me the github" for stonemasons, we would want to see the pretty works of art that someone has made and select for that. But what about the guy who worked for 20 years laying the stone to keep the buildings up? He can't show off his work. But if I work in his building every day, I'm going to care a lot more that he was selected based on his ability to choose the stone that keeps buildings up than on his art.

The majority of code never sees the light of day. We are much more like miners than mathematicians in that the public cannot see our immediate work product, only the results after it has worked as a team. If you've never been hired you obviously can have all of your stuff public, but that's just selecting against people who have worked.

Analogies are hard.

This is just a request for an argument from authority which is a form of logical fallacy: whether the opinion expressed is correct is not reliant on the skills of the person expressing the opinion.
A reading achievement would be to read his blog and understand the magnitude of what he has done.
They think differently.

Take a look at Smalltalk at Xerox PARC, AI lab and Scheme language at MIT, Plan9 at Bell Labs, Erlang at Ericsson, Go at Google, FreeBSD and OpenBSD projects, etc.

For an individual achievements - Linux 0.9, viaweb, arc, clisp, nginx, redis, sqlite, git, vi, emacs, etc.

Each particular story could be enough for learning almost everything about software engineering.

Erlang is a story of applied principles, methodology and design decisions - real-world functional programming success.

Plan9 is an example of what system programming really are, that less is really more and good is really enough.) Take a lot at src/lib

Arc is a prove of concept that lies in foundation of the "On Lisp" book - that you could evolve a language together with your software in a bottom-up process. And he did.

The story of Scheme language you could read in MIT AI memos, where, actually you could find all you need to know about programming.

Go is an example of how ideas form Plan9 and language design comes together in a unique language with unique features.

The evolution of the Lisp is another example. Systems should evolve.

There's a crucial difference between a good programmer and a successful one.

And the two aspects are certainly not mutually exclusive, and by that I mean: being a good programmer does not necessarily translate into being a successful programmer. The reverse is true too.

IMHO, to nurture a lasting career as a "programmer", you have to balance the two aspects. Be good and successful.

I think they stop being programmers and become solution engineers. The programming changes with the times but the ability to design and implement elegant solutions to a given problem is a timeless (and rare in terms of 'really successful') skill.

Or, so I think.

That's also one of the reasons why I don't like the title 'programmer' as opposed to something like 'software engineer'.

How to be an Excellent Programmer for Many Years

(Excellent==Successful. Money & fame are more difficult to control.)

1. Choose a small subset of available technology, learn it intimately, and embrace it. Then evolve that subset.

2. Understand the pros and cons of various data structures, both in memory and on disk.

3. Understand the pros and cons of various algorithms.

4. Understand your domain. Get away from your computer and do what your users do.

5. Be ready, willing, & able to deep dive multiple levels at any time. You must know what's going on under the hood. There is a strong correlation between "number of levels of deepness understood" and "programming prowess".

6. Use your imagination. Always be asking, "Is there a better way?" Think outside the quadralateral. The best solution may be one that's never been taken.

7. Good programmer: I optimize code. Better programmer: I structure data. Best programmer: What's the difference?

8. Structure your data properly. Any shortcomings there will cause endless techincal debt in your code.

9. Name things properly. Use "Verb-Adjective-Noun" for routines and functions. Variables should be long enough, short enough, and meaningful. If another programmer cannot understand your code, you haven't made it clear enough. In most cases, coding for the next programmer is more important than coding for the environment.

10. Decouple analysis from programming. They are not the same thing, require different personal resources, and should be done at different times and places. If you do both at the same time, you do neither well. (I like to conduct analysis without technology at the end of the day and start the next morning programming.)

11. Never use early exits. Never deploy the same code twice. Never name a variable a subset of another variable. You may not understand these rules and you may even want to debate them. But once you start doing them, it will force you to properly structure your code. These things are all crutches whose use causes junior programmers to remain junior.

12. Learn how to benchmark. Amazing what else you'll learn.

13. Learn the difference between a detail (doesn't really make that much difference) and an issue (can end the world). Focus only on issues.

14. Engage your user/customer/managers. Help them identify their "what". Their "how" is not nearly as important.

15. Write a framework, whether you ever plan to use it or not. You'll learn things you'll never learn any other way.

16. Teach others what you know, either in person or in writing. You'll accidently end up teaching yourself, too.

17. Always tell your customer/user "yes", even if you're not sure. 90% of the time, you'll find a way to do it. 10% of the time, you'll go back and apologize. Small price to pay for major personal growth.

18. Find someone else's code that does amazing things but is unintelligible. Refactor it. Then throw it away and promise yourself to never make the same mistakes they made. (You'll find plenty.)

19. Data always > theory or opinions. Learn the data by building stuff.

20. At some point, run your own business (service or product). You will learn things about programming that you'll never learn as an employee.

21. If you don't love your job, find another one.

> 17. Always tell your customer/user "yes", even if you're not sure.

I have found that you get higher marks for saying NO in the right occasions than being known as the one that always says YES.

There's clearly a middle position to be had here. By saying NO if you're not completely confident you can do something, you miss out on the best learning opportunities. That said, if you suspect something cannot work, or isn't the right way of doing something for another possibly non-technical reason, being prepared to say NO is critical for delivering.

So possibly: If you always say NO, you never learn anything. If you always say YES, you never deliver anything.

That's a good way of putting it.
It's important to also put either answer in the context of how it will affect the Time, Cost and Quality Triangle of program management. The customer loves to hear 'yes' but sometimes don't realize that that 'yes' is going to typically mean more time and/or money.
Learning to say no is the biggest challenge and virtue of the best developers out there. It's not a "no I can't do it" it's more of a "no I can't do it in that time" or "no I don't think it's the right way to go, here is how I think we should do it". Saying NO can make a difference between a successful project and a nightmare.
Could you please elaborate on No. 11?

"Never use early exits". Could you please elaborate what you mean by that?

PS. I'm not trying to unintentionally start a flame war. Just trying to understand.

I'm glad you asked, I have the same question exactly.
I believe he referred to the rule to use a single return statement at the end of any single function definition.
Excellent question that is difficult to answer. I'll give you a short response here and then write a blog post with example code when I have time. Put your email in your profile and I'll make sure to let you know when that's ready.

A little background: I have gotten many calls when legacy code has a bug or needs a critical enhancement and no one in-house is willing or able to figure it out. I'm no smarter than anyone else, but because I'm stupid and fearless, I often do something that few others attempt: I rewrite or refactor the code first, then work on the bug/enhancement. And the first thing I always do is look for early exits. This has always given me the most bang for my buck in making unintelligible code understandable. The only entry to any function or subroutine should be on the first line and the only exit should be on the last line.

This is never about what runs fastest or produces less lines of code. It's strictly about making life easier for the next programmer.

Early exits can make things really easy (I'll just get out now.) 20 lines of clean code. No problem. Until years later, when that function is 300 lines long, and the next programmer can't figure out what you're doing. Much of the maintenance had been done in emergency mode, each programmer just trying to get in and out as fast as they could.

Early exits make it much easier for bad things to evolve:

  - 200 line multiple nested if statements
  - 200 line multiple nested recursions
  - unidentified but critical "modes" (add/change) (found/notFound)...
Removing early exits forces you to understand what really should be happening and enables you to structure code into smaller, more intelligible pieces.

Short, hand-wavy response, but I hope that helps clarify some. Stay tuned for a better answer...

I'm not sure if I would agree on this. Take for example the Linux kernel. You have basically early exits just everywhere. Take any random file from here: http://git.kernel.org/?p=linux/kernel/git/stable/linux-stabl...

It often goes like this:

  check if we have already done this or so -> exit
  check if this is possible to do. if not -> exit
  do some first thing. on error -> exit
  do some other thing. on error -> exit
  ...
(comment deleted)
He also said his statement "This is never about what runs fastest...". Kernel code needs to run fast and take advantage of shortcuts.

IME, the jobs most programmers are doing don't need to try to accomplish maximum speed or need to wring a few bytes out of RAM. Certainly we don't want to be wasteful, but long-term maintainability is more important, again IME, than absolute speed or minimising memory footprint by a few (k) bytes.

Back in the bad old days when I was writing programs to run on mainframes, yeah, we did need to fight for every byte. A $5 million machine back then had less RAM and less raw CPU power than a tablet does today. We don't live in that world now.

> He also said his statement "This is never about what runs fastest...".

This style has nothing to do with running fast, it has to do with lowering the cognitive load of the rest of the function. A branch means you have two states to keep in mind (the state where the branch is taken, and the state where the branch is not taken). Without early exit, you have to keep both states in mind until the end of the function just in case.

With guard clauses, you can discard on of the states (the one which matched the clause) entirely.

Computers can do that repeatedly and reliably with even (hundreds of) thousands of discarded states. People reading code and trying to understand what's actually in play at line umptyfratz of function iGottaGetThisFixedNow(), not so much.

In the end, I'm not disagreeing with early exits per se, just that over time they can make it more difficult to understand function because assumptions about state have to adjust as a maintainer goes through the code. Those assumptions may have been crystal-clear to the writer originally but how many times is the original writer the only maintainer?

But, a computer scientist once argued, multiple returns are structured: they return to the same point. Knuth wrote an article on structured programming with GOTOs, and pointed out that this can save memory.
> when that function is 300 lines long

This is what I would focus on avoiding instead.

What if you fail on line 20? Carrying on may cause cascading errors, what alternatives are there to return an error code directly apart from storing a return value in a variable, use a goto to the end and return once? (assuming this is C)
Also early exits are the exact same things as GOTOs. It equals to:

  goto end;
  ...
  end:
It should help people figure out why it's bad - in 99.99% of the cases.
I believe early exit is strictly better than `goto end`. There's no language enforcement requiring the "end" label to be at the end of the function. If there was, I wouldn't mind the use of `goto end`. I don't think your argument is persuasive to anyone who doesn't already agree with you.
(comment deleted)
I think you misunderstand why goto's are frowned upon. Goto's are bad because they allows you to jump to anywhere in the code, regardless of structure, which undermines all assumptions you can make about control flow.

Function calls and return are like goto that obeys structure, and therefore don't have the same problems.

(comment deleted)
(comment deleted)
Goto's are bad because they allows you to jump to anywhere in the code, regardless of structure, which undermines all assumptions you can make about control flow.

Knowing where you are jumping doesn't help you to make assumptions about the control flow.

Goto's are bad because they allows you to jump. The jump in itself is the problem because it breaks the instruction flow arbitrarily - without explicitly expressing the boolean condition for it. Early exits are of the same kind: they don't express explicitly the boolean condition of the jump. We know where we are jumping. Not why. With time, the boolean equation of the code which determines the instruction flow is unmaintainable. And then you end up not understand where your flow is going through, not because you don't know where a jump is going, but because you have lost why.

Most gotos, early returns, breaks and continues (C speaking) are considered to be bad habits for this reason.

return only goal is to return values to the function caller. Not to jump.

Function calls jump back to whatever call them so it's like there has been no jump at all in terms of instruction flow - you basically can continue to read the code assuming some code has been executed behind the function name.

While loops are the exact same thing as GOTOs. It equals to:

    start:
    if(!p) goto end
    ...
    goto start;
    end:
It should help people figure out why it's bad - in 99.99% of the cases ;)
(comment deleted)
A loop is based on a conditional jump (aka. a flow control statement in imperative langs) which makes all the difference. The problem with jumps (is usually called a jump, purely arbitrary jump) is that they are arbitrary: http://news.ycombinator.com/item?id=4627730
How do know what happens at an end-brace? Have to go look at the matching start-brace to see if it is a while or for or if. Madness! Can I assume the code above even executed once? No! What of I check the guard clause first? It has variables! Oh heavens, control flow depends on arbitrary RUNTIME data!?
> And the first thing I always do is look for early exits. This has always given me the most bang for my buck in making unintelligible code understandable.

Ouch. It will be kind of amusing if we ever work on the same code - I frequently start a bug fix by refactoring to introduce as many early exits as possible. I find guard clauses so much easier to understand than nested conditionals that sometimes refactoring it like this is the only way I can understand the code at all. I would love to see a blog post where you compare different styles.

OTOH, If you're talking about things other than guard clauses then I think we might have a much more similar viewpoint.

I disagree because I find that it makes my code more elegant. A lot of smart developers I respect have also embraced early exits. But then again I haven't yet worked with large legacy codebases.

I'm still learning so I'd be grateful for a heads up if you make that blog post. I've put my email in my hn profile.

I think the biggest problem is that early exits make you forget you have to clean things up before returning (a bigger problem in C and sometimes Java, than it is in modern dynamic languages). There are certainly other reasons, but I'll leave them to others that are more experienced!
Indeed. I have found "guard clauses" with return/error at top of function to be clearer and less error prone.
Thoughtful, elaborate comments like this are why I read HN. Thanks, ed.
Great comment. But aren't 7 and 8 kinda at odds with each other? I understand that #7 is a bit hyperbole, but still...
The best programmer in #8 already did #7. So he never had to write a lot of code to handle poorly structured data. That's why he says, "What's the difference?"
Oh, now I get it. When reading #7 I got the impression that you were dismissing the so called micro-optimization - something along the lines of "ship early, fix things later. Don't get stuck over-engineering and delaying writing code".
I think that 7 and 8 are actually saying the same thing. #7 is saying that structuring your data correctly is optimization, and #8 is directly telling you to structure your data well.
> 11. Never use early exits.

As a general piece of advice, this is flat out wrong. Or, to put it more correctly, this is only valid advice when using certain languages and only under certain conditions. Just because it is sound advice in languages with C/C++ derived syntax doesn't mean it should be presented as good advice in general.

Why do you think it is bad for C? Take for example the Linux kernel where you find early exits basically everywhere. (See also my other response here: http://news.ycombinator.com/item?id=4626763)

Even less bad in C++ where destructors can automatically handle any cleanup (exactly that is also common practice in C++; making the cleanup implicit). Similarly in many other more high level languages with GC and/or automatic refcounting or so.

In rare cases, it might be more complicated, though.

But you seem to have some languages in mind where it really doesn't matter? What languages?

Well, most early returns are avoided mostly because it makes it harder to understand the code. But when you use guard clauses, like on your Linux Kernel example, you actually improve the code, because you reduce cyclomatic complexity (everything is now a linear path: a -> b -> c), you can reduce nesting, you can avoid unnecessary mutable state... so it's a win. The problem with early returns is when you use them in non-obvious places.

I believe that the majority of programmers agrees that using early returns for guard clauses is an okay exception.

Yes, I think really "avoid early returns" is an overextended special case of "avoid the nonobvious".
Exactly.

Also, for example, when you have lots of "if" clauses, those languages force us to use mutable state (and a variable initialized as null) just to avoid early exits. But we can avoid both by treating the "if" as an expression, as in Ruby, Lisp, etc, or with the ternary conditional operator...

Plus, IMO, there are some situations where early exits are a good idea even in languages derived from C, such as with guard clauses/preconditions.

There's a nice discussion about that here with some points I made: http://c2.com/cgi/wiki?SingleFunctionExitPoint

(EDIT: I edited a lot but still couldn't make it clear that I agree with you, but I still ended up making points about completely different things, sorry about that, my english skills are lacking sometimes)

I understand why not to use early exits. But what's wrong with early returns?
Huh? You _want_ early exits in c code how else will the compiler optimize?
> 18. Find someone else's code that does amazing things but is unintelligible. Refactor it. Then throw it away

Throw away the unintelligible code, or throw away the refactor?

Always ignore advice that begins with the word "always". The use of "never" is never a good sign either.
Wahh, I'm caught in a recursion. halp.
Case-distinction-man to the rescue
Only Sith deal in absolutes!
I bet you could turn that into a profitable book. HyperInk?
> 13. Learn the difference between a detail (doesn't really make that much difference) and an issue (can end the world). Focus only on issues.

Good advice. So why do you give the same amount of attention to variable naming and early exits as to much higher level issues? I don't think the difference between Carmack and a random developer has much to do with adherence to coding standards.

Variable naming and early exits are not details. They are fundamental issues, two of the most common causes of shitty code. Most programmers don't understand how important they are and relegate them to the pile of "coding standards" or just want to debate their theroetical pros and cons. Just look at what's happened to this thread.
I think you should heed your own (quite excellent) advice. In this case the real issue is how to best structure code for readability, maintainability, and fewer errors. Things like naming conventions and module structure are the details by which we accomplish these higher goals. Don't get too hung up on doing things one way or the other -- focus on what you're trying to achieve.
Great list Ed.

About #17, one of my clients once told me he hired and kept me because I never outright, or in the beginning said no, and instead said 'let me think about it', or 'anything is possible relative to time and money'.

As guides to implementing technology, I think this is a fundamental skill.

19. Data always > theory or opinions. Learn the data by building stuff.

This is not true.

It depends on how much data you can get and how representative it is.

A big mistake is to assume that an unrepresentative sample of data is representative, and to draw conclusions based on that assumption.

If you do not have a representative set of data (and you can't always get one) then data can be less-than "theory or opinions".

And to add to that: one can easily misinterpret (or even just mismeasure) data, especially if it is data about a complex system.
If we are in a situation where we are unable to collect the data in the first place and you propose that theories or opinions are better, from what place did these putatively superior data or opinions come from? Because they clearly aren't coming from data.
Leveraging the experience of many? I wan't my website to be fast. I don't have deep understanding on web optimization and don't have yet enough data or time to build my own solution. I search around in the web, and go to http://developer.yahoo.com/performance/rules.html. I trust them (yahoo) because them are probably more competent and have MORE DATA than me. I implement some of the ideas, get some results (and if I'm smart, get a clue on why are good ideas and how it affect the performance).

Acting in data IMHO is only if have LOT of data. If not, acting in expertise of others look best to me..

If we are in a situation where we are unable to collect the data in the first place

that's mischaracterising my point. I didn't say anything about having no data. I talked about when the data you're able to get is unrepresentative.

from what place did these putatively superior data or opinions come from? Because they clearly aren't coming from data.

i think that's just playing word games with "data". We're talking about data concerning the problem at hand. Theories may come from data, but they don't come from data you obtain about the problem at hand. And knowledge can come from experience, which again is a form of data, but clearly not the sort the person was talking about. You can reason based on knowledge and principles.

Sure, it'd be better if you had good data, but when you can't have that sometimes the best you can do is to reason based on knowledge/experience/theoretical ideas.

When you advise against naming a variable a subset of another variable, are you talking about confusing names, or practices like breaking off a chunk of array to process instead of finding a smarter way to step through it like mapping or in-place logic?
No, just variable naming.

As we speak, I'm maintaining some old code with the following variables names:

  - CommandRec
  - Command
  - Comm
  - Com
along with the fact that some of these are reused for different purposes and all are global.

I'm having a hell of a time finding all instances to rename them properly.

I understand that some programmer interfaces are better than others hanlding this, but that belies my main point:

"Just name shit what it really is."

Awful names for sure. In Java and with Intellij IDEA for example, renmaing variables is a breeze, with a text editor much harder.
If only the programmer had the sense to name them in a style-compliant way

Cmnd

Cmd

Command

RecCommand

Command

(Couldn't resist that last one)

"Never use early exits" is tantamount to saying "never study programming languages deeply enough to understand control-flow graphs". That's not simply a good rule of thumb, it's a terrifying omission. I would suggest that early exists are simply a matter of taste and never using them is the crutch that keeps junior developers junior.

Data are on my side here: a quick perusal of the Quake 3, the Linux kernel, the Clojure runtime, and LevelDB show that Carmack, Torvalds, Hickey, and Dean all use them where appropriate.

That one caught me up too. Maybe if you have full control of the input data and performance is not a concern, then they should be avoided, but "never" is a pretty small set.
Specifically try to judge whether an "early exit" leads to simpler, more maintainable code in this particular case. Optimize for lower cost, not for just following a rule.
Agreed. A lot of the time, early exits just make sense. Instead of holding a variable called "succeeded" and doing a bunch of if elses, why not just continue on every failure? You're only testing for half a dozen side-cases and just exit out early when you encounter any one. No need to wrap all of your actual work in 5 levels of if elses.
Although 'never' is a very hard word, I found that in real live most code that uses early exists simply breaks SRP (come to think of it 99% of the time that is the case)

I know people will say "but I will only write this little return statement here" before you know it you will "add this little assignment before it returns" ...

Never might be strong but it make a very good point.

And Never let someone tell you that you're 'junior' and they know better. Rules were made to be broken.
"Never use early exits" is exceedingly bad advice, in my experience. What has led up to your claim that early exits are bad? As I've gained experience, I find myself writing code like this more and more:

    if (UnexpectedOrUnhandledCondition(x)) {
      ...
      return false;
    }

    if (OtherError(y)) {
      return false;
    }
and so on. Serial code like that is trivially easy to understand when reading; more importantly, six months later, it's far more explicit and easier to comprehend than the comparable single-exit version.

The alternative to early exits is nesting, and nesting is the readability killer. My experience has apparently been just the opposite of yours: that avoiding early exits is a sign of a junior programmer, and returning early whenever possible is a sign of an experienced programmer who knows that understands code maintenance.

I agree. The alternative as you state is nested conditionals. Yuck! An alternative construct I have seen and used is to wrap code in a do {} unless(0) block and break to a single failure return or complete the block to a single success return.
well worth the read. thanks!
I can't wait to read the responses, but before I do I'm going to throw out my theory. Some people keep their physical health going, and some don't. I'm not talking about going jogging, but rather metabolism, toxin accumulation, brain function, etc.
You've picked the rare few outrageously smart and successful as examples. This is like asking, how can I have a career in music like The Beatles, Michael Jackson and Elvis?
But it's still useful to understand what made them successfull. People do biographical research, write huge biography books, and read them for this exact reason. In the case of Beatles, for example, it is widely believed that it's their time in Hamburg, when they were playing every single day for hours non-stop, that was crucial to their formation as star musicians.
Programming is a tool to solve a problem.

Focus on hard problems and you will end up using and developing the right tools to solve them. By focusing on hard problems, you will naturally stay up-to-date with companies looking for your expertise.

There are plenty of things a "great" engineer does differently, but to be "as successful" as those you've cited, you need more than that. There are 1.5M software engineers in the U.S. Your examples are probably in the top 1000--that's the top 0.1 percent (i.e. 0.001 of the total). To get there you need high cognitive capacity, hard work, and an extreme amount of luck. That said, you can increase your luck my examining macrotrends in the industry.

But what do I know--I'm not as successful as those guys, nor is anyone posting here, so we're all just pontificating because we like to hear ourselves talk. Don't lean too much on advice from anyone less successful (or as successful) than you.

(comment deleted)
"We are prone to overestimate how much we understand about the world and to underestimate the role of chance in events." -- Daniel Kahneman. Thinking, Fast and Slow.

I returned, and saw under the sun, that the race is not to the swift, nor the battle to the strong, neither yet bread to the wise, nor yet riches to men of understanding, nor yet favour to men of skill; but time and chance happeneth to them all. -- Ecclesiastes 9:11