Learning Tools Versus Learning Concepts

Posted by david

One of the best teachers I had during my time at the University of Illinois was John D'Angelo in multivariable calculus. This class was required for all engineering students, and most of the students in the class (myself included) were not very interested in the course itself. We may have wanted to learn to design bridges, circuits, or software, but this class was really just a hoop to jump through in order to study the stuff we really wanted to learn.

My reason for writing about this course is Professor D'Angelo and his lack of patience for a certain type of student. You see, to do well on the exams in math courses at Illinois, you had one of three options:

  1. To learn the concepts
  2. To learn how to solve the types of problems that would be on the exam
  3. To cheat

While I'm sure there were at least of few students who opted for option three, Professor D'Angelo was notable for designing his exams to foil the students who opted for option two. Many exams would feature questions that looked nothing like those that were featured in the homework problems yet were trivial for students who really grasped the concepts behind those problems. After each exam, it was inevitable that some students would stop by his office to argue that they deserved partial credit for one or more answers because if they had done just one or two steps differently, they would have arrived at the correct answer. The professor was famous (or infamous) among the students for being stingy with these partial credit points since the incorrect steps indicated a lack of true understanding of the mathematics behind the techniques. He once boasted to the class about a student he had sent away by exclaiming, "You deserve zero! You deserve zero!". Despite his temper, he was an excellent teacher, and students who did well in his class were well-prepared for the more advanced math courses to come.

While I was studying computer science at Illinois, I commonly heard students gripe that the coursework was too theoretical, without enough of the practical knowledge that would enable us to land good jobs coming out of school. We may have graduated knowing plenty about complexity analysis and hashing algorithms, but would we know enough Java to succeed at the day-to-day work most of us were heading off to do? I certainly griped about this on at least a couple of occasions, but in hindsight, I'm grateful for the theoretical knowledge I did acquire, due to the type of teaching exemplified by John D'Angelo. I don't know how much the computer science curriculum at Illinois has changed in the few years since I graduated, but I hope it has not moved very far away from teaching the concepts it taught while I was there.

If you make your living as a software developer, you've undoubtedly come across programmers who know all of the surface details of the platform and the tools they work with but lack the conceptual knowledge of how those tools work. Perhaps they're Java programmers who have not only memorized the Collections APIs, but who can write JSTL with lots of custom tags, Hibernate configuration files, and Struts forms without needing to look at a reference.

And perhaps they're also programmers who hear about a technology such as Ruby on Rails or Jython and immediately dismiss it by saying that languages without static typing just aren't "safe" (or fast enough, or secure, etc.) despite having zero or near-zero experience programming in any language other than Java.

While such a stereotypical programmer may honestly believe the reasons he's dismissing the technology in question and may even have a point, he also does have a lot to lose in such a major technology shift as heavy use by dynamic languages. He has invested a lot of time and effort in learning the technologies he works with. He gets paid a lot of money and has (for now) a secure job because of the effort he's put into that learning. When EJB first came out, he spent several evenings learning it. When EJB2 came out, he spent several months. Once he was convinced that SOAP was going to take over the world, he not only learned XML Schemas, XML namespaces, and WSDL, he also learned how to use JAX-RPC, JAXB, and SAAJ. It wouldn't be fair to him to render that knowledge useless by choosing a new platform with a different set of APIs.

I don't mean the previous sentence sarcastically - any programmer who invests the time to become an expert in development tools isn't lazy. Knowing all the details of the tools you're using is a good thing, not a bad thing, and teams can be well-served by having such an expert available. But whether or not having to learn a new platform is fair is irrelevent. Birds fly, fish swim, and technology changes. If it didn't, it wouldn't really be technology. If the University of Illinois had spent its time teaching me all about the mainstream technologies in use in 2001 (the year I graduated), it would have served me well at that time, but my education would be getting more and more stale with each passing year. Instead, I currently find myself really wishing I had paid more attention during that lecture about fixed-point combinators, because not only are they freaking cool, but because understanding them may prove to be somewhat useful in whatever language I'll be using to earn a living a year from now.

The thing is, to get anything done, we do need tools - we need XML parsers, build scripts, and even ORM frameworks, and we need to know how to use them effectively. A Java programmer who doesn't know the difference betweeh the HashMap and a TreeMap classes probably isn't going to be very productive, no matter how well they undertand hashing algorithms. We only have so much time we can spend learning, and if we spend it all on high-level concepts, we'll have a hard time actually building anything. That's the tradeoff. So how should we focus our energy?

One of my biggest metrics for the quality of a tool is how much of what I learn when using the tool will be of value when I stop using that tool. In other words, will learning that tool teach me about the concepts behind that tool? Likewise, how much will my existing conceptual knowledge make it easier to learn how to use the tool? For instance, if I'm going to invest the time to learn yet another ORM framework, I want to get a better understanding of the general techniques ORM frameworks use. As another example, learning how to leverage higher-order functions in Ruby translates well to using them in JavaScript or Scheme and will translate in some degree to any language that supports functions as first-class objects.

One way to get the benefits of learning a tool well and learning concepts that will prove valuable beyond the tool itself is to learn how that tool works. While I'm picking on database-mapping tools, consider the Ruby on Rails interface to the database - ActiveRecord. I bet that anyone who can honestly put Ruby on Rails on their resume has ventured into the ActiveRecord source code at some point. (The same is certainly not true about Hibernate). This is due to the fact that Rails is distributed as source code, rather than object code, and because the dynamic nature of Ruby makes it easy to extend the behavior of ActiveRecord in ways other than subclassing. To do so effecively, however, you need to be familiar with how ActiveRecord works, and the most effective way to do that is to go to the source code. While you could argue that needing to go into the source code to find out how something works is not ideal, you cannot argue that the act of doing so will give you a better understanding of the techniques the tool uses to do its job - techniques that may prove applicable in other situations. If fact, the Rails source code is how I originally learned Ruby. After working through the simple examples given in the Rails documenation, I found the Rails source to be a rich bed of information on Ruby idioms and techniques.

Reading back over this, it seems like I'm picking on Java programmers. That wasn't my intention, but now that I think about it, whenever I've met a software developer who only knows a single platform or programming language, that language has always been Java. Java's dominance over the last few years has made it possible to be a financially successful programmer without needing to learn other languages, and the complexity and sheer number of its frameworks has captured the energy and time many developers have for learning. But like the languages before it, Java won't dominate forever, and the developers who have a solid understanding of the concepts (both within Java-land and outside it) are the ones who will be successful transitioning to whatever comes next.