How To Learn Hacking: Version 1.1

I had meant to blog-announce version 1.0 of How To Learn Hacking but got distracted at a crucial moment. So it went out on G+, where I got some useful feedback.

This version is revised and very slightly expanded. Enjoy and critique.

Published
Categorized as General

38 comments

  1. Heh. I read version 1.0 and enjoyed it. (I discovered it through your G+ page. :-P) But I noticed an error that is still present in 1.1: the link to “How to Become a Hacker” contains “catb.orgs”, so it doesn’t work.

  2. Any hints on how to find managable, but non-boring, problems when the problems that immediately attract your interest are significantly over your head? I tend to gravitate towards system programming, and the kinds of programs I’m interested in hacking on are well outside of the 100-500 line range (or even the 1k-5k range), and the types of features I’d find interesting to add are probably in the 1k-5k line range at a minimum (adding significant architectural features to Linux), and/or involve working with ancient proprietary APIs covered by little or no online literature and little or no recent literature (writing a driver layer for Win 3.x to improve its functionality on DOSBox and FreeDOS, probably motivated more by nostalgia for the system I grew up on than by good sense).

  3. Weird, I’m not sure what landed that in the moderation queue. This post and the following constitute an experiment.

  4. The previous post was a control for the experiment. This post is to test whether the word “hacking” lands a post in the moderation queue. I’ll include it unquoted for good measure:

    …the kinds of programs I’m interested in hacking on are well outside of the 100-500 line range…

  5. I think you should consider striking the words “an above average talent for programming and” from the second paragraph. True as they may be, the Dunning-Kruger effect coupled with this essay’s intended audience of rank beginners suggests to me that those words are likely to turn away exactly the people most likely to benefit from the advice.

    I also have to disagree with the implication that NetHack would be a good place for a beginner to start; yes, it’s an extant and still-popular text-based game, but it’s one with a rather gnarly codebase, especially if we’re talking about vanilla NetHack. NetHack4 cleans it up a lot, but there’s still lots of ugly that hasn’t been ripped out yet. By contrast, while I’ve never looked at the Angband code myself, modern Angband has a reputation for an exceptionally clean and well-organized codebase.

    Those are quibbles, though; while I am not myself a hacker, the document describes a lot of my own experience astonishingly well.

  6. Why can’t this just be a new section in the How to become a hacker HOWTO? It could be placed after the section on basic hacking skils. Yes, properly stated, you aren’t a “hacker” until other hackers call you one, but the Hacker-HOWTO makes this quite clear already.

  7. > Similarly, writing toy programs doesn’t tend to teach you
    > much about hacking, and (b) will tend to de-motivate you
    > unless the program solves a problem you care about.

    This could maybe be emphasized differently. Toy problems bereft of purpose suck, but I think that if you *do* have a small program in mind that solves a problem you care about, it’s an extremely efficient, high-feedback way to learn the basics. Having a program you wrote that you actually use on a day-to-day basis is motivating as hell.

    Something not mentioned that might be helpful: It’s good to know someone who’s already a skilled programmer, even if they’re not directly tutoring you, because they can say “yeah, this thing you have in mind is much harder than you think it is.” A beginner may not notice when they’re about to run in to something like this: http://xkcd.com/1425/

    The software release howto link probably meant to go to http://www.linuxdoc.org/HOWTO/Software-Release-Practice-HOWTO/index.html, rather than the directory listing.

  8. Maybe not appropriate in this HOWTO, but learning a few UNIX tools (ls, cat, grep, find, xargs, head, tail, etc.) Are really helpful in finding your way about unfamiliar code. I find that awk and sed can also be useful, but their terse and quirky command structure is hard to learn and remember. Sometimes it’s just easier to write a short Python script to do the job.

  9. Also, scripting (be it shell, Python + PyPI, Perl + CPAN, …). For example renaming MP3 according to ID3 info (even if you can do this with GUI tools such as EasyTag), or solve Mastermind-like puzzle for game, or backup files, or convert all OGG to MP3, etc.

  10. @ dtsund

    I think you should consider striking the words “an above average talent for programming and” from the second paragraph. True as they may be, the Dunning-Kruger … [is] likely to turn away exactly the people most likely to benefit from the advice.

    From Wikipedia…

    The Dunning–Kruger effect is a cognitive bias whereby unskilled individuals suffer from illusory superiority, mistakenly rating their ability much higher than is accurate. […]

    So, I don’t understand what you are trying to say. If a rank beginner has just enough experience with programming to know that “Lather, Rinse, Repeat” is a silly program, and that person overestimates his/her competence, it seems to me that that would encourage the person to continue programming and trying to learn more.

  11. I like your essay as is. In addition, I’d be interested in reading a section at the end that would close the loop with the beginning: Once the readers of your essay can hack on an intermediate level, it’s time for them to think about the hackability of their hacks by the next immigrants to the land of hacking. As you say, hacking as a style of development usually happens on open source, meaning that the hacks themselves are likely to get published at some point. So what can intermediate and guru programmers do to make their code pleasant and interesting for the newcomers to read, explore, and tinker with?

    I imagine you have a lot to say about that, because even as a casual reader of your code, I notice you must have put a lot of thought into it. Your comments are fun to read whether I look at the code or not. When I do read your code, I usually don’t understand the details, but the outline makes sense even without reading the comments. And if I was to get sucked in deeply enough, I’m pretty sure I would discover further efforts of yours to make even the fiddly details intelligible and modifiable.

    Many other projects I’ve read code from aren’t like that. To the contrary, they often seem to prefer obscurantist idioms so that novices with their annoying questions leave the mavens alone questions. Your code, by contrast, reads as if you want mortals to read, understand, and change it. And I’d like to read how you practice and develop this facet in your sense of coding style.

    I won’t be so arrogant as to write a specification for such a hacking for hackability section. But my general idea would be to imagine The Design of Design by Fred Brooks having sex with The Evolution of Evolvability by Richard Dawkins. Brooks’s essays offers interesting insights into software design, but presume that software design is the top-down, intelligent-design-type process that it no doubt used to be at his employer, IBM. Dawkins, on the other hand, talks about how some embryologies make it easier than others for genes to produce adaptive modifications quickly. He also speculates how natural selection might favor more evolvable embryologies over less evolvable ones. But Dawkins talks about biological embryos, not software embryos — hence the need for sex between his essay and Brooks’s.

  12. The howto links should point to their respective pages at The Linux Documentation Project.
    http://www.tldp.org/HOWTO/Unix-and-Internet-Fundamentals-HOWTO/index.html
    http://www.tldp.org/HOWTO/Software-Release-Practice-HOWTO/index.html

    I found the free book “The Linux Command Line” by William Shotts to be extremely helpful in getting acquainted with Linux. Huge piles of howtos and man pages can be confusing for a beginner because there’s no predefined path of what to read, where to find it and when to stop. This book can be read from start to finish and will provide a solid foundation on which a beginner can start building and exploring. Maybe you can include a link to it:
    http://linuxcommand.org/tlcl.php

  13. @Brian Marshall

    What I’m saying is that rank beginners with actual talent are more likely to be keenly aware of their own limitations, and think to themselves things like “I don’t know anything about writing graphical interfaces, or network code, or threads, or $TOPIC”, and mentally conflate this with a lack of talent. Beginners *without* talent may be more prone to think along the lines of “Yeah, I can totally rock a while loop, given enough time and a few hints”.

  14. @ Thomas Blankenhorn

    I think hacking for hackability is a result of what esr calls “design sense” or the metafore of having an ear for music. This is an appreciation for “elegant” code – code that is simple (or simple as can be) so that if you understand what it is trying to do, you can see how the code works.

    Good code implements a deep understanding of the problem to be solved. Higher-level organization and operation, as well as operation details are all separate and as simple as the problem permits; this is true of a program as a whole, a function and even blocks of code. Of course, the best way to get a deep understanding of the problem is to write the code. As Bjarne Stroustrup said…

    “To write a good program takes intelligence, taste and patience.”

  15. ‘course, some problems have nasty complications and special cases. You want code to be as simple as possible. A primary principle is that special cases should be dealt with explicitly and visibly. Cleverness that results in edge cases being handled correctly as side-effects of the particular way the code is written shoud to be strongly avoided. However…. What follows is my impression and I invite comment (note: I have never seen version control code)…

    In extreme cases, like verion control, you get two things going on… If every odd case was dealt with in an explicit and obvious way, the code would bloat so that readability would suffer as generally simple operations are spread though larger amounts of code. More cleverness is acceptable. Secondly, odd cases keep beeing discovered long after the initial code is written, and the code accumulates tweaks. This can be fixed by refactoring, but the more accumulates tweaks, the harder it is for anyone to understand it well enough to refactor it.

    So… as a first approximation, code should always be written for the benefit of the human reader; let the optimizer make the code fast. All those special cases should be handled in an explicit and visible way.

  16. me, from memory > Brooks’s essays offers interesting insights into software design, but presume that software design is the top-down, intelligent-design-type process that it no doubt used to be at his employer, IBM.

    On pulling the book out of my shelf, I notice that Brooks’s discussion of evolving designs is more extensive as well as more sympathetic than I remembered.

  17. @ dtsund

    …graphical interfaces, or network code, or threads, or $TOPIC. …”

    esr’s howto describes a way of initially learning by working on small parts of existing code. It effectively tells people “It’s okay to ignore all those other complications – just focus on a small part that interests you.”

  18. Brian Marshal> Good code implements a deep understanding of the problem to be solved.

    I agree. But it’s one step to learn to write code that implements your deep understanding of the problem. I suspect it’s a separate step to learn to write code that readers enjoy reading enough to stick with it, that helps them clarify their own understanding of the problem, and that encourages them to modify your code according to their own understanding once they’ve gained it.

    I suspect this because, in my limited reading experience, Eric’s code is really good at this whereas the code of other, perfectly well-respected open-source hackers is obscure to me.

    If my suspicion is right, I’d like to read about this extra step — both for its own sake and because I have a personal aesthetic attachment to essays whose ends circle back to the beginning. Your response makes sense, and so does everything in the current version of Eric’s essay. I’m just throwing out my immediate reaction to reading it because Eric asked for feedback.

    1. >I suspect this because, in my limited reading experience, Eric’s code is really good at this whereas the code of other, perfectly well-respected open-source hackers is obscure to me.

      I know why and how I do this. I don’t know why other hackers don’t. Perhaps they don’t take the idea that source code is a form of communication with other humans seriously enough. I always have it in mind when I write.

      You can see the practices I use for this particularly well in some of the single-file projects that I originated myself; SRC, reposurgeon, and irker are good recent examples. Among these practices are:

      1. A roadmap comment at the head of the file. My goal is that by the time another hacker finishes reading it, he should have some feel for the architecture and (important!) what the tricky bits are and why they’re tricky.

      2. Defining things in a readable order. I take the trouble to build small, easily-grasped abstractions first. Each is a building block for stuff happening further on in the file.

      3. Choosing informative names carefully.

      4. Writing comments at a useful level of abstraction – tied to what’s immediately around them but usually from a view one level up (ideally, no further up) in the architecture of the code.

      5. Using humor to keep the code-reading process from being utterly dry and boring.

  19. I think your metrics (> 1000 lines of code for bare competence) can seriously mislead the youngsters. Yes, if you are scraping rust out of ossified software (like EMACS ( know, I’m just disposed to dislike it)). Then you are a real EMACS hacker, for whatever social good that does.

    Long ago I did major money transfer software for a big bank. Maybe 15-20K lines of IBM S/360 assembly code (most of which I inherited from my mentor). That did not begin to improve the bank’s business like the 50 lines of code for the SWIFT zaps and macros for the IBM 3705.

    In that use case, I learned the 3705, and S/360 multiplexer channel from the iron up, and it paid off. The thousands of lines of code are mostly not relevant. Understanding the problem, the environment and the politics are more relevant.

  20. “the association between hacking and Unix was less strong”
    Because “strong” and its antonym “weak” have “-er” and “-est” forms, the use of more/less and most/least violates a grammar rule and will thus be considered substandard English by people who care about such things.

    “the association between hacking and Unix was weaker

    I suspect that you chose not to use that construct so as not to imply that the association was “weak” in some absolute sense, but that’s really not how comparatives work. The sort of people who think, for instance, that the statement “Bobby Fischer is a weaker chess player than Garry Kasparov” in any way implies that Fischer is a weak chess player will never be hackers.

  21. > 2. Defining things in a readable order. I take the trouble to build small, easily-grasped abstractions first. Each is a building block for stuff happening further on in the file.

    How well does this intersect with some people’s C coding practice of avoiding forward declarations unless it is impossible to do so (i.e. each function is defined after all the functions/objects it calls, unless a cycle prevents this)?

    1. >How well does this intersect with some people’s C coding practice of avoiding forward declarations unless it is impossible to do so

      Pretty well. Genrerally if function B needs the prototype for function A, it means B is built on A in the narrative order I’d want to write them in anyway.

  22. @The Monster:
    >Because “strong” and its antonym “weak” have “-er” and “-est” forms, the use of more/less and most/least violates a grammar rule and will thus be considered substandard English by people who care about such things.

    The use of “less strong” here does not violate any grammatical rule (“more strong”, however, would). It may be a stylistic flaw, depending on what style guide you’re using and how picky you are, but no more so in my mind than using “less quickly” in lieu of “more slowly”.

  23. > I don’t know why other hackers don’t.

    One question is whether the other hackers in question can communicate as well as you in general — never mind in the context of programs.

  24. > Perhaps they don’t take the idea that source code is a form of communication with other humans seriously enough. I always have it in mind when I write.

    Have you ever tried literate programming à la Knuth I wonder? If so what do you think of it?

    1. >Have you ever tried literate programming à la Knuth I wonder? If so what do you think of it?

      I’ve read descriptions of the tools. The approach didn’t seem natural to me. Source code is its own language; it seems to me that the proper goal of communicative programming is to make that language clear and easy to read.

  25. Would it perhaps be useful to add a line or two on how to deal with one’s patch being rejected?

    When someone is learning a new art or craft, be it music or sofware, his earlier works are less likely to be of high quality than his later ones. Speaking from experience, having one’s sincere efforts at contribution being rejected can be quite discouraging, regardless of whether those efforts are a patch that addresses a personal annoyance in a program, or a riff suggestion for the band’s newest song.

    I think the willingness to accept rejection and failure, and to analyze such in search of new things to learn, is necessary to developing a new skill, be it music or hacking.

  26. Would it perhaps be useful to add a line or two on how to deal with one’s patch being rejected?

    This, this, this, for multiple reasons. In addition to helping form a realistic expectation of what the path to contribution is like, spreading this will help inoculate against falling for the $FOO-card. I’ve seen plenty of privileged individuals scream discrimination when their subpar work is criticized, and it’s necessary to keep hammering on the point that in the open-source community, work is (ideally) adopted or rejected on intrinsic merit. I’ve had pull requests rejected with terse comments that I didn’t pay close attention and spammed whitespace changes–and the maintainer was right to do so.

  27. >>How well does this intersect with some people’s C coding practice of avoiding forward declarations unless it is impossible to do so

    >Pretty well. Genrerally if function B needs the prototype for function A, it means B is built on A in the narrative order I’d want to write them in anyway.

    What that means AFAIU is putting helper functions that deal with the minutiae of the problem first, the important high-level code last.

    I personally prefer my narrative to begin with the big picture, then move to the details.

  28. Eric S. Raymond: What are your thoughts on tonight’s happenstances in Ferguson Missouri ? What would you have done differently if you were in charge there (if anything)?

    Here’s a song about it all:
    Requiem for the street of West Florissant in Ferguson Missouri.
    http://youtu.be/MKWeF5dEI0g

    1. >Eric S. Raymond: What are your thoughts on tonight’s happenstances in Ferguson Missouri ?

      Way off far off topic for this thread.

  29. Is there a handy link to earlier versions of the document that I’m missing? I see the revision history at the top, and I assume that’s 1.1 below it, but I can’t seem to find 1.0 as a result.

  30. @esr, I think people have been spoiled by their ability to easily find cvsweb/viewvc/cgit copies of most open-source projects – this is at least the second time in recent memory you’ve gotten this request. Is there an RCS equivalent, and/or can cvsweb work on non-CVS collections of RCS master files?

  31. Many thanks… This was a critical missing point from the visionary essay of “How to become a Hacker”. IMHO, it’s even worthwhile to mention the term of Software “Architects” and “Agile” methods in that essay too.
    Hackers are the ultimate “designers”. So, knowing this ultimatum while learning to hack is a vital point..

  32. Maybe you could also rewrite that Barbie book. I have some problems with the existing rewrite, here: http://www.themarysue.com/barbie-remix/

    It’s this assumption that people judge female programmers more harshly than male. I have a hard time believing this. I’m male and *i* have to prove myself. And also that a book about a girl being a programmer has to harp on about feminism, instead of just being about a girl programming. And also that people assume the programmer is likely to be male for any reason other than programmers are, in fact, more often male.

    And also that I am posting anonymously because I am terrified of being misunderstood, starting a Twitter storm, and getting fired.

    Any way, turning the Barbie book into How To Learn Hacking for kids could be a good project.

  33. 1) Quote: “It’s a good exercise to add explanatory comments and notes to to (sic) the code as you figure out things about it.” s/to to/to/

    2) s/macrolevel/macro level/

Leave a Reply to Thomas Blankenhorn Cancel reply

Your email address will not be published. Required fields are marked *