5

In the University one of the lecturers was insisting on a piece of advice I found odd.

This lecturer insisted that his pupils do not care too much about decisions like the choice of the programming language, target platform, or other design choices that are not strictly necessary to make a working prototype. When people were protesting that creating something that is known to be broken is a waste of time and waste of work, the lecturer argued that:

What programmers often do not realize is that code is being constantly rewritten. Look at most successful companies, Google for example, and products, World of Warcraft for example: They don't maintain their code, they rewrite it. I already lost count how many times the engine of WoW was rewritten and replaced by a new version. Rewriting code, even in another programming language and under changed requirements, is not hard once you have a working prototype; what is hard is making this working prototype. You can carefully choose your programming language to meet the requirements of your target platform and to achieve necessary performance; you can worry about the quality of your first iteration of code; then writing your first iteration will be much more difficult and time consuming and after you're finally done you will realize you have to rewrite your beautiful code because your code's quality is nevertheless unsatisfactory as it is impossible to determine how a code should look like without writing it first, not to mention changed requirements. Instead, focus only on making a working prototype, without caring for anything else; then, once you have it, make an informed decision how to fix the code and how to adjust it for your particular requirements and rewrite your code accordingly, this time caring for its quality; then possibly rewrite it once again before releasing it. If your product is successful enough to enter the maintenance phase you will also be periodically rewriting code whenever a need for a relatively major change arises.

In particular, this means that we should not care too much about the quality of the code of the prototype and write it in Python if we like Python even if we know that Python is unavailable for our target platform.

(I tried to summarize the lecturer's opinions above, hoping that I understand them well and that I didn't misrepresent them).

This is a direct opposite of the usual recommendations to always put an utmost care for the quality of one's code and as well as a direct opposite of this popular essay. What can be said about this piece of advise?

Philip Kendall
  • 22,899
  • 9
  • 58
  • 61
gaazkam
  • 3,517
  • 3
  • 19
  • 35
  • Possible duplicate of [Develop fast and buggy, then correct errors or be slow, careful for each line of code?](https://softwareengineering.stackexchange.com/questions/99980/develop-fast-and-buggy-then-correct-errors-or-be-slow-careful-for-each-line-of) – gnat Jan 04 '18 at 12:21
  • @gnat I don't believe this is a dupe; the other question asks if the code should be first written sloppily and then *refactored*, while I'm asking if we should *refactor* code or *rewrite* it! – gaazkam Jan 04 '18 at 12:22
  • And also I'm asking if we should write code slopilly first and then rewrite it or if we should be slow and careful. But this is still a different question. Refactoring != rewriting – gaazkam Jan 04 '18 at 12:24
  • "_I already lost count how many times the engine of WoW was rewritten and repleaced [sic] by a new version_" Where can I read more about this? – Caterpillar Jan 04 '18 at 12:35
  • @Caterpillar To be honest ,Dunno. This is what my lecturer said. – gaazkam Jan 04 '18 at 13:02
  • @Caterpillar I linked this myself – gaazkam Jan 04 '18 at 13:13
  • @gaazkam Oops, mea culpa! – Caterpillar Jan 04 '18 at 13:19
  • @gaazkam, I would say it depends on what sort of company you end up working for. If it is a cowboy outfit writing code for non-critical systems, then your lecturer may be right. But if indeed you are working for a large company that has a public reputation, like Google or Microsoft, or in a regulated industry, it is very unlikely either that serious faults will be tolerated or that major rewrites will be embarked upon frequently. Perhaps there was a subtlety in your lecturer's argument that has been lost in translation. – Steve Jan 04 '18 at 15:47
  • 1
    Possibly relevant: [When is a BIG rewrite the answer](https://softwareengineering.stackexchange.com/q/6268/64132) – Dan Pichelman Jan 04 '18 at 16:23
  • 1
    Most university professors live in an alternative universe that has nothing to do with reality. This guy sounds like he's never actually had someone to pay him to write software, not for a long time at least. – Andy Jan 04 '18 at 23:17
  • When it comes to apprentice, [Quantity Always Trumps Quality](https://blog.codinghorror.com/quantity-always-trumps-quality/). (The book cited in the article is : https://www.amazon.com/dp/0961454733/ )However, after one graduates from school and looks for job, code quality will be one of the factors being judged by interviewers. – rwong Jan 05 '18 at 08:03
  • I think the (correct) summary is **not to let perfection turn into a fear, a fear that prevents you from getting lots of code-writing practice**. However, make sure you are improving each week, each month, that you are not merely repeating your older self. The part about code being rewritten depends on the type of workplace and software product. – rwong Jan 05 '18 at 08:08
  • @Andy, agreed about (some) university lecturers! Many of whom are not professors, and seem to obey the principle of "Those who can, do. Those who can't, teach!". Many quite experienced lecturers struggle to grasp the importance of, the need for, and the irreducible complexity of, the *integrated design* of software. If you knock out code that is poorly designed and integrated, you'll be lucky if it even gets put into use before having to be thrown away and re-written - and the design challenge of an isolated "working prototype" may be very different than that of a whole integrated system. – Steve Jan 05 '18 at 12:14
  • Anyone who thinks Microsoft throws out and rewrites regularly should take a look at the "Have Disk" dialog of the driver installation wizard in windows 10. It's identical to Windows 95's – Caius Jard Jan 06 '18 at 08:56

8 Answers8

14

In the University one of the lecturers ..

Sounds like an academic who is suffering from the Dunning-Kruger effect. But maybe you have just misinterpreted some of his statements.

Rewriting code, even in another programming language and under changed requirements, is not hard once you have a working prototype

When you only have a working prototype, and that prototype is not very large, then rewriting the code is probably not too hard, because there is not much to rewrite. However, once you have a successful piece of software developed over several months and years, and a solid user base, a complete rewrite becomes more and more harder. It makes a difference if you try to rewrite 1k LOC, 20kLOC or 400k LOC, and that wisdom is mostly independent from the programming language. And I am sure major software companies like Google or Microsoft don't throw all their major products' code over board every year and rewrite it all again from scratch, that would simply be not economic.

what is hard is making this working prototype

Making a first prototype is surely harder than doing it the second time when you have the first one built before, and as long as someone does not fall into the trap of the second-system effect. But the really hard part comes after that - making a quality, stable product. And since you quoted Joel Spolsky, let the quote him too: good software takes ten years.

Instead, focus only on making a working prototype, without caring for anything else; then, once you have it, make an informed decision how to fix the code and how to adjust it for your particular requirements and rewrite your code accordingly, this time caring for its quality.

Of course, "time-to-market" is often much more important than code quality when bringing a new idea into a competing marketplace, that is true. Prototypes are important for demonstration purposes, marketing, proof-of-concepts. Replacing the first prototype by a fully rewritten version then may be the most sensible approach. Not rewriting it when code quality was sacrificed for getting the thing out of the door during prototyping maybe indeed a huge failure - but often devs have to convince their superiors about that, otherwise they get forced to build a whole system on that prototype, with no chance ever to switch to a different architecture.

If your product is succesfull enough to enter the maintenance phase you will also be periodically rewriting code whenever a need for a relatively major change arises.

First and foremost, you will constantly refactor the code of such a product. You may also rewrite some parts of it from time to time, if evolving them in small steps doesn't seem possible or affordable any more. But you surely want to avoid throwing the whole thing into the dustbin and start all over. Trying that will lead to the kind of desaster mentioned in Joel Spolsky's essay you already mentioned.

This lecturer insisted that his pupils do not care too much about decisions like the choice of the programming language, target platform, or other design choices that are not strictly necessary to make a working prototype.

That recommendation is fine, at least for this audience. Don't forget at a university, pupils typically don't start a long-term development for some commercial product, they start with learning projects, and 99,9% of those will be thrown away either, independently of the code quality.

So TLDR; most of what your lecturer said is ok when applied to small prototypes, in his academic environment, but you should not misinterpret it as a recommendation or an excuse to sacrifice code quality in bigger, commercial software systems.

A final note on

... write it in Python if we like Python even if we know that Python is unavailable for our target platform.

How often do you encounter a situation where a prototype has to be created on a platform which is so different from the target platform that Python is not available on the latter, but it makes sense to use Python on the former? Not that such situations don't occur, but this looks to me very contrived.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
8

This is something that I would be very wary of in a private company. I have personally encountered a number of times that a 'quick and dirty' prototype has been put in place and that 'prototype' has then subsequently been sold as completely working software.

Very often in these circumstances, very little time is then available to rewrite from the start, so your prototype gets some polish and then shipped, adding to the bottom line for the company.

In short, while prototyping can by it's nature be a bit rough, you should always keep an eye on what the final product may be.


I would note that actively coding your prototype in a language that is not available on the platform that it will be shipped on would seem like a way to get around this problem, however it's not likely to make you too popular with the management...

Paddy
  • 2,623
  • 16
  • 17
  • 3
    +1 Prototype software always ends up as products, with promises that there will be time to pay off tech debt/refactor/rewrite at some point in the future. Because business people rarely see those three things as providing value to customers, they're rarely given resource and so that time rarely comes. – GoatInTheMachine Jan 04 '18 at 14:45
  • 2
    You'd think they'd figure it out when the time saved by cutting corners ends up equalling the time lost from fixing bugs at the last minute, so that ENG's original estimate for doing it _right_ ends up being correct anyways. ;) – jscs Jan 04 '18 at 21:25
  • 1
    That work *might* pay off hugely in the future, but cutting corners pays off a little bit *now*...alas short term gains always win for the majority of people! – GoatInTheMachine Jan 05 '18 at 11:07
3

What I find is that when presented with 2 extremes the answer is usually somewhere in the middle. Another great read would be The Cathedral and the Bazaar, which on the surface would seem to echo your professor's statements. I think the intent behind what your professor was addressing is this:

Stop worrying about how to start and get something written.

Paralysis by analysis is a very real problem that students fall in to. It's because they have too much theory and not enough real world practice. Get some real world practice to find out if what you think should work actually does.

If he stopped there, I don't think there would have been any confusion.

There are some statements that need clarification:

  • Real world software is rewritten regularly, but not as regular as your professor's comments would seem to indicate
  • Student projects aren't really intended to be works of art, they are abandonware--written for an assignment and never touched again
  • If you happen to have a good idea from a school project that you think you can make into a real product, it's probably better to write it with that in mind

However, in the real world, you will have to maintain software that other people have written. The fact that it isn't done the way you would have done it doesn't mean it's bad or needs to be re-written. When a company is willing to rewrite software it's because of one primary reason:

The cost of rewriting the software to enable the current needs is less than shoehorning the feature in to the software.

Most developers I know are very conscientious about writing the software as well structured and designed as they can within the schedule and skill constraints they have. They tend to work iteratively, building new features in a little at a time. If the schedule allows, they prefer to clean up by refactoring as they go along. Unfortunately, schedule and pressure from management to deliver force some to cut some corners with "good enough" solutions. If we didn't have the schedule the release cycles could be far too long to be competitive.

You'll find that:

  • If you do it early enough, most ugliness in software can be fixed with small refactorings
  • If you focus on getting just enough working for your requirement, you can clean as you go

Just remember that ugly working software trumps beautifully architected non-working software every time.

Berin Loritsch
  • 45,784
  • 7
  • 87
  • 160
2

I think you may have misunderstood your lecturer's statement that "code is constantly being rewritten".

If a bug is discovered in production code, you don't throw out the whole thing and start again. You find the bug, you fix it, you test it, you deploy. And this is very difficult to do if the code is an unreadable mess.

That said, it's important to differentiate between prototype code and production code. If you're just exploring a concept, then it's okay for prototype code to be rough around the edges. However, at the point at which you decide that the concept is worth turning into a fully fledged product, then yes you should rewrite it with a view to stability and maintainability.

Pete
  • 3,181
  • 1
  • 12
  • 18
2

While the lecturer's opinions sound crazy, they do make sense in context.

The one important point is that your "product" might not be your whole business. It might be just one service that is small enough that rewrite might be good idea instead of building hack over hack. This is case in both Google and WoW. They are not huge monoliths, but composed of many small interconnected services, where each can be rewritten independently. This is why Microservices are getting popular nowadays. Having each microservice built using different language or on different stack is not only possible, but even recommended. The problem here is that many people's experience with software is with huge monoliths. In which case, idea of rewrite is as crazy as it sounds. So to make this kind of "rewrite when necessary" mentality, the whole product must be divided into small, loosely-coupled parts. Which is not so common in our industry.

Another thing that comes to mind is tha quality doesn't mean just code quality. Software quality is broad concept, that encompases code, testing, documentation, etc.. And testing is the important part here. If your code has solid suite of automated tests, then rewriting it is trivial. But again, this is not something that comes for free. Good tests are expensive and hard to create. But once you have them, the code becomes as pliable as putty. It becomes way too easy to refactor or even outright rewrite parts of your application without worrying about breaking anything. And I do believe both Google and WoW do have big suites of automated tests.

To sum up : Idea that code can be drastically changed or even rewritten is valid and even encouraged, when you make sure that your whole product is split into small loosely-coupled units and big effort is put into building and maintaining automated tests for those units.

Of course, this is just my interpretation colored by my experience. I might be wrong and the lecturer really is crazy and his ideas unsustainable.

Euphoric
  • 36,735
  • 6
  • 78
  • 110
  • 2
    If your 100kLOC code base has a solid suite of automated (black box integration) tests, then rewriting it surely easier than without such a test suite, but it is definitely not trivial. And if it has a solid suite of unit tests, rewriting it is actually more effort, since one also has to rewrite the unit tests as well. – Doc Brown Jan 04 '18 at 15:56
  • @DocBrown "since one also has to rewrite the unit tests as well" No. As definition of "solid automated tests" (notice AUTOMATED not UNIT, I was very careful not to use UNIT tests in my answer) is that the implementation can change without changing the outside behavior. – Euphoric Jan 05 '18 at 07:17
  • 1
    Automated tests can be be both - unit tests or other tests. But that was not the point of my comment. My point is, rewriting does not get **trivial** just because you have tests, even when those test don't have to be touched. – Doc Brown Jan 05 '18 at 10:49
0

He probably exagerated a bit, however there is some truth to it.

  • "analysis-paralysis": there are so many possible choices and ways to make develop something that looking too long for the best technology fit might become counter productive at some point. Perhaps if you just picked the first "ok" one, you would already have finished the task by the time you would take to evaluate all possible technologies.

  • "unexpected roadblocks". You can't foresee everything. And if you have invested soooo much time in building an optimal "solution" just to discover later on that some detail causes real trouble, the effort is either all wasted or it becomes very time consuming. Doing early prototyping is a very good way to explore what lies ahead of you, including the pitfalls.

  • "early returns". A prototype is very useful, be it as a proof of concept. Perhaps you'll have to rewrite it all (and better) next time, but you've earned valuable information, feedback, ways to improve it ...and maybe your project wouldn't even be afloat otherwise because the "right" solution would have been too time consuming.

  • "aging technologies". Especially for larger projects, by the time you finish it, it's likely that a lot of tools, technologies, APIs, libraries have progressed to a point where your current solution feels obsolete. I was once working for a company which transitionned huge codebases from assembler to C, then C++, and by now probably C# and in a decade, it'll change too. Likewise, JAVA GUIs are ported to web techs, web techs are ported to native mobile and so on, and so forth.

...so, well, yeah, it's a matter of finding the right balance between planning and doing.

dagnelies
  • 5,415
  • 3
  • 20
  • 26
0

When you are prototyping a smallish piece of a big project, your lecturer's comments are right on.

For example, when I worked at a next-generation genetic sequencing company, many of the algorithms were developed in python because of familiarity to the data scientists, and speed of development. It often took a lot of hacking and experimentation to get the I/O and data structures right, and to meet processing speed and space requirements for the huge data sets. We sometimes used R or MatLab. There are lots of other options here.

After the prototype was working, the initial interface to it was via the command line. Slowly, over time, most were converted to our "real" application, written in Java, which was viewed (note that I'm not taking a position on this!) as more robust and maintainable, and was certainly more familiar to the software engineers.

user949300
  • 8,679
  • 2
  • 26
  • 35
0

Code is not constantly rewritten, so there everything is already based on a wrong assumption.

Sometimes you have code that is used once and never again. Quality doesn’t matter if you can verify that the result is correct. Most code isn’t like that.

Sometimes people write prototypes with the intent to throw the prototype away and write real code later. And then you get management deciding that the rubbish prototype is good enough, and it’s bad quality will haunt you forever. In theory, this shouldn’t happen. In practice, there’s a difference between theory and practice.

Unless you are 100% sure that the low quality won’t affect YOU but is someone else’s problem, make sure that everything you do has decent quality from the start. It’s cheaper that way.

gnasher729
  • 42,090
  • 4
  • 59
  • 119