Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

[Disclaimer: this question is subjective, but I would prefer getting answers backed by facts and/or reflexions]

I think everyone knows about the Robustness Principle, usually summed up by Postel's Law:

Be conservative in what you send; be liberal in what you accept.

I would agree that for the design of a widespread communication protocol this may make sense (with the goal of allowing easy extension), however I have always thought that its application to HTML / CSS was a total failure, each browser implementing its own silent tweak detection / behavior, making it near impossible to obtain a consistent rendering across multiple browsers.

I do notice though that there the RFC of the TCP protocol deems "Silent Failure" acceptable unless otherwise specified... which is an interesting behavior, to say the least.

There are other examples of the application of this principle throughout the software trade that regularly pop up because they have bitten developpers, from the top off my head:

  • Javascript semi-colon insertion
  • C (silent) builtin conversions (which would not be so bad if it did not truncated...)

and there are tools to help implement "smart" behavior:

However I find that this approach, while it may be helpful when dealing with non-technical users or to help users in the process of error recovery, has some drawbacks when applied to the design of library/classes interface:

  • it is somewhat subjective whether the algorithm guesses "right", and thus it may go against the Principle of Least Astonishment
  • it makes the implementation more difficult, thus more chances to introduce bugs (violation of YAGNI ?)
  • it makes the behavior more susceptible to change, as any modification of the "guess" routine may break old programs, nearly excluding refactoring possibilities... from the start!

And this is what led me to the following question:

When designing an interface (library, class, message), do you lean toward the robustness principle or not ?

I myself tend to be quite strict, using extensive input validation on my interfaces, and I was wondering if I was perhaps too strict.

share|improve this question
    
I wonder what is the difference between HTML and general data? The robustness principle is about communication. One writes - one reads. Why network communication is different than visual or API? I have an API example where the principle of being liberal at what we accept simplifies the life of users who are programmers, reduces the code size and, therefore, improves performances + eliminates bugs. Look stackoverflow.com/questions/18576849 –  Val Sep 2 '13 at 16:37
    
@Val: actually, your example does not match. "being liberal in what you accept" is not just a matter of base/derived, it is going beyond that and also accepting (and interpreting) slightly erroneous inputs. –  Matthieu M. Sep 2 '13 at 16:38
    
How showing some case does not show that case? –  Val Sep 2 '13 at 16:40
add comment

10 Answers

up vote 18 down vote accepted

I would say robustness when it doesn't introduce ambiguities.

For example: When parsing a comma separated list, whether or not there's a space before/after the comma doesn't change the semantic meaning.

When parsing a string guid it should accept any number of the common formats (with or without dashes, with or without surrounding curly braces).

Most programming languages are robust with white space usage. Specifically everywhere that it doesn't affect the meaning of code. Even in Python where whitespace is relevant, it's still flexible when you're inside of a list or dictionary declaration.

I definitely agree that if something can be interpreted multiple ways or if it's not 100% clear what was meant then too much robustness can end up being a pain though, but there's much room for robustness without being ambiguous.

share|improve this answer
1  
I agree, robustness when it doesn't cost much is worthwile. –  Matthieu M. Oct 16 '10 at 18:04
2  
Even the comma separated list causes problems, kind of: chrome's and firefox's javascript engine seem to accept {"key": "value",} as valid, IE does not. I often stumbled upon this particular problem until i improved my build process with JSlint. –  keppla Jul 22 '11 at 8:27
2  
@keppla that's an issues with implementation rather than design. I'm not sure if that's legal by the javascript spec and IE isn't following, or if that's a "nice feature" that FF and Chrome added, but in Python it's specified to be valid and implemented as such. If it's specified as valid and it doesn't work, then it's a faulty implementation. If it's not specified then it shouldn't really be relied upon (although as a matter of practicality if it doesn't work in a major browser it might as well be considered not in the spec if you don't control the user) –  Davy8 Jul 22 '11 at 11:45
5  
@Davy8: Trailing comma seem to be illegal (stackoverflow.com/questions/5139205/…). I dont want to rely on this, my point is, when enough people accept the input, it becomes de-facto standard (because one does not notice that it is an error), which leads to something we encountered in HTML: that the errors become so commonplace that you cannot ignore them as bad input anymore. –  keppla Jul 22 '11 at 11:59
    
@keppla I agree completely. If different browser implement it differently it becomes ambiguous via implementation. I was speaking more from a design perspective rather than implementation. On the other hand though developers should program to the spec when at all possible. For instance there are types of collections where order isn't guaranteed but it may follow a specific ordering based on an implementation detail that isn't part of the spec. –  Davy8 Jul 22 '11 at 13:07
show 1 more comment

IMO, robustness is one side of a design trade-off not a "prefer" principle. As many have pointed out, nothing stinks like blowing four hours trying to figure out where your JS went wrong only to discover the real problem was only one browser did the proper thing with XHTML Strict. It let the page go to pieces when some portion of the served HTML was a complete disaster.

On the other hand, who wants to look up documentation for a method that takes 20 arguments and insists they be in the exact same order with empty or null value place holders for the ones you want to skip? The equally awful robust way to deal with that method would be to check every arg and try to guess which one was for what based on relative positions and types and then fail silently or try to "make do" with meaningless args.

Or you can bake flexibility into the process by passing an object literal/dictionary/key-value pair list and handle the existence of each arg as you get to it. For the very minor perf tradeoff, that's a cake and eat it too scenario.

Overloading args in intelligent and interface-consistent ways is a smart way to be robust about things. So is baking redundancy into a system where it's assumed packet delivery will regularly fail to be delivered in a massively complicated network owned and run by everybody in an emerging field of technology with a wide variety of potential means for transmission.

Tolerating abject failure, however, especially within a system you control, is never a good tradeoff. For instance, I had to take a breather to avoid throwing a hissy fit in another question about putting JS at the top or bottom of the page. Several people insisted that it was better to put JS at the top because then if the page failed to load completely, you would still potentially have some functionality. Half-working pages are worse than complete busts. At best, they result in more visitors to your site rightly assuming you're incompetent before you find out about it than if the busted up page is simply bounced to an error page upon failing it's own validation check followed by an automated e-mail to somebody who can do something about it. Would you feel comfortable handing your credit card info over to a site that was half-busted all the time?

Attempting to deliver 2010 functionality on a 1999 browser when you could just deliver a lower tech page is another example of a foolhardy design tradeoff. The opportunities blown and money I've seen wasted on developer time spent on bug-ridden workarounds just to get rounded corners on an element hovering above a !@#$ing gradient background for instance, have completely blown me away. And for what? To deliver higher tech pages that perform poorly to proven technophobes while limiting you choices on higher end browsers.

In order for it to be the right choice, the choice to handle input in a robust manner should always make life easier on both sides of the problem, in the short and the long term IMO.

share|improve this answer
    
"for a method that takes 20 arguments" > no need to look further, after 5/6 the method is wrong. Thanks for the answer though :) –  Matthieu M. Apr 6 '12 at 6:04
add comment

I divide interfaces into several groups (add more if you like):

  1. those that are under your control should be strict (classes typically)
  2. library APIs, that should be also on strict side, but extra validation is advised
  3. public interfaces that must handle every kind of abuse that comes in (typically protocols, user inputs, etc). Here robustness on input really pays off, you can't expect everyone is going to fix their stuff. And remember for user it will be your fault if the application doesn't work, not the party who sent some ill-formatted crap.

Output must always be strict.

share|improve this answer
add comment

I do notice though that there the RFC of the TCP protocol deems "Silent Failure" acceptable unless otherwise specified... which is an interesting behavior, to say the least.

The TCP RFC's don't use the phrase "silent failure" so it is not clear exactly what you mean by this. However, if mean that it is acceptable for segments to be lost, that's essential for the protocol to work. After all, TCP is designed to provide reliable byte streams over a packet switching network that is inherently lossy.

share|improve this answer
add comment

Unfortunately the so called "robustness principle" doesn't lead to robustness. Take HTML as example. Much trouble, tears, waste of time and energy could have been avoided if browsers had strictly parsed HTML from the beginning instead of trying to guess the meaning of malformed content.

The browser should simply have displayed an error message instead of trying to fix it under the covers. That would have forced all the bunglers to fix their mess.

share|improve this answer
    
Quoting myself (must be getting old): "however I have always thought that its application to HTML / CSS was a total failure" –  Matthieu M. Nov 15 '11 at 13:31
    
True, but the very same fault tolerance also helped to make web so popular. –  MaR Nov 15 '11 at 16:58
    
The browser vendors failed on that one. With doctypes we had the ability to make our own choice in this very regard, but at the end of they day everything pretty much ended up behaving the same way as long as you had any doctype declared. Now they think a hyper-complex set of exacting rules to follow in regards to how to deal with failure is the solution? I think they're failing to identify the problem. –  Erik Reppen Apr 6 '12 at 0:00
    
You are saying that fail-fast, which is opposite of "robust" is more efficient. –  Val Sep 2 '13 at 16:36
add comment

Overapplication of Robustness leads to you guessing what the user wanted, which is fine right up till you get it wrong. It also requires the completely misguided faith that your customers won't abuse your trust and create random gibberish which just happens to work, but that you won't be able to support in version 2.

Overapplication of Correctness leads to you denying your customers the right to make minor errors, which is fine right up until they complain that their stuff works fine on your competitor's product, and tell you what you can do with your 5,000 page standard that has the word "DRAFT" still scrawled on the cover in crayon, and at least 3 experts claim is fundamentally flawed, and 200 more honest experts say they don't fully understand.

My personal solution has always been deprecation. You support them, but tell them they're doing wrong, and (if possible) the easiest path to correctness. That way, when you turn the bug-feature off 10 years down the line, you at least have the paper trail to state that "we warned you this might happen."

share|improve this answer
    
+1 for deprecation, it is indeed an important concept and I am surprised that it was overlooked up until now. –  Matthieu M. Nov 15 '11 at 12:11
add comment

Definitely not. Techniques such as defensive programming obscures bugs, making their appearance less likely and more random which makes their detection harder which makes isolating them more difficult.

The vastly under-rated Writing Solid Code was tremendous in repeatedly emphasizing the need, and techniques, of making bugs as difficult to introduce or hide. Through application of its principles such as, "Eliminate random behavior. Force bugs to be reproducible." and, "Always look for, and eliminate, flaws in your interfaces." developers will vastly improve the quality of their software by eliminating the ambiguity and uncontrolled side-effects that is responsible for a large quantity of bugs.

share|improve this answer
add comment

You're right, the rule applies to protocols, and not programming. If you make a typo while programming, you'll get an error as soon as you compile (or run, if you're one of those dynamic types). There's nothing to be gained by letting the computer guess for you. Unlike the common folk, we are engineers and capable of saying exactly what me mean. ;)

So, when designing an API, I would say don't follow the Robustness Principle. If the developer makes a mistake, they should find out about it right away. Of course, if your API uses data from an outside source, like a file, you should be lenient. The user of your library should find out about his/her own mistakes, but not anyone else's.

As an aside, I would guess that "silent failure" is allowed in the TCP protocol because otherwise, if people were throwing malformed packets at you, you would be bombarded with error messages. That's simple DoS protection right there.

share|improve this answer
    
"If you make a typo while programming, you'll get an error as soon as you compile " I present to you the millions of compiler WARNINGS a standard compiler will spit out, while still producing perfectly executable tasks. –  deworde Nov 15 '11 at 11:11
add comment

As a counterpoint to Mason's example, my experience with the Session Initiation Protocol was that while different stacks would interpret the relevant RFCs differently (and I suspect this happens with every standard ever written), being (moderately) liberal in what you accept means that you can actually make calls between two devices. Because these devices are usual physical things as opposed to pieces of software on a desktop, you simply have to be liberal in what you accept, or your phone can't call another phone of a particular make. That doesn't make your phone look good!

But if you're writing a library, you probably don't have the problem of multiple parties interpreting a common standard in mutually incompatible ways. In that case, I'd say be strict in what you accept, because it removes ambiguities.

The Jargon File also has a horror story on "guessing" a user's intent.

share|improve this answer
    
Very amusing story :) I realize that you might need more leeway when you try to interact with existing systems, since if it doesn't work you'll be blamed. –  Matthieu M. Oct 16 '10 at 16:24
    
In fact, if your phone doesn't work with most other phones, your phone is bad. –  SamB Mar 28 '11 at 21:33
    
@SamB: Replace bad with broken. –  deworde Nov 15 '11 at 10:54
add comment

I think that HTML and the World Wide Web have provided a wide-scale real-world test of the Robustness Principle and shown it to be a massive failure. It's directly responsible for the confusing mess of competing HTML almost-standards that makes life miserable for Web developers (and their users) and gets worse with every new Internet Explorer release.

We've known since the 1950s how to validate code properly. Run it through a strict parser and if something isn't syntactically correct, throw an error and abort. Do not pass go, do not collect $200, and for the love of all that is binary do not let some computer program attempt to read the coder's mind if he made a mistake!

HTML and JavaScript have shown us exactly what happens when those principles are ignored. Best course of action is to learn from their mistakes and not repeat them.

share|improve this answer
1  
I think you may be dramatizing the level of failure. OK yes it is annoying for developers to work with sometimes but it isn't all that bad. With the release of version 8, Internet Explorer has reached a very reasonable level of compliance although they can do much better. –  ChaosPandion Oct 16 '10 at 13:58
3  
@ChaosPandion: the problem is not lying with Internet Explorer itself I think, but with all the non-standard web pages that were accepted by previous versions and that everyone now has to live with... and try to accomodate more or less successfully. –  Matthieu M. Oct 16 '10 at 14:10
2  
I actually think the IE team are in the worst possible position of all the browser developers. Joel sums up my thoughts pretty nicely. –  Dean Harding Oct 16 '10 at 23:22
2  
Also, while the Robustness principle may make life hard for Web Developers, it's hard to call the World Wide Web (now an integral part of almost every major institution on the planet) a massive FAILURE. –  deworde Nov 15 '11 at 10:47
2  
"We've known since the 1950s how to validate code properly. Run it through a strict parser and if something isn't syntactically correct, throw an error and abort." To apply this to a real world scenario: If I've screwed up a single icon on the far right of my page just below the cut, giving up on the whole page is a really good way to send someone looking elsewhere, because of a problem they wouldn't even have noticed. Yes, you can argue I shouldn't have made the mistake. But that rather presupposes I haven't already gone to your more robust competitor and am no longer taking your calls. –  deworde Nov 15 '11 at 10:51
show 9 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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