Edit and Continue, which shipped in Visual Studio 2005, is generally regarded as A Good Thing. It's pretty difficult to argue against the benefits of immediacy when debugging, but that isn't about to stop some people:
While they raise some valid points, the underlying argument is essentially the same in all three cases: Edit and Continue should be removed because it's dangerous. And we're clearly too stupid to be trusted with a dangerous tool like edit and continue!
This reminds me of a similar scenario in video games. There are two types of video games:
If you are killed between saves, you have to go back to the last save.
Certain groups of hard-core gamers think "save anywhere" games are fatally flawed. Real men, they say, work their way through a level and earn the save point. They believe that games should remove the "save anywhere" option, lest we all become a bunch of spoiled, lazy gamers who can barely lift our thumbs.
But here's what drives me crazy: the hard-core gamers don't have to use save anywhere! If they're so hard-core, they should easily be able to resist the temptation to save their game. They can simply save at the beginning of a level, or confine themselves a few saves per level, or whatever. So when they say the "save anywhere" option should be removed, what they're really saying is, "everyone should play games the same way we do," and veiling it in some macho rhetoric to intimidate people into agreeing with them.
The comparison between game saves and edit and continue is fairly apt; either you can edit a program whenever you want-- even at a breakpoint in a debugger-- or you can only do it when the program is stopped. Clearly, offering both options is more flexible and inhibits no one.
However, there's a big difference between encouraging people to take challenges and forcing them to take challenges by removing flexibility from the product. Not everyone plays games for the same reasons you do. And not everyone writes code for the same reasons you do, either.
The EC and Save Anywhere think sounds a bit like a strawman argument.
Sam hit the nail on the head - unit tests provide a better developer experience than edit and continue. It requires good unit tests written test-first that result in testable designs that defeat the design conditions that bring about the need for Edit and Continue. Without those qualities and without the developer knowledge, unit testing and Edit and Continue aren't likely to express the differentiable qualities that folks like Sam and other testability and design folks take for granted.
Software developers who know how to achieve testability are often more accomplished software designers than folks who rely on EC. They achieve productivity that far outstrips the kind of penny-ante, short-term productivity achieved through RAD and tooling like EC.
And indeed, everyone should construct code the way we do. If we’re talking about building applications and systems, there’s a lot more at stake than a gamer twiddling away his study time in the glow of Halo. The domestic industry is being left with very little wiggle room to continue to play at coding rather than to take it head-on with a professional verve that spawns intellectual curiosity, inquiry, study, and practice.
In some respects, I think the analogy between coding and gaming is more telling about the attitude toward coding that folks who use EC as a low-grade buttress against their lack of understanding of testability. It highlights the lack of visibility into the meaning of testability by lethargic programmers who have yet to muster the person integrity and professional ethic needed to penetrate deeper into understanding testability and its inherent design considerations and benefits through practices like TDD.
Once you speak from real, prolonged experience with test-driven design, you realize that you’ve moved to another completely different game, rather than just a level in the same game with bigger monsters.
Sam, I understand and respect your position, as well as your experience. If I were to write the perfect unit test and perfect code to go with my perfect unit test every time, I would never need to go into the debugger. I would also have a candy keyboard with gumdrop keys. I mean, hey if we could all write perfect code the first time around, we wouldn't need unit tests either. Most people I know, I may lead a sheltered life, don't just slap any old syntax into their source file and say "well, I'll just find all the bugs at runtime and set a breakpoint.". They write well thought out code, even if their thinking is wrong or flawed. But sometimes, $#!t happens and who you gonna call?
The biggest irony in your position on EC is that you have spent a lot of time learning and loving dynamic languages like Python and Ruby. EC is a H U G E part of what makes Ruby, Python, and Ruby on Rails so great. Even if it isn't called EC, it's a big boon to productivity to be able to just fix the error and hit "refresh" rather than exiting the IDE, and doing the ctrl-shift-b shuffle.
I, however, have a BIG problem with this statement. I thinks it's arrogant and counter-productive.
"I think EC comes out of the sloppy just hit F5 world of VB and people don't think before they run"
yeah, if only those stupid VB programmers weren't out there writing 90% of the business applications, there would be more room for perfect code right? Your bank probably runs on VB code. Your insurance company, your doctors office, everything. Every, and I mean EVERY, company large or small has a rinky-dink little Access database (with VBA) that they are completely dependent on for their day-to-day business. The time of the "hardcore" C/C++/COM programmer is over, finished, done, stick a fork in the old dinosaurs and put them out to pasture. VB, C#, Python, Ruby, and other languages and frameworks that don't require you to wear sackcloth and ashes and self-flagellate to get real work done are here and they are the future.
Scott on February 6, 2006 1:48 AM-- He said respectfully with a smile. :)
Scott on February 6, 2006 1:51 AMOnce you speak from real, prolonged experience with test-driven design, you realize that you’ve moved to another completely different game, rather than just a level in the same game with bigger monsters.
I agree that everyone should be trying to step up their "game", no pun intended.
But you'll get a lot more flies with honey than vinegar.
You could make the same point about refactoring being dangerous. If you design correctly the first time, you shouldn't need to refactor, right? That kind of logic is flawed. Refactoring is a useful feature, Edit and Continue is also useful feature. If you don't find it useful, don't use it.
Sean Chase on February 6, 2006 2:06 AMOoh! Ooh! My turn to weigh in.
A couple things. I think the main argument around EC isn't necessarily whether it's "evil" or not, I think it has to do more with its priority. At least for me.
Should Microsoft have spent time on EC over other features? And that really depends on what features empirically help developers produce better code.
Like Sam, I believe that helping developers learn to write unit tests and approach pragmatic test driven development (which MS has unfortunately collosally failed at) gives more bang for their buck.
So while I agree that EC is useful (heck I've been in situations where I'm running a unit test in a debugger and would have loved to save time by fixing a typo rather than doing the whole recompile re-run bit) in the hands of a good developer.
The real question is whether other more useful, more helpful features were put aside in favor of EC.
Haacked on February 6, 2006 2:19 AMSam, I understand and respect your position, as well as your experience. If I were to write the perfect unit test and perfect code to go with my perfect unit test every time, I would never need to go into the debugger. I would also have a candy keyboard with gumdrop keys. I mean, hey if we could all write perfect code the first time around, we wouldn't need unit tests either. Most people I know, I may lead a sheltered life, don't just slap any old syntax into their source file and say "well, I'll just find all the bugs at runtime and set a breakpoint.".
I don't understand the argument. Its fairly easy to write very useful unit tests with TDD. It takes me less time to write a 2-4 line unit test than a round of debugging and such. There is no such thing as a perfect test. There is a such thing as writing tiny small tests that each cover and assert a logic condtion.
on the ruby, etc.
Its not the same as rummaging around in the debugger. Dynamic languages use a ton of unit tests - check the ruby and rails sites. They come out of the agile movement
I would say that my imperfect unit tests which get refactored keeps me out of the debugger 99% of the time nowdays. We need to start teching people to do it right and spend time on tools that teach guide this, refactoring, etc rather than tools that encourage cowboy hackery
Sam Gentile on February 6, 2006 2:58 AMSam,
"I don't understand the argument."
I think my main point is that the IDE shouldn't punish people for having fumble fingers or for not having written perfect code before running the application. Removing EC, IMO, would punish people who don't write perfect code. is it possible to write code that passes a unit test, but still contains an easy to fix flaw? Like an off-by-one error? Do you write unit tests for string localization and typos? Are there unit tests for control positioning? Wouldn't it be useful, in both smart client and web development, to be able to change the positioning of a control when you notice that it's two pixels too far to the left?
I guess a serious question I would have for you, or anyone else who is using TDD effectively is: Do you ever run the application inside the IDE in Debug mode before you deploy the application or do you go straight from development into production?
"Its not the same as rummaging around in the debugger. Dynamic languages use a ton of unit tests"
Agreed, but fundamentally both activities, editing a Rails controller/view/model/helper at runtime and changing code using EC are the same. You are changing code without having to completely stop the application and recompile. It often takes me as much as a minute or two to re-start my current application. More if I'm debugging client-side script in Visual Studio. (much, much more. Like go-downstairs-and-get-a-latte more). To me, that's time wasted (unless I *do* go get a latte, at which point it's a needed break).
Scott on February 6, 2006 3:40 AMMuch as I admire Sam and the others, there's far too much macho posturing on this subject. I wrote about good and bad EC scenarios here:
a href="http://sleeksoft.co.uk/public/techblog/articles/20051224_1.html"http://sleeksoft.co.uk/public/techblog/articles/20051224_1.html/a
Having a full-time job as an adult, games are now a regulated use of my time... Any game not featuring "save anywhere" is a waste of that time. I am playing the game for enjoyment and to get through it in a reasonable amount of time. If I have to play the same place OVER AND OVER (Prince of Persia is a shining example) I get fed up because I feel like I am wasting what little free time I have. Do I wish I had enough time to play games without save anywhere? Sure, but I also like not having to live with my parents.
Edit-and-continue is a tool like any other. Just because it can be abused is no reason for removal. I've used Delphi for some time now, but back in my VB 4/Access 2 days there were times that edit-and-continue was pretty nice for experimenting in real time, especially in loops.
Ryan McGinty on February 6, 2006 3:48 AMWe're talking past each other. You keep saying "perfect code." I don't write perfect code and neither does anyone who uses TDD. With all due respect, I donb't think you understand the purpose and method of TDD. TDD is not only about finding errors but a methodical way to develop software with a process of self-discovery along the way. It is *not* and ever been a way to write or gauyrentee "perfect code." I don't know what that is. You try to ensure some level of quality but I think you paint the agile people as going extreme on "perfect code" and writing tests forever to get there. Thats not what its about and I think you may benefit from Scott Bellware's posts on TDD as well as Jim Shore, myself and otehrs.
All the best
Sam Gentile on February 6, 2006 3:57 AMJeff I think you've hit the nail on the head with this post. Most specifically:
not everyone writes code for the same reasons you do, either
Sam, Scott - I don't think this is a strawman argument and I don't think either of you actually addressed it in your replies.
Sam:
With all due respect, I think your analogy with hard core gamers doesn't make much sense here. I am arguing aggainst being in the debugger *at all*.
(I think this is the same 'EC is dangerous' argument expanded to the Debugger as well. I'd respectfully say you missed the point of the analogy, rather than it not making sense.)
Scott:
And indeed, everyone should construct code the way we do. If we’re talking about building applications and systems, there’s a lot more at stake than a gamer twiddling away his study time in the glow of Halo.
(This seems to be an explicit denial that other people could have a software problem that looks different than yours, and would be better solved by different methods.)
The crux here is the desire to advocate TDD + Unit tests to the exclusion of tools and methods that support other modes of working. Basically it is dangerous to have support for anything that does not lead one to conclude a unit test is the right answer.
Projects with different goals will benefit from a different mix of tools and processes, whether that involves use of EC or Big Design up front.
To make some specific examples:
EC is perfect for prototyping game play mechanics. Would you really try to write a unit test to ensure you don't regress the fun in your game?
EC is useful for letting a software aware Domain special-ist simply make a somewhat less supportable yet useful first pass of the required software. Sometimes that is the right business tradeoff. Does that kind of loose development practice create a headache for software professionals ... you bet. But that is why those are paid positions, because the end goal is the benefit to the software user, not the developer.
(I have to use 'special-ist' above because there is a forbidden word embedded in it. :-)
(Also I should say though I am saying that TDD + unit testing isn't the answer for every problem I fully acknowledge it is a HUGE leap forward in best practices.)
Steve Steiner on February 6, 2006 4:36 AM"With all due respect, I donb't think you understand the purpose and method of TDD."
I'll admit to being mostly ignorant of hardcore TDD. Most of what I know is from reading blog posts about how great it is. The phrases I see most often associated with it is "increased productivity" and "increased code quality". And the last time I read up on "Agile Programming" it was called "Extreme Programming" ;)
Back to the point of EC, I still think it's useful and shouldn't be removed because there are some things that TDD can't really test for. Or it seems to me that you'd go nuts writing unit tests to ensure that all of your spelling and grammer is correct. Most of my issues with TDD come about when I try to apply it to legacy code and web applications (worst of all legacy web applications).
Scott on February 6, 2006 4:51 AMTDD is good. Refactoring is good. Use them together and you get a look at a bigger slice of the agile picture – a picture which is astonishingly under-developed in the minds of folks who write software while tied to the traditional development practice anchor.
Agile approaches like TDD and refactoring aren’t about writing perfect code. Both of these approaches exists specifically to address often extremely less than perfect code. TDD and refactoring are about designs that allow for changeability. I’m personally not after perfect code; I’m after a methodology that allows me to make code better when a better solution is presented.
Through a conscientious practice of Agile approaches including TDD and refactoring, I rarely have to use the debugger – not because my code is perfect, because it certainly isn’t – but because there are alternatives to having to resort to the debugger which exist in a spectrum or color that the Mort species presently is either incapable of or unwilling to perceive.
The Agile movement didn’t just come up with a handful of useful tools like NUnit, NAnt, CruiseControl, etc, to revolutionize traditional software development. These tools were forged by the requirements and expectations of an emerging development methodology. Folks making use of refactoring tools in Visual Studio without knowing about the greater context within which they are used are simply engaging in an impoverished approach to development in comparison to the power that those tools bring to bear in the context of the development environments that shaped them.
There’s a lot more to refactoring than refactoring tools, there’s more to TDD than NUnit, but you can’t see any of it until you go looking. If you think the a-ha moment going from VB 6 to VB .NET was big, wait till you get feel the magnitude of the Agile a-ha moment. Moving into a deep understanding of TDD is an order of magnitude bigger zen smack than the switch from a procedural to an OO world. It’s much more on the order of moving from a flat earth to a round world.
There quite a number of deeply-ingrained superstitions that Mort has to let go of before something like TDD will begin to make sense, and until that time, Mort is confined to the limited capacity for software development thinking that hasn’t evolved significantly since VB 6. And frankly, I have yet to see anyone really get TDD who didn’t put in the effort to really try it first.
Indeed this is definitely more vinegar than honey, but recipes for change in paradigm shift aren’t always formulated with candy-coated gumdrops in mind.
I maintain that a prolonged exposure to TDD practice will totally change your perception of software development and will re-wire your mind toward a higher magnitude of expectation for productivity and quality that go far beyond the middling gains brought by a development style that requires Edit Continue. But first you have to be willing to open your mind to the possibilities that the world may indeed not be a flat disk held on the backs of giant elephants floating in a cosmic sea on the back of a giant tortoise.
Scott,
And the last time I read up on "Agile Programming" it was called "Extreme Programming" ;)
Well no, Agile is an umbrella for all of the contemporary, test-centric methodologies like XP. XP is an Agile method, just like MSF is a waterfall method, but there's no formal methodology called "Waterfall".
Back to the point of EC, I still think it's useful and shouldn't be removed because there are some things that TDD can't really test for.
Can you provide an example that can't be resolved by refactoring the design to make it testable using Inversion of Control and Dependency Injection?
Or it seems to me that you'd go nuts writing unit tests to ensure that all of your spelling and grammar is correct.
Spelling and grammar for what?
Most of my issues with TDD come about when I try to apply it to legacy code and web applications (worst of all legacy web applications).
Indeed. TDD is a design methodology. If the code hasn't been brought into existence by the design pressures inherent in TDD, it's likely not going to have a whole heck of a lot of testability.
However, there are solid techniques for making legacy code testable. See: http://www.amazon.com/gp/product/0131177052/002-1083542-4004061?v=glancen=283155
How about an experiment? You can come work on my team for two weeks and if you still don't see that TDD is much more than you thought it was, then we won't charge you for the two weeks of training and coaching ;) (-- yes, it's a joke!)
Scott Bellware on February 6, 2006 5:39 AM"Because you get to focusing on that one bug and twiddle the code to fix that one bug and introduce six more."
I'm sorry for anyone who has to work on code that is so entangled and badly designed that this could turn out to be true.
Paul Coddington on February 6, 2006 5:49 AMwhich exist in a spectrum or color that the Mort species presently is either incapable of or unwilling to perceive.
And if you treated Mort like an adult instead of a child, you'd have more success convincing him to adopt better development practices.
http://haacked.com/archive/2005/08/03/9210.aspx
We need to stop paternalizing. Java guys are the worst in this regard, though some of the more zealous C# purists are nearly as bad.
Instead of wasting time complaining about Mort and Edit and Continue corrupting the minds of innocent young developers, we should be pulling ourselves up by our bootstraps.
Similarly, time spent arguing about this stuff is better spent instilling a general culture of hard work and professional investment, so all developers CAN become talented.
Jeff Atwood on February 6, 2006 5:59 AM"Can you provide an example that can't be resolved by refactoring the design to make it testable using Inversion of Control and Dependency Injection?
Or it seems to me that you'd go nuts writing unit tests to ensure that all of your spelling and grammar is correct.
Spelling and grammar for what?"
Mostly for non-localized strings. Button text, label text. I do most of my developmet on web applications, so I spend a lot of time dealing with HttpCookie, HttpRequest, and HttpResponse. Which means a lot of hash accessing, which means lots of changing "Request.QueryString["uesrID"]" to "Request.QueryString["userID"]". Web applications are harder to adapt to any kind of TDD methodology due to the code being spread out and not being covered effectively by all of the available tools. You can write unit tests for your client-side script, but NUnit can't really test them. The VS IDE code coverage tools don't seem to support client side script. Most of the UI unit tests seem to involve screen scraping and checking for the correct text in HTML elements, or checking for the HTML elements themselves.
See, I "get" where TDD is useful for biz objects, transactions, and other objects which encapsulate application logic. But I don't get TDD for UI development. Which is where 90% of my pain during development is. 90% of my code is plumbing/data pump code. Put data in/get data out and display it. And that's the easiest, and most tedious code, to have to write. But the remaining 10% is where most of my errors occur. How do I "test" that an event fired correctly?
I mean, if TDD only helps me out with the easiest part of the development...I'm just not seeing the benefit. Am I missing it? Does anyone DO GUI testing using TDD? Is it possible?
I've posted a challenge on my weblog. A nice shiny quarter to the first person who can write a unit test that would have prevented my bug. ;)
Scott on February 6, 2006 6:02 AMSteve,
I agree the EC is a useful tool for folks building prototypes who may not have TDD skills, but I build prototypes without EC. I have yet to find a single justification for EC that design-for-testability and TDD hasn't simply made irrelevant.
I build the same kind of apps that most EC users build. The need for TDD isn't driven by the kind of application under construction.
It's not that TDD is a replacement for EC, it's that TDD changes the fundamental aspects of design so that EC isn't needed. And the result is software that is clean and grokable and much more of a pleasure and much less painful to build on and maintain.
The productivity comes from software designs that result from TDD practice that do not bring the obstructions to progress that are inherent in the opaque software that results from traditional practices.
The entire reason and justification for things like EC is wrapped up in a need to surmount obstacles that are themselves inherent in traditional design and implementation approaches.
It might sound crazy to hear a group of developers suggest that in TDD we've found a new route to productivity and that it's a greater store of productivity than we've ever found before, but that is precisely what what Agilists and TDD'ers are saying.
There's no shortage of TDD practitioners to sing the praises of TDD, what's required now are ears that haven't been desensitized by the numbing drone of traditional development.
The need for EC is a symptom of certain styles of software design that have become prevalent during an age when Microsoft opened the flood gates to a segment of developers who were need during a coder staffing crisis during the boom years.
EC is like putting a Band Aid on a shut gun wound. The real problem is the designs that necessitate EC. Even worse are the people who negligently continue to insist on these designs and who are too lethargic to learn a few new tricks.
The greatest shame rests with Microsoft for encouraging Mort to continue to engage in negligent software practices, but there's little hope that Microsoft will take a responsible stance and desist from its own negligence since the resulting deflation in productivity causes a percieved need for throngs of Mort programmers who in turn drive millions of dollars in revenue for expensive Microsoft developement tools.
Scott Bellware on February 6, 2006 6:07 AMTeaching some people how to use DEBUG mode to begin with is something of a challenge.
The concept that the debugger itself can tell you the exact state of your application at any given time seems to simply defy them. Run, crash, recompile they say. Of course, many of them take HOURS to track down the simpliest of glitches induced by a moment of distraction or simple typo.
Indeed, Edit and Continue is prefectly suited to the simple typo fix, and allow you to test the change in place without having waste time recompiling, rerunning and returning to the exact same code path. Edit and Continue actually DEFIES serious code changes, and as such the serious modifications require that you shut down your app, sit back and think a bit.
It is NOT about edit and continue at all, but rather about a poor experience with an early ineffective debugger which permanently scarred them, or people who are paid by the hour looking for ways to explain why it takes them 8x as long to fix problems as their compatriots who use the debugger.
In perhaps the most perverse use of the word, these people are luddites plain and simple!
There are those out there that don't use debugging simply because they have never been taught how. Take some time, show them how it is done. My experience says that it should take no more than a year or two of concerted effort before they finally clue in, faster in many cases. Very few people prefer to do things the hard way, but there are the occasional purists who will resist as long as possible.
Xepol on February 6, 2006 6:08 AMScott,
See, I "get" where TDD is useful for biz objects, transactions, and other objects which encapsulate application logic. But I don't get TDD for UI development. Which is where 90% of my pain during development is. 90% of my code is plumbing/data pump code. Put data in/get data out and display it. And that's the easiest, and most tedious code, to have to write. But the remaining 10% is where most of my errors occur.
Have you practiced the Model-View-Controller pattern for UI code testability? It's an Inversion of Control pattern for UI that is used to get all the testable code out of the opaque testing containers that Microsoft's tools create and reshape them into testable patterns.
There's usually some percentage of UI code that is better tested with human eyes and hands. The goal is to reduce that percentage to as low a number as possible and to automate the rest of the test using tools like NUnit. If you've got some high-end tool to automate some part of the remaining code, then you could drive toward an even smaller percentage of human-tested code. However, a significant number of UI test tools are more trouble than they're worth.
How do I "test" that an event fired correctly?
Are you asking how to test the wire-up between an event and a handler, if the handler did the right thing, or if the event was actually raised by some UI interaction.?
Scott Bellware on February 6, 2006 6:22 AMCorrection:
Meant to say Model-View-Presenter... Freudian slip.
Scott Bellware on February 6, 2006 6:24 AMWhat, you want to save games anywhere? YOU SPOILED LIMP-WRISTED WIMP!
But I agree that debugging is good, and edit continue is better. Knowing how to use this stuff is essential, sure, but when is that not true?
This reminds me of an episode on the Adobe forums. You see, the venerable word processing DTP application FrameMaker only recently got multi-level undo redo. Previously, you could undo only the last change, and that was that.
Now one user (a well-informed and generally very helpful FrameMaker veteran) came up and said that multiple undo levels were bad because they would seduce people to type without thinking since they could simply undo everything!
Clearly, this line of thought is indefensible since you'd really have to demand the abolishment of even a single undo level, or of all computer word processing, or of using paper instead of etching words into stone, if you followed it to the end.
But for many people, the belief that convenient tools create bad attitudes was always very attractive... I think it was Plato who complained about the invention writing since people wouldn't learn anything by heart anymore!
Chris Nahr on February 6, 2006 6:43 AMFunny how this has degenerated into a conversation about the merits of TDD. I really think that deserves another post.
I think the real issue is adding EC to C# in VS.NET the BEST use of time considering all the other potential features that could be added instead?
If not, what would you put in front of EC that isn't being added?
Haacked on February 6, 2006 7:20 AMI think I'll be taking the middle ground on this one, uncharacteristically... I think EC is a interesting, useful tool. Considering that Smalltalk and Microsoft QBasic had this functionality over ten years ago, it's about time. (Even VisualAge Java had this feature five years ago.)
There are times when I've traced through a complicated call stack, found a silly mistake, and wanted to fix it right then and there. EC allows me to do so without having to start over and step through the code again.
That said... if you're using the debugger much at all, you're behind the times. Techniques like TDD (a href="http://www.jamesshore.com/Blog/Red-Green-Refactor.html)"http://www.jamesshore.com/Blog/Red-Green-Refactor.html)/a and Fail Fast (a href="http://www.martinfowler.com/ieeeSoftware/failFast.pdf),"http://www.martinfowler.com/ieeeSoftware/failFast.pdf),/a combined with good simple design and refactoring, mean that you shouldn't need to use the debugger. If you're debugging more than, oh, once a day, you have some skills to learn. The experienced programmers I know crack open the debugger less than once a week.
So EC is interesting and useful from a technical point of view. But I doubt I'll be using it much.
Cheers,
Jim
PS: In fairness, this all goes out the window when you're working with legacy code.
James Shore on February 6, 2006 7:21 AMI think Scott and Jim have already covered all the next points I would have made and all I really want to say further on this. I have been attempting to "pull up" this community so that Morts and everyone learns about these ways of working but Microsoft comes along and keeps dumbing it down and out with their tools (MSF, VS Team "test", EC, etc). If you wanto to look at ways to dramatically improve the way you work you have to think out of the (tight) box Microsoft paints you into. Thats all I think I can say as I have no religion or anything to sell. I have tried all the other ways for the last 22 years and they didn't work for me, so I stand by what I say because I live it every day in myself and my team and it works. Thanks for the discussion.
Sam Gentile on February 6, 2006 8:45 AMI think they are just affraid that some bad scripting kiddies might be able to produce better software. :)
Peter Palludan on February 6, 2006 9:30 AMI agree, in a bizarre way, with Scott Bellware. He, and his ilk, obviously don't know how to use EC and, therefore, shouldn't use it. I wish they would spare me their condescending concern for us Morts. I do what I can to evangelize the use of unit tests, TDD, and other Agile practices among my fellow Morts. There is absolutely no conflict between using EC wisely and using TDD. You folks are doing nothing more than hurting the adoption of Agile practices with your uninformed criticisms of EC. It might be a good idea to just shut up for a minute and listen to the folks who have differing opinions. You just might learn something.
John Cavnar-Johnson on February 6, 2006 9:47 AMsigh
John,
I spent some time with a Mort who thought if he could only teach me how to use EC that I would see the light. He taught, I learned, it was just debugging in live mode on code that wouldn't need to be debugged through layers of opacity if the layering wasn't built to be opaque.
EC is a trouble-shooting crutch for folks who have simply copped out on learning about software layer opacity, IoC, and DI.
It's never been a matter of knowing how to use a tool like EC, but how to use a tool effectively under the guise of an effective methodology. It's the methodology that precipitates the EC tool that I take issue with. The tool itself is largely benign, except that it perpetuates lack-luster and less effective practices relative to TDD.
To wit, I don't think we're hurting Agile's adoption among Morts. I have yet to meet a Mort who was interested in Agile. I don't really think it's much of a target audience for Agile.
I'm with Jack Greenfield on the notion that a small percentage of Microsoft developers are likely to ever be able to adopt Agile. But I would posit that if the non-Mort developers adopt Agile, that we'll likely need a lot fewer Morts.
I look forward to your writings on TDD for Mort.
Scott Bellware on February 6, 2006 10:26 AMThis is one of those cases of protesting a tool because it has potential to creating bad practices. The reality is that edit and continue does have a useful role to play in fixing small "oops" type bugs without throwing out the state and restarting.
However, I agree strongly that using it _frequently_ may mean that you failed to put proper unit tests in your code: you shouldn't be at the point of editing and continuing often as your test cases should point out the flaw. Additionally, making an edit "on the fly" invalidates any unit tests that have already run, which means another pass will need to be done anyway to be sure that everything is clean, and good unit tests will recreate the state you need for you on that next pass.
Wesley Shephard on February 6, 2006 10:32 AMTotaly agreeing here again. It's a burden when you can't save anywhere in a game, although "genius" gamers don't need it. Plus, it's simply stupid not to be able to save anywhere, when you're palying and another event occurs and you need to leave the PC to somebody else, or shut it down, etc..
Or the next save point was 2 min later, and you've been playing for 30. and you HAVE to stop the game.
What I find horrible is that some people can give so definitive assertions, that "edit and continue" IS bad, forever and always...
Pffff.
Be honest! Who among us developers, never forget an "i++ /i=i+1.." line of code, finishing in an endless loop which, because of an overflow, would give an error you don't understand.
What's more simple: read and understand 'error 80521a1d line 425', or just debug it ?
Those people pretending to own the truth and that "edit continue" is bad, are like the ones saying computers are destroying intelligence of kids, or such stupid stuff.. In the same way coputers can co-exist with their "opponents" (books/ebooks for reading, handwriting, music player, etc..), "edit and continue" can coexist with "edit and compile"...
Thanks for pointing this out. Your blog is great !
Tom
I think the comparison to gaming is a little flawed. The point of a game is to provide entertainment, but things aren't as entertaining if they're totally unchallenging. Thus, one contrived way to increase the difficulty of a game is the inclusion of save points rather than being able to save anywhere (as a side bonus, it also cuts down on the amount of information you need to store).
By comparison, writing software is supposed to be easier. Like a game, it might be entertaining if you really like to do it. But anything that makes it harder is downright silly.
Therefore, the most convincing argument against EnC is that it does, in fact, make writing software harder. For instance, if you could show that code productivity decreased because people relied too much on EnC (at the expense of more sensible things like good design, etc.) and caused an overall drop in software quality, then indeed EnC would be bad. The other arguments ("don't be in the debugger unless you have to", etc.) tend to be spurious or based on opinions rather than a process of reasoning.
Don't get me wrong: I'm squarely in the camp that EnC is one of the greatest invention since sliced bread (or maybe that's milk-dunked Oreos... I haven't decided yet). But I see where the opposite side is coming from.
j on February 6, 2006 12:25 PMI appreciate your thinking on this matter and quoting me. With all due respect, I think your analogy with hard core gamers doesn't make much sense here. I am arguing aggainst being in the debugger *at all*. Its a large waste of effort for little result. Don't get me wrong (and please don't quote that I aggainst the debugger) because its *not* a black and white thing. When you need a debugger, you need one real bad. But those times should be few and far between. Debuggers are for intractable problems that you can't find. Unit Tests are a far better use of time because 1) they are quick to write and 2) they produce better value for the you and the company because the "test" is now *repeatable* and automated. Also they serve as API documentation. I think EC comes out of the sloppy just hit F5 world of VB and people don't think before they run. I think its not just dangerous but a big waste of time. I just wish people could see that they can write 2-4 line NUnit tests in about the same time as debugging and its a lot more rigorous in thinking, value added, etc.
Respectfully, I fully stand by my position. Thanks fro listening. Cheers, Sam
Sam Gentile on February 6, 2006 12:46 PMEdit Continue is a tool. It should be up to the programmer to use whatever tools are available for his particular situation, methodology aside. One of my favorite debugging techniques is changing the instruction pointer while I'm debugging. I'm not desiging when I do it, I'm trying to save TIME. EC is great for investigative work. I often use the debugger to trace through legacy code to understand how it works (absent good documentation). I use a debugger just to view data being passed back to gain insight in how a black-box library call works. EC and changing the instruction pointer can save tons of time in these scenarios.
Alan Kleymeyer on February 7, 2006 1:37 AMcorrect stupid off by one errors and associative array references.
Scott, this is probably exactly the case where it would benefit you to write some unit tests before fixing an off by one error. Write tests to expose the error. Write tests to make sure correcting the off by one doesn't cause other problems.
Simple inline fixes to off-by one errors are notorious for introducing unforeseen bugs. For example, I've had an off-by-one error in VB back in the day. A simple inline fix introduced another off-by-one error. It turned out that what I thought was a 0-index array was a 1-index array. The "obvious" fix introduced another bug.
Also, you never know when another programmer comes later, is working in that code, and changes it for some reason (perhaps indirectly by changing a function that supplies the index. Who knows?). It'd be nice to have a unit test to catch that.
However, I consider myself to be a TDD'er, but I'm not exactly a crusader. I don't think TDD is necessarily incompatible with EC. I don't think TDD necessarily invalidates EC.
I just think TDD is more valuable than EC. But if the majority of MS developers disagree, by all means, use EC to your hearts content.
But also take some time to look at TDD and learn how to minimize reliance on EC.
Haacked on February 7, 2006 2:21 AMWell John, my contention is that once a Mort becomes a TDD'er, he is no longer interested in being a Mort - he has largely moved on from Mort practices. Mort practices and Agile practices are largely relative opposites.
I've introduced quite a few Morts to TDD through the workshops I've been doing in the US and Canada in conjunction with .NET user groups, as well as through consulting gigs. I've never been able to get a Mort to adopt TDD and still remain a Mort. By the time a Mort becomes interested in practicing TDD, he is already on the way out of Mort territory. So I guess it's more appropriate to say that I've tried to encourage recovering Morts through the transition, and I've helped turn on the TDD lights for a few open-minded folks who hadn't yet considered the possibility of a non-flat Earth.
The times where I have been asked to teach non-receptive, die-hard Morts to do TDD, the practices and disciplines often slid down Mort's back like water off a duck - TDD often doesn't stick to a die-hard Mort. Sometimes the material opens Mort's eyes to another dimension of software development, but those aren't the majority of situations. In these cases, the best I can hope for is to introduce them to mere automated testing, and usually not even the mere test-first practices stick - practices which would ultimately clear the path to understanding testability.
Many Morts don't often naturally think about *testability*. Many Morts are only now thinking about *testing*, but only because Microsoft is telling them to do because of VSTS' arrival on the scene. Testing and testability aren't necessarily the same dimension of concern. Not recognizing this is often the cause of new developer testing effort failures. Once a Mort adds testability concerns to developer testing concerns, I would venture that they have started down the path to Mort recovery.
In my experience, the die-hard Mort is a Mort because continuous study and practice aren't a part of his work method. Die-hard Morts typically learn the latest way to create opacity through Visual Studio designers, and that's where it ends. Mort is often a Visual Studio user, period. And that alone doesn't make for a good developer much in the way that owning a license for Microsoft Word doesn't make someone a good writer.
I'm not worried about offending Morts with recriminations about their low-sustainability practices - especially when they hold tight to these practices out of fear or lethargy because those are recriminable qualities for a software developer, and low-sustainability is a recriminable quality for software. When Mort finally learns that testability offers much greater sustainability over Visual Studio’s RAD tooling, then Mort will be a thing of the past.
Oh, and John... "Mort" *is* a generalization. So I don;t feel that it's inappropriate to speak generally about the persona.
Scott Bellware on February 7, 2006 5:58 AMthe real question is (as Phil said)
Should Microsoft have spent time on EC
over other features?
and i think Lisa Simpson said it best:
"You'll never go broke appealling to the lowest common denominator"
i don't mean this in an elitist way: i think it's a true and healthy point of view.
if the language features you choose to include will widen the base of users, then it will ultimately be a good thing. It's the old distinction between low floor and low ceiling.
In some earlier thread on this topic, someone said "why shouldn't a debugger allow you to actually debug?"
And excellent use of a straw man argument, Jeff!
cheers
lb
Leon,
if the language features you choose to include will widen the base of users, then it will ultimately be a good thing.
Good for who? Does a larger user base always equate to a good thing? Is there a tipping point at which a larger user base becomes a hindrance?
Scott Bellware on February 7, 2006 7:22 AMTo me, unit tests and TDD in general are irrelevant to this argument. They are about FINDING the bugs, not about fixing them. No one fires up edit and continue, stepping through their code looking for bugs. They very likely know where the problem is, but don't know why it is happening. The same scenario could occur with unit testing. "I don't know why that test is failing...Silly me, my index is off by one!", edit, continue, test passes, get on with life.
Mark on February 7, 2006 11:57 AMPhil: Leave it to me to be the degenerator. heh heh.
See, the TDD guys said that TDD eliminated the need for EC. But I haven't seen any evidence to that effect anymore than TDD eliminates the need for comments or a story. Maybe it's just the way I used EC in VB. I mainly used it to correct stupid off by one errors and associative array references. Oh, and adding in the stupid recordset.movenext calls. Those were my personal nemesis. See, TDD doesn't really catch those any better than just running the app does. You still get stuck in a loop until the stack runs out. I never just fired up the app in debug mode and started writing app logic until I was done. I never made large, multi-module changes either.
I see TDD being a big advantage, if you are writing de novo code. Or if you are using a fragile API in your code.
Scott on February 7, 2006 12:06 PMGee, Mr. Bellware, you have an amazing ability to generalize from your experience with one developer to a whole category of developers. That's awfully open-minded. Maybe the reason that you haven't met any Morts interested in TDD is that you invariably turn them off by your attitude towards them. Since you're obviously one of the anointed few who are capable of practicing Agile methods, I sincerely doubt whether you can learn anything from me.
John Cavnar-Johnson on February 7, 2006 12:23 PMMark,
"I don't know why that test is failing...Silly me, my index is off by one!", edit, continue, test passes, get on with life.
That's not really an accurate depiction of typical TDD.
TDD practices often result in designs that are more reusable and thus classes that are reused more frequently. Making a change to code therefore could cause cascading defects.
The thinking is more often, "I KNOW why that test is failing...Silly me, my index is off by one. I'm going to fix that and run the unit test suite because I can't completely guarantee that the change to a reusable class won't cause failures elsewhere in the code."
Even if a change is done in Edit Continue, the unit test suite will need to be executed after the change is done. It's more likely that a test will fail, the problem localized, fixed, and then the suite executed. Most often this happens without necessitating time in the debugger. Since testability is a design concern, code is designed naturally by the shaping forces of test-first programming such that problems can be localized outside of the debugger.
Further, Edit Continue could leave the code in an invalid state along code paths that I have yet to traverse in the debugger after making a change with Edit Continue - especially for code paths that are re-entrant into the code changed in Edit Continue. This could lead to false positives or false negatives during the test execution, which is something that is pretty strictly eschewed in TDD. In fact calibrating out false positives and false negatives is what the Red and Green phases are all about in TDD's Red-Green-Refactor process.
TDD in general is more often a design practice than a quality assurance practice aimed at finding bugs. But unit tests are certainly good at doing that to.
If I find myself in the debugger in the course of a test execution, I'm usually not deep in the call stack because TDD produces code with shallow stacks and low opacity. Upon localizing a problem in the debugger I would be more apt to stop the execution of the test, make the fix, and then verify that the fix didn't cause un-localized failures.
If I had code that had to be tested into deep call stacks, with branching, and with opacity, I might consider the utility of Edit Continue, but that's not the kind of code that TDD typically produces.
Scott Bellware on February 8, 2006 3:01 AMOh, and adding in the stupid recordset.movenext calls
Oh, man. That brings back memories. If I had a nickel for every time I've written a loop and forgotten to put a .MoveNext in there. Seriously.
Does a larger user base always equate to a good thing? Is there a tipping point at which a larger user base becomes a hindrance?
Yes, a large user base is always good. More eyes reading and fingers typing means more code samples exist and more knowledge is shared.
I've often recommended products based solely on the community around them. Size matters.
I might consider the utility of Edit Continue, but that's not the kind of code that TDD typically produces
I certainly don't think that TDD and EC are mutually exclusive. I'm not sure they're even related!
A good debugger is, however, CLEARLY a core feature of any competent IDE. So in that sense, I think EC got the right priority.
This is not to say that TDD isn't important. But I have to go back to my "save anywhere" analogy-- removing features to force the "right" behavior is *never* the correct choice. You can do all the TDD you want with EC; you're not inhibited in any way.
Jeff Atwood on February 8, 2006 3:50 AMYes, a large user base is always good. More eyes reading and fingers typing means more code samples exist and more knowledge is shared.
A large user base is good. But is there a point at which a user base is too large? Can and should a user base grow infinitely? If so, would we expect negative repercussions?
A good debugger is, however, CLEARLY a core feature of any competent IDE. So in that sense, I think EC got the right priority
When I look at a debugger, I see a non-repeatable, visual assert. I very rarely need an assert that is non-repeatable. I agree that an IDE needs a debugger, but it's not as productive of an implementation verification tool, and too often it's used for that purpose.
removing features to force the "right" behavior is *never* the correct choice. You can do all the TDD you want with EC; you're not inhibited in any way.
My contention is that EC is extremely rarely necessary in TDD. The point isn't to introduce a motion that EC should be retired, but that the practices that precipitate EC are becoming rather dated in the face of emerging evolutionary software design disciplines.
Scott Bellware on February 8, 2006 4:16 AM"A large user base is good. But is there a point at which a user base is too large? Can and should a user base grow infinitely? If so, would we expect negative repercussions?"
Well, there's always Microsoft as an example of a user base growing too large. Specifically, MS Excel. There are so many users of Excel in the world that the codebase is essentially frozen for eternity. It taks a special dispensation from the Pope to change code in Excel I believe. Some of the largest financial firms in the world are still dependent on really, really, old versions of Excel. So much that they have contracts with Microsoft to ensure that MS maintains those old versions. But market size and it's impact on quality is a horse of a different color.
I came not to bury TDD, but to praise EC. Even the most ardent TDD adopter, Mr. Bellware, admits that EC is "extremely rarely necessary". To which I say, "So is my medical insurance, but I'm not canceling that anytime soon.". MS shouldn't cut a feature in the debugger just because of a vocal minority, no matter how right that minority is. For more examples of this see the VB petition, and the many posts by Raymond Chen about backwards compaility and the Windows platform.
FWIW, I plan to use unit tests extensively when we re-write a major portion of our application this year. TDD, in some fashion, will be crucial to our development.
Scott on February 8, 2006 11:20 AMYes, a large user base is always good. More eyes reading and fingers typing means more code samples exist and more knowledge is shared.
I've often recommended products based solely on the community around them. Size matters.
Of course, then there's Lotus Notes. As you said:
"I won't say that Lotus Notes was the reason I quit my last job, but it was definitely a factor in my decision."
So despite the 120 million users and thriving community, you're not about to reccommend it.
Bigger isn't always better...
So despite the 120 million users and thriving community
Well, 119 million of those users don't like using the app and had no choice in the matter.
Not exactly the same thing..
Jeff Atwood on February 13, 2006 6:15 AMWell, 119 million of those users don't like
using the app and had no choice in the matter.
Not exactly the same thing.
That's not the point. You said:
"Yes, a large user base is always good. More eyes reading and fingers typing means more code samples exist and more knowledge is shared."
Always good. Product improvement stems from having more people using the product is what I believe you are trying to say.
In the case of Lotus Notes, the large installed user base has not seen the benefits you describe. It continues to suck. In fact, the large installed base is probably a big problem rather than a benefit. They're locked into it unless they want to undertake the expensive, risky and complicated process of migrating to a new platform. If people started leaving Notes in droves, IBM would either fix it, or kill it and put everyone out of their misery.
How many developers really have a choice of language or IDE in their daily lives? I'm thinking not many. You use what the project requires. All too often the choice of technology is not made by the front-line coders. Sometimes it's not even chosen by a technical person.
The fact remains that there is a very big user community and it's not a Good Thing (tm).
David Totzke on February 15, 2006 5:14 AMBrilliant - you nailed it with the save point thing. Maybe in a video game there's some honor in toughing it out, but if you're too proud to fix a simple mistake on the fly then you're wasting someone's money.
Sure, this can be abused - anything can - but there's no benefit to anyone in restarting, recompiling, and steping through a complex workflow just to fix a simple bug that could have been fixed in a few keystrokes.
Of course, the wisdom to know what should be fixed on the fly vs. thoughtfully reconsidered is important. Let's assume some people have that wisdom.
Jon Galloway on February 6, 2010 9:47 PMIf you thought then edit and continue debate was hotly debated, then you may want to jump into the XLINQ VB XML Literal debate going on now.
XLINQ XML Literals - Reemergence Of Classic ASP Spaghetti Hell? - http://donxml.com/allthingstechie/archive/2006/02/03/2517.aspx
The XML Literal topic is much more important then EC, since it really gives you the power to create some amazingly hard to maintain code (just like Classic ASP).
Don
Don Demsak on February 6, 2010 9:47 PMJames Shore ended with a great point, which underscores an underlying assumption we all bring to the table: what kind of code are you working on?
TDD is irrelevant when you're doing production support on legacy code. Tests can be introduced over time, but when there's an urgent issue in a production application, you need a debugger. E'n'C is especially useful when you're trying to understand system response to varying inputs, since the time lag between input and response is eliminated. Then, armed with a clearer understanding of the system, you can go higher level and make the right fix. You might just want to write a test at that point, too...
The point is that you can't even write a test when you don't even know the intended purpose of the code you're working on, or when you can't trust it (a ProcessOrder() function that's evolved over time to include new functionality, etc.). E'n'C can help the TDD process in this case; it's not one or the other.
So, back to my original point: Are you architecting new systems? You'll bring that bias to this discussion. Is the bulk of your experience in working on codebases you didn't write? Biased towards production support oriented tools. Even generalists are biased towards their most recent pain point.
Jon Galloway on February 6, 2010 9:47 PMThe comments to this entry are closed.
|
|
Traffic Stats |