Current Projects (January 2014)

By way of a brief update, here are my current main projects for the new year:

  • I’ve invested in and have started working through Peter Van Roy and Seif Haridi’s textbook Concepts, Techniques, and Models of Computer Programming, a.k.a. CTM. As Professor Van Roy explains here, this book “brings the computer science student a comprehensive and up-to-date presentation of all major programming concepts, techniques, and paradigms in a unified framework.”
  • I’ve started learning functional programming in Clojure through a combination of Aphyr’s “Clojure from the Ground Up” posts and Chas Emerick, Brian Carper, and Christophe Grand’s book Clojure Programming: Practical Lisp for the Java World.
  • As a project to tie in with both my continuing computer science education and Clojure study, I am working on implementing a series of common data structures using Clojure. I will be pushing my work to a GitHub repo as I progress.

Building a Foundation in Programming

How does a novice start building a credible foundation in programming without the benefit of a formal curriculum or training? This post offers one possible answer and some recommended resources from the perspective of a current student.

Introduction: My Story

I started studying programming part-time in January 2013 with no prior experience. After several months of exploring programming as one of several possibilities leading towards a new career path, I decided to pursue a career in the software industry with a focus on development for the web. In order to overcome my lack of both a formal background in computer science and prior work history in an immediately related field, land a job, and do it well over the long term, I knew that it would be vitally important for me to invest serious, sustained effort in building a strong practical and conceptual foundation. Although I knew that in a year or so of part-time independent study I could not expect to match the depth of knowledge and experience gained by formally-trained computer science majors, I was also convinced that I could at least ground myself more firmly than many other self-taught programmers. So, despite temporal and financial pressure to move as quickly as possible to building sample projects with popular libraries and web frameworks, I’ve focused most of my attention so far on building a deeper understanding of the underlying concepts and languages upon which current and future software development will depend on a deeper level. For me, these foundations most definitely include significant forays into mathematics, databases, and networking, which I will leave to other posts.

Today, as I am starting to move towards developing my own first projects for public release, I want to pause to reflect and share part of what I’ve already learned and how I went about learning it. I know that there are many other people interested in learning some programming skills without the benefit of formal classes or the ability to study full-time, and that a fellow learner’s perspective can be a big help in pointing the way, or at least in offering some encouragement. To that end, this post offers references to resources that I have found particularly helpful in building the start of my own foundation in programming with a focus on web applications, beginning with conceptual basics, and moving on to more specific language learning at the beginning-to-intermediate level in Ruby, JavaScript, HTML, and CSS.

Please note that I am offering this post as contribution back to the larger community of students and professionals whose work has helped me to learn, rather than as a “how-to guide” or curriculum for a transition I’ve yet to complete. I similarly make no claims to exclusivity or comprehensiveness, either as a description of my own learning, or as an account of helpful resources or necessary concepts. There are surely other good resources that I do not mention here and other approaches to learning that could work both for me and for others.

1. Basic Concepts and Exposure

I had to start at the very beginning. I needed a basic, working concept of both software development and computer science as fields, and I needed to learn to recognize and use the basic building blocks of both programming and markup languages in a manageable, controlled way. I needed exposure. Luckily for me, all of this is possible with nothing more than Internet access and a modern browser. In fact, thanks to free, self-paced courses and tutorials available online and the availability of tutorial programming environments in web browsers, it has probably never been easier to gain the familiarity I needed to get started.

Resources for Getting Started:

If you are also interested in starting from the very beginning, I can recommend the following free resources from my own experience.

A. For background and context:

Nick Parlante of Stanford’s Computer Science 101 Course on Coursera. This is a MOOC (Massive Open Online Course) available as a “self study” without waiting for a new session to be offered. I found the “self study” option, in which all of the course materials are immediately available, to be particularly helpful for picking up an accessible introduction to topics like information storage in bits and bytes or Ethernet. There are also basic introductions to topics like Boolean logic that you will quickly encounter in programming tutorials. In some cases, I have found it can be helpful to have access to another explanation. The beauty of the “self study” option lies in your ability to get what you need and come back later.

Blog Posts by Kyle Kingsbury (Aphyr): “Getting Started in Software” and “Core Language Concepts” My friend and mentor Aphyr wrote these posts to help me get oriented, and he is sharing them with you too on his blog. The first, “Getting Started” should be accessible almost right away. The second, “Core Language Concepts,” will probably make more sense once you’ve had a chance to work with some programming tutorials.

B. Early exposure

Codecademy can be a good resource for interactive lessons and tutorials to help you get started and prepare you for further learning. It’s not perfect. You will probably run into a variety of criticisms of Codecademy and its competitors, some more tempered and well-intentioned than others. Look for a few that seem reasonable to you and read them. Think about the points they raise. Try out a few lessons, and see what you think. I’m not going to add my own proper review of Codecademy here, but I will offer a few comments to frame my recommendation.

For someone with little or no prior experience, Codecademy courses can be great for basic exposure to some very simple programming. As with most things in life, in order to get the maximum benefit from the courses, you will need to have reasonable expectations and a positive attitude. If you are a total novice as I was, resources like those above in section ‘A’ will help provide some valuable additional context.

Be patient and don’t expect too much of a free resource still under development. For instance, you will almost certainly run into an exercise validation issue that you don’t immediately understand. It may or may not actually be a problem with the site. Sometimes it will be part of the site or a browser behavior that you have no control over as a user. Sometimes you will have a perfectly good–or even better–solution to an exercise and it will not validate. Still other times it will be entirely your own mistake. Be patient. Try to figure out what is happening. Read your own code very carefully first, and then check the forums. If it still doesn’t make sense, check back later and try again. If/when you are able, try to reason about why the error is happening and learn something more in addition to resolving the immediate issue. Problems with exercise validation can be teaching moments about testing and writing your own tests in the future. Similarly, browser issues with the interface are teaching you about the very real challenges of making highly interactive applications behave well and predictably across the spectrum of browsers. To give one final example, in February, there was a database migration problem on Codecademy’s backend. Some of my user data was permanently lost. This was also a teaching moment –an opportunity to start thinking and learning about databases. With the right attitude, you can make problems part of your learning process rather than an impediment to it. In my experience, it will be vital to adopt this attitude as a learner whether or not you are working with Codeacademy.

Furthermore, remember that, although they can be valuable, these courses are just a start, and treat them as such. By itself, working through Codecademy (or something similar) is not going to turn you into a credible developer. The courses will also not necessarily teach you the best way to write or think about even a basic concept or problem. In fact, there can be content problems on a variety of levels that someone with more training and experience will notice.[1] But here’s the thing: working through the lessons can start you on a path to become a person who can point out those problems yourself. This has worked for me. At least in my experience, Codecademy courses are enough to give a beginner just enough exposure and practice to take on more complex tutorials and resources, and just enough of a taste to pique a learner’s interest and help build zir confidence to make that sound both possible and fun. As such, I think Codecademy can be a valuable resource for beginners and I can recommend the site.

That said, you could also choose not to use Codecademy at all. You might try something different to get comparable exposure, or even skip right ahead to something like Chris Pine or Zed Shaw’s tutorials (see below). My guess is that it would take a little extra momentum and encouragement to launch most total novices right into those, but it could certainly work.

2. Next Steps:

From here, things get more difficult. I’ve personally focused on learning Ruby as well as possible as a first programming language and enough about JavaScript, HTML, CSS, and the DOM to be a competent junior participant in conversations with front-end developers and eventually build simple sites myself.

I’ve generally been learning these subjects in parallel, mostly because I  get excited to know how the pieces will fit together in the end, and I have a lot of experience managing that kind of parallel learning successfully. I don’t regret learning this way, but it has probably made things more complicated than they otherwise would need to be. If you are learning too, it might be easier to handle one thing at a time.

My general strategy here was to make sure that I had the basics down, and then move onto more intermediate-level resources. I deliberately sought and invested time in second and even third presentations of the basics I had seen before on Codecademy or other tutorials. I wanted to be sure that I was learning best practices, and furthermore, in my experience, repetition and practice, especially in variations, powerfully promotes retention of new information.

Resources for your next steps:

The following is a kind of annotated outline of resources that I have personally used and would recommend to another learner at this stage. Some of these are books that you would need to borrow from a friend or buy. Although money can be tight for those making a career change, I think these are still worth acquiring because of their quality and ongoing utility to a learner.

A. Ruby


First, you’ll want to solidify the basics with some resources aimed at newcomers to both programming and Ruby. In respect, I found Chris Pine’s Learn to Program to be helpful. I used the free online version[2], but there is also a revised and expanded second edition available in paperback (ISBN: 978-1934356364).


Zed Shaw’s Learn Ruby The Hard Way, available in a free online version, is also very helpful. Shaw will take you back through the basics and then push you onto a more intermediate level. Start with the same author’s “Command Line Crash Course” if you need to learn (or re-learn) the basics of the command line interface as I did.

I recently acquired a copy of Peter Cooper’s Beginning Ruby: From Novice to Professional (2nd ed. : ISBN 978-1430223634), skimmed the earlier portions, and started working through some of the later chapters, which cover some more advanced topics at a greater depth than Shaw’s book. It also has the advantage of being originally written about Ruby, whereas Shaw’s work is translation of his Python book. Cooper’s book is helping me to solidify my grasp of a number of things that I didn’t quite master the first time around by jumping from Shaw to Olsen’s Eloquent Ruby (see below), so I’m also recommending it here.[3]

I personally like Shaw’s Hard Way a lot and think it is worth working through in addition to Cooper’s Beginning Ruby, especially because Shaw’s format deliberately emphasizes practice in reading and writing as well as introducing concepts. However, in retrospect, I think it might also work to move from the Pine book or a similar introductory resource (even if in a different language) right into and through Cooper without Shaw. I think the choice would come down to your own learning style and time you can make available to study.

Around this point, you may also find the Ruby Koans to be useful as extra practice and reinforcement. I know that I benefitted from working through the exercises. You will read a lot of Ruby carefully, find and fix problems, and get more practice using the command line and your favorite text editor.

Also at this stage, start working through the Project Euler problems. These will make you apply your knowledge in new ways. You can also learn an enormous amount about efficient algorithms and writing eloquent code by reading a variety of programmers’ solutions to the same problems. It may also drive you to learn more mathematics, which is definitely a good thing.


If and when you feel ready to dig a little deeper, you might move on to Russ Olsen’s Eloquent Ruby (ISBN: 978-0321584106). Olsen will help you to understand and think in the language at a deeper level. My personal copy of this is joyfully and extensively annotated. I keep coming back to it and learning more every time. Try to find ways to apply what you learn here to your work in Project Euler or building the practice projects described by Shaw and Cooper.

For other ideas about books, you might also consider Olsen’s own recommendations. You can check out his “Ruby Reading List” here.

B. Front-End Web Development with HTML, CSS, and the DOM

To start really working with JavaScript and its libraries, you first need to learn to understand its context within web browsers, which means learning your way around the DOM, and, as part of/along with that, HTML and CSS.

In my own work towards that goal, I have personally learned a lot through the companion books Designing with Web Standards, 3rd ed., by Jeffrey Zeldman with Ethan Marcotte (ISBN: 978-0321616951) and Developing with Web Standards, by John Allsopp (ISBN: 978-0321646927).

These books are written for professionals and serious students, with a strong emphasis on understanding and applying web standards and best practices. Working through and referring back to these really helped me to be able to open up Firebug or Chrome DevTools and grasp a lot of what I see, even if I can’t yet build it all myself. Thanks to these, I can also read and understand a lot of the conversations and arguments that front-end developers and web designers are having, which opens up a whole universe of professional discourse to an advancing student.

C. JavaScript

For learning JavaScript itself, I can personally recommend Eloquent JavaScript: A Modern Introduction to Programming, by Marijn Haverbeke, which is available in both an original online version and a revised paperback version (ISBN: 978-1593272821), as well as JavaScript: The Good Parts, by Douglas Crockford (ISBN: 978-0596517748). Neither of these books is likely to be very accessible to a total beginner, so I would recommend picking them up only after gaining some more experience.

Although the author labels it an “introduction to programming,” Eloquent JavaScript past Chapter 4 can be very tough for a beginner. I picked it up very early on, just after completing Codecademy’s JavaScript course, and I was stumped by the time I hit Chapter 6 (“Functional Programming”). I came back to it a month or two later, after I had learned the rudiments of programing in Ruby (which was more accessible to me as a novice) and reviewed some mathematics that I had mostly forgotten. I was then able to work through the rest of the book.

On the first page of his preface, Crockford explicitly writes that The Good Parts is “not a book for beginners” and warns that “the book is small, but it is dense” (xi). He deserves to be taken at his word. I’ve learned a great deal from this book, but only by working slowly and carefully, and only because I had already built a substantial conceptual foundation in programming through another language. In my case, this was Ruby, but for you, it could be something else.


There are, of course, many paths to building a foundation in programming. In this post, I’ve described how I started building my own from the ground up, and I’ve offered references to some resources that have been helpful to me as an independent learner. No two students are exactly alike. You may not like these same resources or prefer others. You might prefer to learn Ruby, for example, from the ever-popular and quite entertaining Why’s (Poignant) Guide to Ruby, by Why the Lucky Stiff. I think that’s great.

Remember, I never meant this to be comprehensive, exclusive, or read as some sort of a curriculum. Frankly, I’m nowhere close to having earned the right make a curriculum. At this point, I’m still working at level of the “intermediate” Ruby books I describe above, and consider myself something like an “advanced beginner.” I’m not yet an expert by any means. I simply wrote this in order to share part of my own story and help give back to the larger community of teachers and learners making this all possible. I hope that his post proves helpful to you in some way. The most important things to take away may simply be that it is possible to learn and that good help is available.


  1. To be fair, I understand that the Codecademy team is actively working to improve their content all the time. I hope that the larger context of my comments here will make it clear that I do not intend to carp at Codecademy or its employees, but rather to recommend their product, which like all products, has its limitations. I also realize that it may seem somewhat unfair of me to suggest that there are problems without citing specific examples and evidence. In this case I disagree. Citing and arguing about specific lessons would take us too far afield from the main topics of this post and would also require me to put considerable time and effort into an unsolicited and unpaid work of criticism, which would be unlikely to directly improve the content itself.
  2. The server seems to be inconsistently available at the time of this writing. Don’t be surprised if you get a 503 error.
  3. I certainly don’t intend this as a criticism of Shaw or Olsen’s work. My need to go back has much more to do with my own learning process and growing levels of understanding and ability at different times in my training than any flaw in the materials. A big part of my journey has been circling back to pick up bits and pieces of knowledge that I skipped over, forgot, or didn’t quite understand at an earlier point. Even the most diligent student attempting this kind of learning at speed will not be able to retain all of the details or fully work through each and every example or exercise in this many resources. I certainly don’t claim to have managed this myself. I don’t see that as a failure, but rather as utterly normal and nothing to be worried or embarrassed about in itself. Gaps in the foundation become a problem when you ignore them and fail to address them when they appear. So I go back. I put in my time. This is why review is important. This is why learning takes practice. If you want to build a solid foundation, you have to fill in the gaps. To paraphrase the great poet Kanye West, you must crawl before you ball. Maybe that should have been the subtitle of this post– “Programming Foundations: Crawl Before You Ball”?

Why software?

So why does a humanist leave the university and start learning to read and write software?

Good question. I think I can best address it as a system of related questions. [1] This post offers an initial answer to one part of that system: why, out of all the possible choices, am I choosing to learn the art of programming? The short, “tl;dr” answer[2] is that this particular humanist is intellectually excited by the craftsmanship and challenge of software development, and blessed with the support of friends and access to resources to help turn that intellectual excitement into a practical career reality.

I imagine that most–if not all–doctoral students and their professors have seriously considered leaving academe at one point or another. Once a person reaches this point, zie usually has increasingly clear ideas about why zie would leave, but faces further questions about how zie would do that, and what zie would do next.[3] In my opinion, a reasoned consideration of why a person might stay or move on depends on a relative calculation of personal goals and priorities, an operation which is necessarily idiosyncratic and resistant to generalization. I want to focus instead on the questions of how I am making a transition and what I am choosing to learn next. I hope that the posts and pages of this blog, when considered as a whole, will grow to become a reasonable answer to the how of a career change from academe, at least as it applies to one person. At the outset, however, it seems appropriate to offer some initial thoughts on why I’ve chosen to learn the art of software in particular.

I’m attracted to reading and writing software by some of the same intellectual qualities that I’ve enjoyed in my work as a humanist: the craftsmanship of constructing and communicating arguments, a disciplined creativity in reasoning, and a fascination with the use and logic of languages. In my conversations with working software engineers and my own reflections on the learning process so far, I keep coming back to the craftsmanship and the creative work that unites writers and researchers in the humanities and social sciences with software engineers and architects. At a certain level of intellectual abstraction, writing software well is not so different from writing articles, books, or conference papers well. To speak of the field I know best, I believe that in writing a good historical argument, a historian  exercises a disciplined imagination and practical creativity in the use of zir materials and tools, critically deploys the work of, and collaborates with, peers, mentors, and predecessors around the world, carefully attends to nuance and contingent logic in the design and structure of zir assertions, and mobilizes language with elegance and clarity to communicate both the process and the results of the argument. If you consider a program as another form of written argument, I think there are meaningful resonances here. Granted, the parallel is not perfect, and the description is both incomplete and idealized when applied to either endeavor, yet, at least in my experience thus far, there is an underlying intellectual kinship in the art of reasoning and writing as a humanist and as a programmer.

This kinship points to another major attraction for me: the challenge of writing software well. I want to do work that challenges me to think creatively and trains me to think more effectively. Amidst a flood of exhortations to “learn to code [in n easy steps for fun and (quick) profit],” I choose to learn to write programs not because it is easy, but because it is hard.[4] I know that while becoming functionally literate in a language (more or less what “learn to code” usually means) is a valuable foundational skill, it is neither an end in itself, nor at all equivalent to becoming a skilled professional writer. Reasoning well and writing well are not easy in any language. They take an enormous amount of accumulated practice and ongoing effort. For me, the effort is worth it because I think the practice is training me to be a better analyst and problem-solver in general by unlocking new tools and modes of thinking, particularly those drawn from discrete mathematics.

Finally, I am learning to write software because I have the human support and access to physical resources to do so, and I happen to live in a place (the S.F. Bay Area) with relatively abundant opportunities to start. Not everyone has these advantages. I work very hard but I am also very blessed. I would not be learning the art and practice of programming without the support of a considerable human network, and the process is further facilitated by various forms of privilege (i.e. unearned social advantages) from which I benefit in ways I may not even realize.[5] Although my learning process so far could be characterized as one of independent learning and self-study, it would not be possible without the support and encouragement of family, friends, and mentors, including many authors of helpful books, blogs, and tutorials whom I have never met. I want to recognize this support–since it is so often overlooked in favor of a cultural ideal of individual achievement–and begin to express my gratitude for it.

To start, I want to thank my friend, Kyle Kingsbury (a.k.a. Aphyr). Kyle first gave me the confidence to imagine myself programming and started providing me with the tools to do it. Although I did not have any prior training in programming, Kyle had the open-mindedness to connect my experience learning languages for my previous job to the prospect of learning programming languages, and the kindness to use an afternoon off to literally take out a dry erase board and start teaching me the rudiments of programming in Lisp. By hand. That was the beginning. Since then, he has been a great mentor to me in the world of distributed systems and programming more generally. For the record, Kyle is also a wonderful friend and a good person in the broadest possible sense, whose friendship over the last six years has meant more to me than I could possibly express here. Suffice it to say that he has helped me become a better person and a better thinker, and continues to do so.

So, with the help of a network of friends and mentors, I’m learning the art of building software. I hope that in it, I will continue to discover a sense of intellectual excitement and new problems to challenge me. I’ll be writing more about the process here as it progresses.

  1. I know! Of course I’d take a question like that and break it down into some set of constituent parts. The habitus is too strong! So strong that I made a footnote in a medium without footnotes and then internally, instinctively connected the impulse to do so to a concept from sociological theory… I left this here for you, dear reader, to let you know that I know, that sometimes I’m in on the joke too, and that, at the end of the day, I’m both laughing with you and not sorry. Also, in all seriousness, this site has a pretty decent short explanation of Bourdieu’s use of the concept of habitus .
  2. Known in some circles as a “thesis.”
  3. “Zie” (usually pronounced “zee”) is a gender-neutral, third-person singular pronoun replacing the various cases of “he” and “she” in situations where specifying these genders would be inappropriate. I am using this pronoun here to refer to any one person. I think this is a good alternative to using the third-person “they” for singular subjects or the very clunky and gender-binary-reinforcing “he or she.” Since I am referring to any individual person, and all people do not fit into this binary– gender is more complex than this–, I believe this is an adaptation well worth making. There are several systems of gender-neutral pronouns in use today. I am using the zie/zir variant (subj.: zie; obj.: zim; poss. adj.: zir; poss. pronoun: zirs; reflexive: zimself), but, in my opinion, the important point here is the concept rather than the specific system used.
  4. Yes, I’ve appropriated President Kennedy’s “Moon Speech” to describe the challenge. The original quote from Kennedy is: “We choose to go to the moon. We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too.” NASA publishes the full text of the speech here.
  5. At minimum, I think we’d need to consider my sex, sexual orientation, race, class, and able-bodiedness and keep adding from there. First steps to overcoming the injustices of privilege include recognizing it for what it is, talking about it, and helping to educate others. One of the most essential things a person can do from a position of privilege is to learn to listen. Really listen. This Prezi by Cassandra Duplacy might serve as a good introduction to the concept of privilege and the problem. I think this blog post by Matt Sweet offers a few good reminders and suggestions for confronting privilege. I also recommend this post by Jamie Utt on listening.