Do you strive to understand your tools, or simply “make it work”?
kylewritescode.com
kylewritescode.com
The problem is that learning to build/configure/use XYZ is almost always a wasted effort, it is not like learning a new algorithm that will be useful knowledge for decades, so if the effort is too big I consider it wasted time.
Examples of tools that are not easy to master but that I'm trying to learn well are vim (it's 15 years I use it), and git. Both tools pay back a lot, and in the case of git it is hard to learn not because it is hard per-se, but since you are learning general concepts about distributed VCS, so it's not a wasted effort.
At the moment, I'm trying to build a drop-in blog engine for Rails 3.1, which involves reading a fair amount of source code. But I need to wrap this up today and start on a different client project tomorrow, so I can't afford to dive too deeply.
Another question to ask yourself is, "If it breaks, could you fix it?" And what is fixing it? Swapping parts, fiddling with function params, without knowing exactly what went wrong at a deep level? Paying someone to fix it for you? Is it "understanding" to know whom to pay for what repair?
I believe it is possible to have a thorough understanding of every aspect of every tool we use, but this would tend to limit the extent most of us would build up from it, as time spent learning these fundamentals is no longer available for deriving from them. If we assume humans have limited time and capacity for understanding what already is, it's by necessity that we use certain inventions as black boxes in order to build from them.
Or maybe the question is, "Should you be able to build your own toaster?"
http://www.ted.com/talks/thomas_thwaites_how_i_built_a_toast...
Software tools on the other hand have a way of spiraling in complexity. We're so good at using physical tools because this simplicity allows us to learn their use on an unconscious level, ie. muscle memory. The take home here is that we need to radically simplify the programmming tools we use. Unfortunately the trend towards frameworks rather than libraries is moving in the wrong direction.
However, many software projects are complex machines---and like real world machines they're made of parts.
It'd better then to have a framework because the framework assures you that all these parts ought to work together, or at least have been designed to a certain abstract standard.
Imagine building a car but rather than being able to order Ford-fitted parts or Toyota-fitted parts, you'd just get generic parts that you then have to machine yourself in order to make work. Every part, every screw, everything. It'd take tens times as long as if you only had to machine rare parts (e.g. a 1965 engine block to fit a 1973 model frame).
If I think the tool is a sloppy stack of hacks, I don't care how it works --- I actively avoid the nightmare. I don't want to spend my time figuring out which bad decisions, bugs, and corner cases made it behave in a certain way.
Tools that are "internally cohesive" reward the effort put into learning them.
Knowledge gained learning one function of an internally cohesive tool can often be applied to others, opening up new functionality and encouraging you to learn more about the tool.
This way your understanding of good tools tends to grow organically instead of the jarring pile of rote-learning that a kludgy tool tends to require.
For example, yesterday I got fired from my employer on my 90th day for not being productive enough. I can't fault my employer because I understand his perspective. He needs employees that are productive. I spent most of my 90 days learning the tools and EXACTLY how they work, without much to show for it. This was my fault. I spent too much time learning.
This is true with many things that I learn on my own as well. For example, in the last few days I started teaching myself Kohana PHP framework. If some of MY applications are going to be using it, I want to know exactly how it works and everything about it. I want to be an "expert" at everything, but I'm not quite sure how realistic that is.
I think I am going to try to change my ways to only learn enough to "make it work". If the tool is worthwhile to use over and over again, it is inevitable to develop an intimiate understanding of the way it works over time. I think it is more important to be able to have awesome products to show for the time you invest in your tools.
Bottom line: Understanding your tools in depth allows you to differentiate outcomes that will be opaque to less knowledgable competitors.
The TCP/IP stack: strive to understand it.
Random Java SOAP abomination: get in, make it work, get out.
There's no chance in hell to understand all the tools. It's quite possible to understand the concepts and general principles these tools are built around (i.e., all the stuff you get taught in a proper computer science course), which I think is what one should thrive for.
Note that even understanding the concepts will not even nearly equip you to (easily) understand and re-implement these tools, there's a lot more to any properly crafted tool than just the rough concepts.
Entrepreneurs have a totally different profile. Instead of the "how" and "what" of the project, they focus on the "why" and the "who cares". Will this project be valuable? Should I pivot this idea? Who is my first customer and what do they want?
These tendencies don't coexists very well -- they both want to be priority 1 in my mind. While I've been writing code, polishing scripts, reading kernel code, and accumulating my 5000 lines of emacs-lisp hacks, my friends chose different routes and started small businesses or pursued influence and high salaries. Now I'm a super-wonky developer and they're much better at sniffing out the real value in the world. Each of us has our place and on some days I'd rather be them. Somehow though, and somewhat mysteriously, when it comes time to choose I'd rather be rewriting the low level than pursuing meaning at the high-level.
Lesson #1 from my car hacking hobby.
before this I was all over the vws (1.8t, tdi, and then an idi), with all the usual vw stuff (especially diesels. I love diesels).
I think my next step will be either a subaru (track car), or a honda/bmw (just a get-around car).
I'm pretty limited tho since I live in Ottawa and have no garage. ask me if I've looked into starting a garage co-op here, and I'll tell you terrible insurance related woes.
I'm of the school that in many things, if you have to teach someone how to use it, you've done it wrong. Let the user learn by doing.
Probably can't apply to everything, but we should work as had as we can to try to get there.
The understand-your-tools side builds the tools that the make-it-work side uses. The feedback between both sides is important for improvement. The success of the make-it-work side helps to quantify the value of the ideas coming from the understand-your-tools side. It's unfortunate that these two points are often treated like opposing sides.
I know other people that do that too. For some of us, the immediate reaction to a new thing is "ooh, shiny, how does it work? Let's run some experiments." The scientific mindset is useful, I think, no matter what you wish to exploit.
I mean, I suppose minimal projects could get completed, but I never work on minimal projects. Mine always have edge cases, and that requires knowledge.
The best powerful tools don't require an in-depth understanding of them to get started (think git, rails or Linux). But mastering them over time will make you better by orders of magnitude than the copy-pasters with no fundamental knowledge of the tools they use every day.
The trick is in figuring out which tools are good, and which of them you want to commit to.
Also if I find something that is complex, e.g. OAuth, I try to preserve the sources of information I used to reach a decent level of understanding for maintenance purposes.
If I'm just doing something quick and not worried about future usage, I just make it work.
If later I have a strong desire to understand how it works I'll dive in, but most software tools I don't care to know.
I don't really care about the detail inner workings of my car.
That said, a lot of the tools I use at work are built by myself or my team. I trust them, so "making it work" is enough for me, especially because I don't always have the time to understand everything 100%.
If I'm doing something as a hobby, I try to understand it, because time isn't really a factor there, and that's the fun part, right?
For technology or tools, the underlying specifics are going to change insanely fast, so if you are learning it, you will need to unlearn soon (and learn something else).
So should you learn internals of libc? STL? JVM, bytecode? rt.jar? .NET CLR? V8 JIT?
I don't know. I want to know what is going on? Know it first, automate next, thats what I try to do most of the times.
Know that first. Then, if you choose, go use turn key systems/hosting environments.
We all just want to make things work. Oftentimes with programming, having a better understanding of your tools helps you become better at "making it work."
Just the other day I was talking to a friend about learning programming. I said to him that I'm quite capable of teaching someone who knows the basics of programming more as long as there's the initial foundation to build on but I'll be damned if I know how to teach someone who doesn't know how to program at all how to program.
I don't even know how I learnt to program. I was a kid at the time and I guess I basically just typed in programs from books and then played around with them. I guess this model largely follows the idea of direct instruction [1]. It's one reason I like Zed Shaw's Learn Python the Hard Way [2] because it starts by just saying "type this in... actually type it don't copy and paste it" because for beginners this approach actually works (well).
One thing I find interesting is that many non-programmers I know are afraid to just start pressing buttons and messing around with stuff to get the computer to do what they want. They want to know how to do it before they start. I think this fits in with the theme of direct instruction as I've learnt the behaviour of doing something without knowing exactly what will happen. Without this willingness to try (fail) your ability to learn seems to be incredibly impeded to the point of being near-impossible (IMHO).
To bring this back to understanding your tools I would say I follow this pattern:
- If I can, I'll learn just enough to get by;
- I'll slowly accrue new techniques and knowledge as time goes by and I use it (studying this kind of thing without needing to use it is virtually useless for me); and
- For things that are most key to what I do I'll expend time and energy delving deeper into them but this applies more to languages, APIs, frameworks, platforms, etc than it does the tool. The tool is, after all, a means to an end not an end in itself.
For me I've found learning tools to follow a fairly similar pattern to learning (human not computer) languages: I can try and memorize things all I want but I seem to have this base rate at which I will accumulate "instinctive" knowledge that is a function of how much I use something with very little variation up or down.
YMMV.
He thinks that only about a third of the populace can learn programming at all, and that may be the difference between teaching someone who knows the basics of programming vs teaching programming to a non-programmer.
I also think that if you write a paper like that, that it should include a lot of qualifiers as to what you think you've discovered and what research might be done in order to validate/disprove your findings.
Broadly binning a large part of the population as far as a fairly basic ability is concerned (the ability to instruct another entity, which is the essence of programming) based on some extremely flawed tests is not the way science should be done.
Try the 'test' they give to people on a population and then try this test on another population of similar size and observe the difference:
move 10 to a
move 20 to b
move contents of b to a
The fact that programmers use '=' in a way that non-programmers would never use it should not be part of any 'aptitude' test. That's just syntax and it would give anybody with even a cursory knowledge of programming a huge advantage. Even just the assumption that statements are to be executed in a particular sequence greatly affects the outcome of tests like this and you may have to specify such a thing up-front if you expect people to be on a level playing field.Note that I'm not saying that the conclusion of the paper is wrong, I simply object to the hidden assumptions behind the design of the test. Removing those assumptions would be pretty tricky thing to do with 100% accuracy, and in the end the conclusions reached in the paper might still stand (but I doubt that they would be the same in magnitude).
I was guilty of forgetting this in a programming interview and gave an answer from algebra.Needless to say interview went downhill very soon.
Try coming up with a 'consistent mental model' that works with random execution sequences.
Then try again for one that works backwards. And so on.
At best this test determines which people are going to be 'easy' to teach programming. But just like sales start at 'no' teaching starts when the subject is having problems, not when it's easy.