Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Coding tip: Leave your code in a broken state (plus.google.com)
120 points by mmahemoff on Jan 16, 2014 | hide | past | favorite | 61 comments


I understand the rationale, but I see a problem with this, and a better system.

The problem is that you might be juggling 30 things in your head while writing that code. When you come back tomorrow, you have to start remembering them all, and you're more likely to forget one of them, and spend time debugging later to fix the resulting lesser-quality code.

The better system (in my opinion) is to finish your code for the day, it will leave you feeling good and accomplished. But before you leave, write a to-do list for tomorrow's code, with detailed notes, while the code is still all fresh in your head. Then you can go home and not think about work, and truly relax, and know you'll get to the office tomorrow knowing exactly what you need to start with, and won't be forgetting anything important.

And I'm not sure the analogy with fiction writing is useful -- writer's can suffer from writer's block, so leaving a paragraph can help jump-start the creative part. I've never heard of programmers suffering from coder's block.


There are two separate problems.

One is getting something easy to gnaw on, to get into flow, to remove the inclination to procrastinate.

The other is picking up where you left off.


You have a point about not leaving with the big fragile stack inside your head. But see my example's TODO - it's really leaving after I've just resolved a lot of tension by solving a big problem and now I'm able to restart with more of a low-level grinding task. So I guess there's really more to it than just leaving the code in broken state. I mean it's broken in that you've deliberately created a syntax error, but the next step can still be very straightforward. Sort of like a broken test, which others have mentioned is a good variant of this practice.


I think conceptually that the hope is still the same.

If you leave your code in a broken state, it will take some practice, but the idea is that it will liberate you from having to try to carry the cognitive load, because you have a natural reminder.

Also, if you are juggling 30 things, you're likely not writing your code well as a principle; limiting your work in progress will allow your "breaking" to be limited to a specific function/algorithm/task/unit test (or whatever).


I prefer to write a pending test, that way I can just run my tests the next day and get into the groove again.


This is all well and good, but if you check in intentionally broken code, or if you fail to check in your code because it is intentionally broken, it will drive me bananas, and I will look for you, and I will find you.


By "break", I assume he toilet or coffee.

So I assume he means code that he hasn't checked in yet, but might do when he gets back if he can't remember what was doing and it compiles.

Personally, I like to check in broken code late on that Friday evening before I take 2 weeks holiday. Unfortunately, these days with these new fangled source control systems you can't check it out again and keep it locked while you are away.


I never check it in in this state. Checkins are 100% working and passing all tests for me.


Have you heard of distributed revision control? Local check-ins are awesome.


Unfortunately, that doesn't keep some idiots from pushing broken code to `origin master`.


Why can they do so on a mature project? Why can they not only push to their branch, have the repo have commit/push hooks for fast linting, have CI builds for each commit, and only merge into master when comfortable (e.g. after QA)? And if it's a fairly new project and they're working in master directly, what's the harm of broken code?


Even non-idiots make mistakes. Use the pre-push hook that comes with your repo: https://github.com/git/git/blob/master/templates/hooks--pre-...

Then, just mark your commits with WIP.


It's no trouble at all to work on a personal branch and merge it back in once it's fixed/complete. Especially if you're planning on doing it and are using a tool like git flow.


If you leave broken commits in the history, you'll make it very hard to use tools like "git bisect". You can "skip" broken commits, but that should be an occasional exception. It doesn't matter if that was on a personal branch either, because once you merge it's all part of the same graph of commits.

I have no problem with broken commits locally, but I don't want to see those in a public tree. Merge or rebase with squashing, please.


A rebase in the personal branch that squashes the broken commit into the ones that fixed it would remove any traces of broken code in the master branch.


> if you check in intentionally broken code ...

Agreed, but that's not what you should do.

Many times I have finished the day with a working commit and push, then I add a compiler-error "todo ..." line to the code locally so that it's clear where I have to resume tomorrow.


I practice a variant of this where I have some small, well-defined task to do at the beginning of the next day to ease into the flow of things, but the thought of leaving the code in a known uncompilable state (even if just my local copy of it) would just make me feel uneasy until I've gone and fixed it.


I'm with George on this one. I like to finish off a day with the atomic module/query/code I'm working on working nicely (optimized or not; it needs to function). Somehow, in my mind, it's like closing the trailing bracket. I like to finish the day 'clean'.

Sure, this might cause the next day to be a slower start, but you have to balance this out against the peace of mind you get from leaving the office and having no worry about. That is worth a lot (and might cause me to sleep better and be more productive the next day?)

It's like doing the dinner dishes before going to bed so you don't have to wake up to them (or not enjoying the rest of the evening because you think you'll have to do them in the morning).

Like George, I'll often plan my next day ahead so that I know what I'm going to do to hit the ground running (Optimize the code I wrote last night, add input error correction, cough add comments or tighten up the format ...)

All these things aside. Do what works for you!


As the OP, I get that mentality and have it too. One could call it an extremely mild and very normal kind of OCD we all have. For that reason, there are times (or moods) when I do the completion thing.

But because of the motivation benefits, I also try to bend my brain to focus more on the checkin as the snapshot that must be pristine in any time slice, and the editor as just a flowing set of arbitrary frames between checkins.


Personally I try to make the code work by the end of the day as kind of a motivational thing. (Like you described above.)

Also, to be pedantic, I think it would actually be a mild kind of OCPD.


I notice a definite sense of satisfaction if I finish the day with things working as opposed to not working (especially if I have been working on that feature for more than a day). Though the scope of my tasks varies so much it is difficult to "try and make the code work by the end of the day". I don't think I ever plan anything that I think should take more than a day, but more often than not downloading a new library and configuring it to work should be simple and takes as much time as any coding. (Still it will likely be quicker than me writing all the functionality and tests myself).


>I practice a variant of this where I have some small, well-defined task to do at the beginning of the next day

I start with some large task, with the intention of getting fully absorbed and in the zone. Then get interrupted to fix an excel upload error - users who insist on using excel also seem to be the ones who are incapable of reading error messages. Then someone asks me a question about something. Turns out a 2 line bug/change needs fixed. Might as well do that before I get into the zone. "Can you get a list of all projects with blah, blah". Might as well do that before I get in the zone as well.

Before I know the day is gone and I have achieved nothing satisfying.


What I like about leaving it uncompilable is that way, I know I won't forget to finish that unit of work. Sometimes I'll leave it uncompilable, sometimes I'll just leave my self a little note with what I've done, and what I have left to do.


I'm more in this latter camp. I'll perhaps leave it completely compilable, but with logic incomplete, e.g. a stub function that always returns true. My task the next day is easy, then; it starts as finishing the stub, and as I do that, the rest starts flowing.

I've had days where I start by just running the code end to end and seeing what's egregiously broken, but I find this puts me in whack-a-mole mode the entire day and it's extremely tiring. Though, I do feel like Sherlock doing it.


Agreed in this regard. Whenever I have to leave in the computer before I have the chance to finish something, I usually just make a comment with the string `WIP` in it:

    /* WIP: make sure to initialize buffer by calling function foo() */
... the idea is that I'll remember that I left my code in an unfinished state, search for the `WIP`, get my bearings and then go off. Of course, that's easy to forget -- but impossible to forget if your WIP note is uncompilable.


If I have TDD set up...I'll add a breaking test...it's a little more verbose, but the fact that everything else passes gives me a nice sanity test when I revisit the code. And of course, unless I totally bunked the test, I can actually keep the test as part of the suite (yes yes, I'm aware that tests themselves become legacy code that demands maintenance and that nothing comes for free)


I call bs on this tests have a cost mantra. They may have value, i.e. be useful, and then it is ok to spent a few minutes fixing them if needed. But if fixing them is costlier than their expected value, then just skip them.

I see many reasoning for not writing tests everywhere and very few reasons are acceptable. In some cases in some non mockable languages it is really too hard, this reason is ok. The only other good reason to not write tests is "I don't want to."


My brother works in publishing and came very close to ruining a 6 figure order of calendars because he put his personal birthday on them to test his proof readers.

Don't break your code to remind yourself where to start.

Instead, leave a failing unit test. Not only does it tell you were to start but you also told yourself what you were doing ShouldDoThisNext().


I like to use a syntax error if I'm implemented in the middle of a number of related changes. As long as I follow basic hygiene of running/compiling the code before committing, I'll be reminded of where I was.

I typically use '...' for this, since it is/was invalid syntax in pretty much all languages.

Then perl went and added it as a placeholder...

http://search.cpan.org/~jesse/perl-5.12.0/pod/perlop.pod#Yad...

so it now compiles (but will at least throw a not-implemented error).


I believe this tip originated from writers. By leaving your thoughts incomplete, but with an end in mind, you can begin writing the next day and get into the flow immediately.


I think this is backwards from what works for me. For me, the difficulty is always in starting something new. It doesn't matter what time of day it happens, if I finish something, and I'm proud of it, I have almost zero motivation to get to work on the next thing.

I get that you're trying to prevent morning lethargy from coinciding with decision avoidance, but I think I have a better system. Don't end the day just before you finish. End the day just after you start, just at the part where it starts getting good. The next morning, you'll be excited to come in, because you know what to try next.

You can ride that high into your morning standup, confidently say "this is what I will do today," and ideally a half hour before quitting time, you'll finish what you're working on, and while you might be tempted to say "done enough, time to go home," you won't do that. Instead, start on the next thing. Spend 30 minutes figuring through it. Figure out an approach, write it in your journal, and then go home. Start implementing again tomorrow, and repeat the process.


I like the idea, but I find it really difficult to actually stop when I'm "in the zone". I tend to recognise when I am and treasure those moments of hyper-productivity to get lots done.

I use the technique in the article and have for a while. I find that the relatively easy task of fixing a compile error will gently lead me back into coding.

I expect it's a personal thing, though.

As an aside, I like to leave a bunch of TODOs lying around in code for things like documentation, so I can come back and do that boring stuff when I'm feeling brain dead. I never use TODO for something important that needs to be done because chances are it won't! (I don't know why, I think it's just something about the nature of TODO).


I won't leave code intentionally broken, but I always save some small trivial task for the next morning to immediately get into the swing of things. I really like being able to come in first thing and get something done, even if it's small. If the first thing I have to do requires a lot of deep thinking, I'm likely to procrastinate.


>If the first thing I have to do requires a lot of deep thinking...

That's why I try to think about what I have to think about, the night before. E.G. Try to enumerate all possible solutions/causes to a problem (most likely to least likely) to give yourself something to just dive into the next morning.


Does this affect your sleep? I occasionally think about tomorrow before I go to sleep, and I find that my sleep that night was not as restful as it could have been.


I noticed this recently. I started my job 3 years ago, building a database system from scratch for my organization. Learning Django, and building something new sparked my interest in coding again.

3 years on, it is now mainly maintenance programming, actually fixing stupid excel upload errors (I have argued for hours that we should not be using such an inappropriate method for uploading data, but important people insist).

Anyway, the point is, I don't usually bring problems to my sleep with me (I have outside interests). But recently I was asked to add a new feature. It turned out to be a complex problem - along the lines of the P versus NP problem. Now this got me thinking. In my sleep. I did have strange code like dreams (not had that since studying at university). I wouldn't say I sleep badly, more with a sense of excitement (excitement may not be the exact word, but something similar).


In my C# code I like to leave a "throw new NotImplementedException();" behind if I can't finish something. I'm with some of the other posters though in that I like to leave stuff working at the end of the day.


Do you then add a test that fails from this exception?

Otherwise, you are simply leaving a bug that is only discovered at run-time rather than one that is discovered at compile time. Doesn't seem like an improvement to me


Seems like an improvement to me! And I'm the one doing it, so I'd know.

And for your information...I do have a test, but it doesn't fail, it returns positive. I search for "NotImplementedException()".


#pragma warning DOH!!!


Better yet:

Vim can save a session via :mksession file_name.vim which can then be restored by vim -S file_name.vim

It's nice when I have to quit programming while in the middle of task where I'm drowned in context spread across multiple tabs and splits. I'm not trying to spread the Vim gospel; this feature is nothing really extraodinary so I guess it's available in other editors/IDEs as well.

Overall this is roughly equivalent to putting your machine to sleep mode while your edition session is still on.

My personal opinion is that both methods make OP's look pretty primitive and hacky.


I am an IDE (Aptana / Eclipse) user.

VIM / Emacs sound like they have so many cool features. Can someone not build a decent interface that doesn't rely on remembering cryptic commands for all of the features?

To people who know both. Would it be worth me learning either Vim / Emacs in this day and age? Eclipse has a lot of features and plugins. And way more intuitive interface (I use git through it, without having really learned all the syntax and options, it does most of what I want).

Vim / Emacs seems like a lot of learning (that I could spend on possibly more useful things). Opinions?


Similar but more general advice I got early in my career, was to not try to leave work with everything in a tidy state. If you are hunting a bug, for example, you'll be tempted to stay until you've fixed it, or at least understand it. Don't do that. Go home. Your mind will continue to work on the problem subconsciously and you may very well wake up the next morning with new insights.


I believe Ernest Hemingway invented this technique (or the writing equivalent, on which this is based).


My code is always in a broken state...


I know you're joking, but I've heard this 'tip' before and am puzzled because there is always a backlog in my head of "shit that is fucked up" on any given project. There doesn't seem to be any need to throw some made-up bug on top of that list for me to have something to start fixing if nothing else comes to mind.


There is also unspoken benefit of this - training yourself that IT IS OK to leave code in broken state. An feel good about it. Too many developers kill themselves by trying to end the day in a perfect code state. And it has nothing to do with happiness :)


As long as this stays local, or on a secluded branch, why not... but if you push a broken commit to master then you fix it immediately. And there's no place in a team for someone who intentionally pushes broken commits to master.


TDD.

When you get to work, run your tests. All green? Great! Write some more tests that fail then make 'em green again. Failing? Even better, now you have something to fix.

TDD made programming 5x more fun for me.


I actually do this sometimes when it's near the end of the day and I know the problem at hand might cost a few hours. I'll write a comment but not in a code comment, exactly like the article suggests.

Funny enough, it never had to serve this exact purpose and had I written the comment so that it wouldn't prevent a build, I would've still continued where I left off. I think (but am not sure) the fact that I wrote it down at the end of the day makes sure I don't forget.


my gut reaction here is to cringe and generally be revolted.

with some thought it seems like an okay idea... it gives you a place to start in the morning that is easy and helps you overcome the 'start working' hurdle at the beginning of the day.

with more thought it reveals bigger problems in methodology which enable this to be practical imo. ranging from not having a plan through to not having discipline.

imo you should be able to leave things in 'a convenient state' which may be broken or not, and then pick it back up... as long as you are working to a plan, and the code is sufficiently clean and friendly then you should be able to approach /someone elses unfinished work regardless as to what state it is in and start working immediately/.

On the other hand I know that most people struggle with reading code... maybe this is part of the problem more than anything else?

The context switch involves some dallying around reading code and making sense of it in the morning - I don't see how leaving things broken removes this. Rather this seems like a prescribed way to force yourself to leave at least the bare minimum documentation you should to do your job as a programmer with a little more efficiency.

Write things down, don't trust your memory, its easy to think when you are in your late teens or twenties that its an immutable record and highly reliable - especially if you have been inflicted with an especially good memory - the truth is that its a bug riddled system where data constantly degrades. Work around it like you would any other faulty system and keep backups too...


I totally agree with this. Leaving things working... partially, is the best way to forget tomorrow and ship half finished code with tomorrow's distractions.

I also find this is a good strategy to step away from something and renew your perspective on the solution after a good break. Especially at the end of the day. That's worst the 'I just want to get this working by poking around, not writing unit tests' leave here in a rush, trap time.


Don't do this. Try and leave you code working at the end of the day. What I do instead is leave a bunch of @todo comments in my code when I'm done programming. This does two things: It gives me some obvious starting points tomorrow and leaves those tasks fresh in my mind as I go through out the rest of my day. I often come up with really great solutions just from writing a very simple @todo sentence.


I've been doing this for years. If it's a compiled language, I prefer a compile error. It's easy and I might as well get SOME value for the compiler, as specious as it may be. If it isn't, I stick to a failing unit test that was asserting the last unit of work I was working on. Helps me get into the "zone" faster and I feel less anxious about getting started in the morning.


I usually do this end of the day, just throw in some pseudo code for what I want to accomplish the next day. In the case of Rails I still have to learn about everything, so it is really easy to adhere to this practice :)

However it is a bit conflicting, I don't necessarily want to commit this stuff, but I always want to push my work in case of disaster.


This is great advice, and something I do all the time with #warning and #error (works with both Clang or GCC, not sure about other compilers) for partially completed methods or to-dos. When I'm mid-project I'll have "#warning TODO: Fix this" and the like all over the place.


I keep a notes.txt and errant random files in a folder hidden in .gitignore and keep that open in sublime text, or else just leave myself a note in a comment at the top of the main source file. It's easy enough to break my stuff as it is.


Along the same lines,

Write a function that captures your TODO's, and set an urgency level. If the urgency is high, make it a fatal error (or whatever in your given language).

This is a great way to make TODOs much more functional and actionable.


What a great idea! I'm going to try it.

All too often I dither around for an extended time when starting. Then, when finally started, everything just flows.

Maybe this will help reduce dither time.


Pen and notebook (paper type, not a knee burning laptop), with a checklist of things to do tomorrow works for me. q


I have to try this out to




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: