85

As I am currently struggling with learning WCF for a project at work, for the past several days I have been looking at online tutorials and examples on the best way to make a WCF client; and today, when I told my boss I was having a hard time finding good tutorials because some of them would not go into details with their examples (for instance showing a piece of code that works but not explaing why exactly, or making an example with just a few lines instead of at a larger scale), he told me that I should not try to understand them completely, because there are times where a code will just do what it does and I should leave it at that (he gave me the example that when doing calculus, for instance, we use formulas that we don't know how they were conceived or how they work, we just know that they do and we use them).

And this bothered me because I have always been told that it's really important to understand your code, and that just copying and pasting without knowing HOW it works is practically a sin; which is why I always take my time in understanding something before moving forward with it. And it's not like I'm trying to understand how a particular class works at an assembly language level, I just want to know why a set of instructions does the trick, and why another one doesn't, or why both do and under what circumstances. But my boss tells me that I will end up wasting time obsessing over these little details, and I should just skip it. So my question is, is he right? Is it okay to understand your code only to a certain extent and keep going, and have I only been obsessing over little things that don't matter?

8
  • 3
    also related: Does searching documentation and samples look bad?
    – gnat
    May 8, 2014 at 5:56
  • 17
    @gnat I am not sure how you got those two questions, but they are completely different from this. May 8, 2014 at 7:57
  • @BЈовић meta.stackexchange.com/questions/194476/…
    – gnat
    May 8, 2014 at 8:03
  • 18
    As for the calculus example, I think it's rather poor. Sure you can use calculus formulas without understanding, but that won't make you a mathematician. But maybe that's just me, using mathematics as black box is my pet peeve ;) May 8, 2014 at 13:29
  • 2
    @DavidWallace I was talking about code that I'd have to maintain.
    – Ana Ameer
    May 8, 2014 at 14:30

8 Answers 8

126

The sole purpose of software abstractions is to hide functional details. Were it not for those abstractions, it would not be possible to progress beyond a certain point in computing, because systems would simply collapse under the weight of their own complexity. Human brains can only comprehend so much information at once.

Consider what happens when you write a method. When you write a method, what you are doing is hiding some bit of software functionality behind a method call. Once that method is written and proven to work by writing unit tests about that method, you no longer have to think about what's inside that method unless you need to change something about its implementation.

Large software systems are built upon many layers of these abstractions. You have a microcode layer in the processor, machine code, address and data buses, language compilers, object-orientation, data structures, domain-specific languages, and so on. You have libraries built on top of other libraries, which in turn are built on top of an operating system. You don't fully understand how any of that stuff works either, but you're still able to successfully write computer programs that do something useful.

That said...

You can't just copy/paste code without understanding how it works. The person who tries to make his program work by copy pasting code that he doesn't understand is setting himself up to fail. You need to understand the code you write. That doesn't mean that you have to know how WCF works internally, but you do need to know what the purpose of WCF is, how to write code that properly interfaces it, and how the code you write functions in concert with it. Many copy/paste programmers don't even have a decent understanding of the programming language they are copy/pasting, let alone in-depth knowledge of the libraries they are using.

So you need to have some decent skills, and you need to understand the code you write (or paste) that calls WCF. But you don't need to have in-depth knowledge about how WCF works internally.

Similarly, programmers who think they can stitch together a program by randomly wiring up software patterns are missing the point. We call those folks Cargo Cult programmers.

13
  • 14
    I would qualify that, while we all at some level have to give up and treat the underlying internals as a black box of infinite mystery, but we do have to know what pattern of inputs gives what pattern or outputs. Cargo Cult programming results from just that lack of understanding, wiring up outputs from one chuck to another and then another with no understanding how the throughput is transformed in the process. I don't how 90% of the code I run on works internally but I do know precisely how that invisible code transforms my data and state. That transformation is the true program.
    – TechZen
    May 8, 2014 at 5:48
  • 3
    I think there's a distinction here between "understanding" and "being capable of understanding". Copy/pasting code that you couldn't understand if you stared at it is a different proposition to copy/pasting code that you're happy to look at more closely if something goes wrong. May 8, 2014 at 8:34
  • 13
    Given your answer, one could say that you at least have to understand the layer of abstraction you're working at.
    – Rotem
    May 8, 2014 at 16:39
  • 7
    To summarize, when you call a function, you don't necessarily care how that function you call is implemented, as long as you are using it correctly. However, when you copy-and-paste the code of a function, that code becomes yours, and you are fully responsible for it. May 8, 2014 at 16:50
  • 3
    Agreed on all respects. I'd like to point out that knowing the internals of a library is useful when your code isn't working even though it apparently should. When you understand the flow of that library, you often discover where your initial assumptions break down. May 8, 2014 at 19:24
34

I think the answer is context.

One of the most powerful techniques for managing code complexity—which is the real job of a software engineer, in my mind—is abstraction. An electrical engineer does not have to reprove Maxwell's equations in order to develop a new product, and I do not need to know anything about a car in order to use a steering wheel. Both are important abstractions because they allow us to intuit and use things without understanding them. This in turn allows us to build bigger abstractions.

As an aside, because abstraction is so important I think it is sometimes good to even enforce it with other developers. For example, in my office we sometimes have one developer write the unit tests for a block of code before the block of code is written by a second developer. It enforces the idea of simple interfaces and clear abstractions.

That said, abstraction is no excuse for not understanding how code works when it matters that you know how it works. Refactoring code is an obvious scenario in which the implementation details matter quite a bit. I don't need to know how a car works in order to drive it, but a mechanical engineer and a mechanic should both understand how a car works, arguably in different ways.

As a second aside, one of my first lessons on the job was to never touch code I didn't truly understand. For example, I was once working on a new feature and noticed another line of code in the module that didn't make sense, so I "fixed" it and then released a bug. That taught me a pretty big lesson, which is to admit when I don't readily understand a piece of code and to recognize that good and complex and nontrivial code can be non-obvious. I'm pretty new to software development, but I have found the idea that "good code is easy to read" to be an insidious one that no software developer I know puts into real practice. Sure, don't write obscure or bad code, but hard problems often require complex code. Don't be upset if it takes you time to understand things. My favorite Feynman quote is, "But it is not complicated; there's just a lot of it."

So when do you abstract and when do you take apart the Swiss clock? I suppose it depends on when you're wearing the watch and when you're building it. My own opinion is that the best people in any field are T-shaped, meaning they understand their work in a larger context—something that is only achieved through abstraction—but also know what they need to know deeply.

1
  • 3
    "Don't be upset if it takes you time to understand things" - that really lifted up my spirits! So thank you :)
    – Ana Ameer
    May 8, 2014 at 4:08
19

There are three different parts to understanding software:

  1. First is understanding why a piece of software (as big as an application or as small as a single function) exists. You need to know the point of it, why it was written.
  2. Next I think is understanding what a piece of code does.
  3. Finally is knowing how a piece of code works, what it's internals look like and do.

Which of these you need to have a grip on in order to understand a piece of software differs depending on what you need to do with that code.

For example, take .NET's String.ToUpper() method. I know what this method does, and why you would want to use it, but I don't know how it's written (that's an implementation detail) and I don't really care - as long as I can use properly. I won't ever need to modify this method, so my understanding of the internals isn't necessary.

If I was copying code off the Internet, I need to make entirely sure of what the code does and why. If I was just copying it and never modifying it (unlikely) then I don't feel any need to understand how it works. But if I was going to be modifying it (likely) then I'll need to know how it works - otherwise I'm just using guesswork to modify the code, and that's probably not going to end well.

6
  • 1
    One thing you may want to add to your answer is "How long" something takes. This can be an important piece of info that could fit into the what or how the way that you presented it. +1 May 8, 2014 at 13:48
  • 4
    With something like String.ToUpper() you do need to be aware of what character encodings it will successfully work with, and what's unsupported. For example, does it assume Latin-1 or Windows-1252 encoding, or does it work with UTF-8? That's "behind the scenes" information you need to know -- not quite to the level of knowing all the internals, but still, a vital bit of knowledge.
    – Phil Perry
    May 8, 2014 at 13:56
  • 1
    @PhilPerry That is part of the interface and should be documented. It is not an internal detail.
    – ignis
    May 9, 2014 at 7:04
  • Sometimes it's not well documented (I'll take your word for it that it is in this particular implementation). It's one of those things that tend to slip through the cracks, particularly in volunteer-supported open source projects, where documentation tends to lag behind.
    – Phil Perry
    May 9, 2014 at 13:26
  • @PhilPerry: If the purpose of calling String.ToUpper is to accelerate e.g. repeated case-insensitive string comparisons, all one needs to know about its handling of things like UTF-16 is that it is expected to match the way the Framework's case-insensitive string-compare methods are supposed to work (not necessarily how they do work, given that ordinal comparisons on any the result of any constant transformation will define an equivalence relation, but some string-comparison methods in the Framework are broken and do not define equivalence relations.)
    – supercat
    May 10, 2014 at 16:00
14

Not that I disagree with the other answers, but let me respond to what I read between the lines. If your boss is advising you that you don't need to understand how something works, it could be some feedback that you are taking too long to get something done. Some people easily get distracted by unimportant details and for them it is advisable to work on staying on track.

On the other hand, if programming is your chosen profession and you do have the intellectual curiosity to dig deeper into some technology that is important to what you do, then I would encourage you to take some extra time to follow your interests when possible. The insights that you gain, though not immediately rewarding, will pay dividends in the long run. It will help you make sense of the technology, put you in a position to extend it in many cases, and will prepare you for an even deeper understanding in the future. Over time, this is what differentiates an expert from a casual user.

5
  • 7
    You should strive to gain additional knowledge, but your boss may not want you to do it on company time (unless it's specialized knowledge that directly pertains to what you're working on). I agree that he may be giving a hint that you're getting too distracted and wasting time on unimportant details. Good time management is a characteristic of good, mature workers.
    – Phil Perry
    May 8, 2014 at 13:59
  • 1
    I'm still working on my time management, but I do agree this is something I have to improve on. Thank you for the advice.
    – Ana Ameer
    May 8, 2014 at 14:30
  • 1
    I think the boss and the OP are both just trying to "hedge" their bets. Your boss when in doubt wants you to know enough to get the job done, but the OP wants to know what he's doing in case something comes up and wants to know sooner rather than later. The compromise is about when to learn more. Sometimes you have to do it after the project/task is complete at the risk of still not having enough time.
    – JeffO
    May 8, 2014 at 18:21
  • @Phil: Here's the argument that the boss should understand: It's bad if the employees learn on company time and then leave. It's worse if they don't learn and stay.
    – gnasher729
    May 9, 2014 at 16:55
  • There's a difference between taking the extra time to make sure you know what you are doing and getting distracted at every turn. The former is a virtue (en.wikipedia.org/wiki/Festina_lente). The latter, there's medication for. May 9, 2014 at 18:14
6

In the great book pragmatic programmer this is called "programing by coincidence" (http://pragprog.com/the-pragmatic-programmer/extracts/coincidence)

The bigger problem with this is, if you don't know why a piece of code works when this piece of code fails for whatever reason, you don't know why fails and you can't fix it.

3

I don't completely agree with the statement: "You can't just copy/paste code without understanding how it works."

Forgive my stupidity, but from a programatic viewpoint, isn't including a library of methods/functions which I don't know they work essentially the same as copying/pasting that code into my own?

I.e., if I'm programming using jQuery, I include the jQuery library and then use it. Using Robert Harvey's answer, this is fine since jQuery has abstracted out all of the things I need to use without having to write the code myself or even understand it completely. Do I really need to know exactly how jQuery works behind-the-scenes before I can use it?

Having said that, I agree with the principle behind the statement, but wanted to point out that the concept of "copying/pasting" code (without complete comprehension) is actually more common than one might think and not as onerous as this statement would make it seem.

5
  • 6
    The difference is that jQuery isn't your code. If there's a bug in jQuery, its devs will fix it and push an update. If there's a bug in code you copy+paste without understanding, no one is going to be able to fix it.
    – Red Alert
    May 8, 2014 at 19:40
  • 2
    If there is a bug in a library, the devs might, or might not, fix it, at some point in the future. Your boss/customer does not care whether the bug is in your code, or a library that you selected. There's no easy answer here, just bear in mind that usage of a library is both a benefit and a risk.
    – DNA
    May 8, 2014 at 22:23
  • Both good points. I should add that I do see the difference between copying/pasting 10 lines of code and including a library of 100s. If I paste code into my own, I should strive to understand it as much as possible, however, there is a point at which I may have to just accept the fact that I'm not going to be able to understand it all and I believe that shouldn't prevent me (or any other coder who is learning a new language) from using other people's code snippets. There will most likely (hopefully) come a point when I go back and look at it and say: "Oh! That's what that code is doing!"
    – reblevins
    May 9, 2014 at 15:49
  • @reblevins, I think you're missing the point here. If you're using an API to a library or something like that, supposedly someone else is responsible for making sure it works according to the spec, and fixing it if it doesn't. You're using a high level abstraction. Of course, it's your responsibility to read the documentation and know what it can (and cannot) do, and how to properly invoke it. "Copy and paste" is a different animal. It's "low level" stuff (in-line code), which you should fully understand if you're going to use it.
    – Phil Perry
    May 12, 2014 at 13:13
  • @PhilPerry, ok perhaps I didn't use the best example, but I still don't completely agree that copying and pasting code without understanding it is always bad. At the risk of belaboring the point, take an example someone mentioned in another discussion. What if the code contains an algorithm written by someone with a PHD in mathematics? Am I really required to understand that before I use it?
    – reblevins
    May 13, 2014 at 18:59
2

As most of the time, it all depends. At the extreme end, there is the use of a library. You are not supposed to know or care how it works. You are supposed to know what to put in and what comes out, what it can and what it cannot do.

At the other end, you don't know how to do some task because you haven't done it before. You find ten lines of code on the internet, which seems easier than finding the right information in your documentation (and often is). At that point I'd strongly suggest that now is the right time to learn how to do that task. So take the code, understand it, make it your own. Realise that lots of code on the internet isn't necessarily written by the cleverest of people, so there may be weaknesses and misunderstanding, so by learning now you can make sure that the code works. And at the point where you include those ten lines in your project, they are your responsibility. If the code doesn't work, it's your fault. So you have to understand it, as if you had written it.

So what's the difference to the library? Isn't that your responsibility as well? The code of the library isn't. The choice of library and the usage of the library is. If the library crashes your application ten times a day, that's because you picked a library that is unreliable. You don't have to understand the code of the library, but you have to understand its reliability issues and act.

1

Your boss' advice might work fine, but it is risky. There is a danger that in the long term you will get into bigger problems, which could be averted by taking the time to understand things in the first place. If this is a one-time thing, the risk is relatively small. If you build an entire software system this way, you have a ticking time bomb on your hands. What you don't understand, you don't have any hope of fixing or changing without causing bugs.

On the other hand, if you disobey your boss, your own job may be at risk. If you like your job, then in the future, try to resolve technical issues yourself before he has to get involved. I had a boss once who would mess things up whenever he got involved in technical decisions (though he was stellar at sales and customer relations). Most of the technical staff learned to listen to what he would say, then turn around and do something different. As long as the software worked, he would never follow up and check whether his technical advice was actually implemented. The job paid well, but I'm glad I'm not there any more.

If this attitude is pervasive at your place of work, I would at least consider other work options.

2
  • No employment lasts forever; you must make sure that you learn what you can so you are better qualified the next time you look for a job. Your boss doesn't care; he only cares about his profit. (Good bosses realise that it benefits them if you learn, because they get a better employee, and smart employees stay longer).
    – gnasher729
    May 11, 2014 at 1:42
  • @AlexD, did your boss happen to have very pointy hair? Were your coworkers named Wally and Alice? :)
    – Phil Perry
    May 12, 2014 at 13:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.