184

I recently had a job interview in which they gave me an hour to write some real code. It wasn't a huge amount, probably less than 100 lines. After about 45 minutes, I compiled, ran it, and got it to work. I may have spent 5-10 minutes working out compile errors and a couple minor bugs, but overall it was very smooth. (Incidentally, I did get an offer from them.)

However, what puzzled me was that after I handed over the completed code, the interviewer told me that the only thing I did wrong was "not compiling as I go along". I asked him what the difference is, and he said "what would you have done if you finished the code and it didn't compile in time".

In my understanding that's an invalid argument, because "getting code to compile" for a given length of code generally involves fixing a constant number of compile errors and takes a fairly constant amount of time, which should be the same whether you do it after you finish writing the code, or if you interleave it with your coding time. If anything, interrupting your coding to search for missing semicolons would probably be detrimental to your efficiency. Except in extreme circumstances when I'm experimenting with obscurities around edge-cases on things like virtual functions in derived classes, etc. it seems reasonable to expect that code written by a an experienced developer will compile, minus the occasional typing error, and even if it doesn't, it's not as if I would have to rewrite a portion of the code in order to fix the compile error.

In another similar incident, I was given an incomplete codebase in an interview, and asked to finish it and make necessary modifications to get it running. I started by reading through the existing code, and then after a few minutes (even before I had finished looking at the code), the interviewer told me that's enough. When I asked him what he would have done (i.e. "what did I do wrong"), he told me that he would have started by immediately getting the code to compile.

Why is that even relevant? In my opinion and in my experience, whether or not a piece of code compiles is essentially random, involving things like whether or not semicolons are missing, and has little to do with the correctness of the underlying program. (To me, focusing on compiling is like running an article through a spell-check without proofreading to check the grammar.)

If you give me a piece of incomplete code, the first thing I do will be to read it. I won't even try to compile it until I know what the code is doing and I know the algorithm is correct.

Anyway, these have been just a couple recent incidents, but in general I've heard many developers talk about compiling their code as they go along, and yet nobody has been able to tell me the benefit of doing so. I understand the benefits of testing your code as you go along, but why compiling?

So my question is this: Is there something I missed? Is there actually a benefit to compiling as you go along? Or is this some sort of myth propagated by the software community that you must compile your code frequently?

sakisk
  • 3,397

17 Answers17

218

Is there actually a benefit to compiling as you go along?

There is. It gives you a shorter feedback loop - which in general, when designing (UI, writing software, visual design etc...) is a good thing.

A short feedback loop means you can quickly fix errors early on, before they become more expensive to fix.

To borrow your example, say you were coding in a C-like language and forgot a } somewhere in the middle of the program.

If you compile just after you finish writing the statement, you can be quite certain you have just introduced the compilation error and can fix it there and then, within seconds.

If you don't, however, you would have to spend a good amount of time reading the code, looking for the exact position that the } is and making sure, once you have located the error that the fix is indeed what was intended. This would take place a while after you left that bit of code. It wouldn't be as crystal clear as during the moment you wrote it.


Now, yes, the end result is the same, but you wasted a good amount of time on syntactical issues that the compiler is there to help you with - an amount of time that could be significantly shorter if you compiled as you went along.

Oded
  • 53,734
106

Compiling is a form of test, especially in languages which make extensive use of types such as Haskell or ML. In other languages it's a syntactic scan that tells you little.

Having said that, "compile as you go" seems to me a very situational habit. You could equally well be marked down for being "twitchy" for compiling more frequently than the interviewer's personal prejudice. It sounds like nitpicking; nobody likes to admit that an interviewee has aced the test; it tips the scales of the salary negotiation.

Not all build systems are fast. I worked on a (C++) project where Make would spend 30 seconds just stat'ting everything to determine whether it needed to build or not, and most files would take a couple of minutes to build if you had made changes. We were reluctant to do this more frequently than every 10-15 minutes. Someone will no doubt supply an anecdote of when compiling involved taking your deck of punch cards and carrying them to a different building ...

Compile when you feel you've done a complete conceptual unit in your head and are ready to have it validated. Once a minute or once a week depending on the workflow.

pjc50
  • 15,223
32

So my question is this: Is there something I missed?

Yes: your mind is not a compiler. While a compiler can make n context switches per second, your mind cannot. The number of context switches your mind can make in a day depends on a number of factors like experience/familiarity with code base, how mentally immersed you are in the code, how clean the code is, how complex is the problem you are tackling, how tired you are, if you are frequently interrupted or in a noisy environment and so on.

Compiling a code base (all at the same time), for the first time (think "project with 20 files") will force you to switch context from what you are thinking about (e.g. "this value is set to 5 here, then in the for loop blablabla, and the complex algorithm yields the correct value on return") to a compilation problem that is completely unrelated to what you are thinking about (different file/module/function/pre-conditions/syntax/variable names, preconditions etc).

The more code you compile at once, the more context switching your mind has to make. This is not a problem for a small code base, when all the code you wrote is whatever you wrote in one hour. It is a big problem though, when working in an existing code base, with multiple (and many times undocumented) interdependencies.

Is there actually a benefit to compiling as you go along?

You minimize the context switches your mind has to make, allowing you to focus more on the impact and side effects of the changes you make. It also makes you less tired (and less prone to mistakes) and increases the quality of your output (i.e. you can guarantee minimized side effects easier when you change and compile one file at a time, than when you compile and change ten).

If you compile in very short iterations (this assumes the compilation process is optimized to take a short time) it is possible to fix compilation errors without getting out of "the zone".

Or is this some sort of myth propagated by the software community that you must compile your code frequently?

It is propagated by the software comunity as well, but it has good reasons behind it.

In my understanding that's an invalid argument, because "getting code to compile" for a given length of code generally involves fixing a constant number of compile errors and takes a fairly constant amount of time

It sounds to me like you have little (to no) experience, in maintenance of medium to large legacy code bases (hundreds or thousands of source files). This is where this attitude (i.e. "compile as you go") will help the most, and this is where you form this kind of habit.

I would imagine that the people who inteviewed you drew a similar conclusion ("you have little to no experience in large code bases").

utnapistim
  • 5,313
26

I think there is more than a little professional snobbery here. The implication seems to be "if you've never had the need to compile regularly then you've never worked with anything that complicated - go get some more experience and come back when you've learned to work exactly the way we do."

But obviously there is another side to this. Some projects take an age to compile. I've worked with frameworks that take 30 minutes or more to compile after even minor edits. Heaven help you if you ever need to edit a header file. Full recompilations are typically done overnight, and if you're relying on the compiler to catch your mistakes there are still rare errors that won't be detected during a partial build. You just don't re-compile every 5 minutes under these conditions - unless you're feeling lazy.

The compiler cannot help you with logical or semantic errors and syntax errors really aren't so hard to avoid that spending half of your day compiling becomes worthwhile. Of course, you'll make the occasional typo, but I'm going to assume you can both touch-type and read. If you have the freedom to choose, use a coding style that makes good use of layout to visually highlight errors and you'll never drop a brace, bracket or semicolon ever again. It takes a little practice and a little more discipline than most are used to, but it is possible. I can write code for a couple of hours at a time, in a plain text editor, and compile it first time better than nine times out of ten. Sure, I could compile more often, but I can't remember the last time I had an error that would have been easier to correct as a result.

If you aren't a fan of constant recompilation, you're in good company. Here's Donald Knuth:

As to your real question, the idea of immediate compilation and "unit tests" appeals to me only rarely, when I’m feeling my way in a totally unknown environment and need feedback about what works and what doesn’t. Otherwise, lots of time is wasted on activities that I simply never need to perform or even think about.


All of that being said... if you're working in a context where compilation is a free action, why wouldn't you? At home, on personal projects, I hit ctrl-S about once every 30 seconds and the "compile" shortcut nearly as often, in an IDE that constantly runs the code through the compiler's front end to provide real-time error highlighting. Why pass up a free lunch?

21

There are merits to compiling as you go. But I very much agree that staying on task is an OK coding strategy.

The most significant benefit to incremental compiling is the mentality many get in if they wait for the end to compile and test: we're more concerned at the end in getting the code to run than anything else at that point. We say "Oh, just need to add this bracket so the compiler stops complaining" or "oh just need to capitalize this" without thinking if there is an underlying semantic error that this syntax error hides. I really do find syntactical errors often nest themselves in semantic errors (the converse not true).

As an example, say I changed a variable's meaning and as a result, changed its name. The name change generates a syntax error later on in the code but if I just please the complier by correcting the name, I've ignored why that error came into existence.

Lan
  • 475
15

I understand the benefits of testing your code as you go along, but why compiling?

But how will you test your code as you go along when you don't compile accordingly?

The extreme case is test-driven development (TDD). It is obvious that TDD does not work with your strategy, since TDD means extremely short cycles of write-test, compile (should fail), write-code, compile again, run-test, fix-bugs, compile again, refactor, compile-again, run-test, and-so-on...

So not everyone does TDD, at least not always (me too, I admit). With your current strategy, you will never have a chance to even try TDD. But even when you are not doing TDD, it is IMHO extremly helpful to test your code more regular - which is not possible when you don't compile it regularly. And when your test fails, you have running to debug it (which can help you to understand why the nice looking algorithm you have written some minutes before does not behave so nice as you thought it should do). And the more code you write without compiling, the more code you write without testing, so the more likely it will happen that you run into a case where you cannot predict that the time to fix the problem is "O(1)", as you wrote.

jub0bs
  • 109
Doc Brown
  • 218,378
14

I actually agree with you that compiler errors should be no big deal for an experienced developer. I don't think the cost of fixing them increases significantly enough over time to worry about. If it were possible to postpone fixing all the compiler errors until just before a push, I would do so, as it would present a much smaller and more consolidated interruption.

Unfortunately, finding compiler errors isn't the only thing compilers do. At the risk of stating the obvious, compiling is required to run your program, and running your program is required to find all the more complex, subtle, and interesting runtime bugs that even experienced developers create. And those types of bugs are more difficult and therefore more expensive to fix the longer you postpone debugging them, because they can build on or mask each other.

However, I wouldn't necessarily mark someone down in an interview exercise for postponing compiling until the very end. Interview exercises tend to be very straightforward, and experienced developers usually know their limits. The more confident you are about what you wrote, the longer you will go between compiles. That's just human nature.

In order to not mark you down for it, the confidence would have to be justified, though. If you had spent 45 minutes writing something without compiling, then required another 45 minutes to debug it, I would have weighed that heavily against you.

Karl Bielefeldt
  • 148,830
9

The one important thing about compiling often, missing from other answers as far as I can see is this: if you compile rarely and get a large amount of compiler errors, most of those are meaningless, because they are generated by the first error. It could be because you had wrong type, or typo, or plain syntax error which makes some declaration invalid.

You could always just fix the first one, recompile, fix the next remaining one, and so on, but with large code base this can be slow. But if you try to skim through the long list of compiler errors and spot errors which are independent, then you spend a lot of time reading irrelevant messages, or navigating code from secondary error spot to actual cause.

Another thing going for regular builds is, nothing stops you from starting to compile as soon as you have a complete block of code written, which should compile. You can then continue writing more code while compilation goes on, just as long as you don't save the new edits until compilation finishes. So there's practically no time wasted on waiting for build. If you wait until you have written everything you are going to write at that time, you then have to wait for compilation without nothing to do. This is basically the manual version of what modern IDEs can do in the background automatically.

hyde
  • 3,754
3

No, it's not unreasonable to hold off compiling until you've done a sufficient amount of code (and a 'sufficient amount' depends on the coder and the code being written).

For example, if you're an awesome coder who takes his time to get it right, and you're not writing massive amounts or convoluted code, then compiling regularly is a waste, and probably a distraction too. If you're not, then compiling every function can be a good thing. It depends on the person.

As a counter-example, imagine you're writing JavaScript code - there is no compiler. Instead (given the nature of most JavaScript code) you would run the program (or refresh the page) to see the results of your coding. Now, you cannot do that until you're written enough code to make sense. As a result, JavaScript developers tend to "compile" as often as they can, which isn't necessarily very often.

In short, there's no correct answer here - the interviewer isn't wrong, but neither are you. Do what makes you productive and forget what anyone tells you you're supposed to do. There are much more important factors about coding than your tendency to hit F7 regularly (or not) is of absolutely no consequence.

gbjbaanb
  • 48,749
  • 7
  • 106
  • 173
3

For a sufficiently experienced programmer compiling code is never the bottleneck.

Once you know a language well enough (i.e. when you no longer have to think about the syntax and instead just code for functionality) you tend not to make simple syntactical errors. Those you do make are usually typos or copy-paste bugs, and they can be cleaned up in short order with just a few compilation passes.

I regularly write code all day without compiling, then I'll compile and just fix up what syntax errors and warnings the compiler reports before I commit my code (with a note that says "needs to be tested!"). I have no problem cleaning up 1,000+ lines of C or C++ code in just a few minutes.

Debugging and testing on the other hand is what takes a while. Logic errors arise for all sorts of reasons and I have yet to meet a compiler that will tell me about the subroutine I totally forgot to write, or will notice that my binary tree doesn't work because I pasted node->left when it should have been node->right.

While I think it's generally unwise to fight with an interviewer, I'd say if you felt your style was worth defending you should have pointed out that you left yourself enough time to debug the code you'd written. That's the thing no good programmer ever neglects.

p.s. - If I had been watching you review code by reading it, I would have hired you on the spot. That's what a pro does, every time.

par
  • 455
2

With a good development environment I see little reason to compile unless you're actually planning to test code. The background syntax checking tools catch most everything that the interviewer seems to be talking about, although I will admit there are still a few cases (involving changes that propagate across files) that aren't always fully identified.

That being said, I will try to compile and run pretty much the smallest unit of code that can actually produce an outcome. Half an hour ago I was creating a means of printing some search results and I did half a dozen test prints (to .pdf, not paper) making changes to the result to make it look better--a rate of about 1 compile per 10 lines.

1

In my opinion and in my experience, whether or not a piece of code compiles is essentially random, involving things like whether or not semicolons are missing, and has little to do with the correctness of the underlying program. (To me, focusing on compiling is like running an article through a spell-check without proofreading to check the grammar.)

My experience is very different: less than 5% of compile errors I get are about syntax. I know the language well, when I get errors it's mostly type errors, telling me that the semantics are not correct.

This is why I am happy to benefit as quickly as possible from the feedback of my compiler. Have you ever experienced using an IDE which underlines compile errors in real-time? Having a shorter feedback loop can be very valuable.

If you give me a piece of incomplete code, the first thing I do will be to read it. I won't even try to compile it until I know what the code is doing and I know the algorithm is correct.

If you are expected to work on code written by someone else, you don't always have time to read everything. The good news is: well-written code has low coupling, and should enable you to reason independently about just the part of the code that you need.

In those cases you have to assume that the code you have not yet read is correct, and investigate lazily when there is a problem.

"getting code to compile" for a given length of code generally involves fixing a constant number of compile errors and takes a fairly constant amount of time, which should be the same whether you do it after you finish writing the code, or if you interleave it with your coding time.

Context-switching is costly for your brain, therefore fixing small errors as soon as you write them can be more efficient.

EDIT: I can also make an analogy with source control, when a whole team is working on the same sources. Compiling as you go along is like making frequent commits, it helps to avoid having a lot of pain at the end when you have to merge and sort out everything.

You say that you disable things like red lines under your text. Do you also do that when typing an email or writing a technical document? Then you have to proof-read again all the pages instead of fixing mistakes as you go.

Another advantage is, when working on your code, if you keep it compiling or near-compiling at all times, you can benefit from a lot of semantic-based IDE features (safe renaming, refactoring, finding uses of a symbol...).

If you want to have a better understanding of how these features help, you could try enabling them and practicing, to experience yourself their benefits. You could also try to do some pair-programming with anyone that is used to them, and see how they benefit from them.

1

I thought a bit longer about this, because I felt that there is something very, very wrong with the interviewer and couldn't exactly point out what it is. Here's the problem: For any code that I have written in the last twenty years, the amount of time needed to turn a workable algorithm into code that compiles has been minimal. Any gain in efficiency in that area has so little impact on total development time that it is totally negligible, and an interviewer who rejects a candidate for perceived inefficiencies in that area has no idea what makes a good developer.

Most time should be spent on gathering information what the code is supposed to do, gathering information and specs about outside services that need to be used, creating a global design that will lead to correct and maintainable code instead of hacked together code, and finding algorithms that will lead to working code instead of code that is patched together until it happens to work (code that has obviously no errors vs. code that has no obvious errors).

Then come a tiny amount of time writing code that compiles.

Then comes a larger amount of time spent to make sure that the code works, and to make sure that we know that the code works and will stay working. Which is done by writing unit tests, stepping through code, and to a large extent by having well-designed code in the first place.

This interviewer concentrated on something that is covered by ten words in my reply. Which represent 10 percent or less of the actual working time. And has almost zero influence on the ability of that developer to produce reliable and working code.

gnasher729
  • 49,096
1

The advantage of "compiling as you go along" is you get constant feedback, and won't have a chance to go far wrong before being pushed in the right direction. For a competent programmer like you, that's not a huge consideration, but for many others it is. Put another way, "compiling as you go along" is a way of "minimizing the maximum loss," even though there are some potential efficiency losses in your case.

Companies these days aren't just interested in a finished product. They want to know that it was "under control" all along. For them, "getting there is half the fun."

Tom Au
  • 893
1

The other answers here mount a good defense for compiling frequently on the job, but since your question is centered around interviews, I'd like to tackle that angle of it.

In my interviews, I do the exact opposite: candidates can't use a compiler. They write short programs on the white board and then we discuss them. I have found that too many developers use the compiler (or interpreter) as a crutch, and that is a far bigger waste of time than compiling too infrequently. If I'm offering you a lot of money and you can't even write FizzBuzz correctly without a compiler, then you're never going to cut it on a long term basis, working on problems that are 100x more difficult than the toy exercises in the interview. And yet these simple exercises weed out more candidates than any other part of the interview.

The goal of an interview is to evaluate the mutual fit of the candidate and the business. A good interview question should state the objectives of the question and how the interviewee will be assessed. Springing a trick question on the interviewee and then penalizing them for not knowing the hidden answer doesn't help the interviewer or interviewee. Unfortunately, most programmers — even senior ones — aren't trained to interview other programmers, so they just rely on clichés and ask the same types of questions they were asked when they interviewed, without much though about whether these are effective techniques for evaluating candidates or not.

I'm not claiming that my approach is the "one true way", but it has served me very well. Like so many software methodologies that start with a capital letter, there are an equal number of "mandates" for interviewing. They're all bunk. You need to do what works for you and your business.

0

In larger projects, with several subroutines, you want to test these parts, before using them in the larger scheme, since it is way easier to debug if you know certain parts already work.

In order to test these smaller pieces, you need to compile.

It might be that the interviewer confuses this situation with a small program that is not designed in this manner.

0

Regarding the second interview, a benefit of compiling is that you can observe, within just a few seconds, what the programs does (or doesn't). From there it is easier to read the code and to focus your efforts on the relevant parts. Perhaps this is what the interviewer was expecting.

Reading an unknown code base like this from beginning to end can be quite unproductive (you're not a compiler), while compiling/running the application will quickly give you a bigger picture.

laurent
  • 715