views:

199

answers:

3

I have read about how the fail-fast style of programming in languages like Erlang end up with much shorter programs than the defensive style found in most other languages. Is this correct for all types of programs and what is the reasoning for this?

A: 

The fail-fast style of programming is focused on better code readability and debugging. The user experience is a secondary target: a user may experience strange error messages or program failures, but the greater quality of code allows programmers to easily find the bug and correct the issue.

Defensive style programming, instead, focuses on validation input from user and from other portions of code. The code is more verbose, because the programmer has to carefully verify input and fail gracefully in case of error. This lead to more code (from the programmers' point of view) and a more robust application (from the users' point of view).

frm
Not correct. You are confusing fail-fast style with no-error-handling style. Fail-fast style still allows your program to catch errors and recover from them without bothering the user.
Deestan
Obviously, the user also reaps the benefits of less buggy software with the failfast style. I would rather say failfast is about clarity in what is correct input and what is incorrect input, and actually enforcing this. Clarity invariably yields better programming. Errors in input should be flagged as such (instead of having the app limp on into undefined land), but that doesn't prevent the app from handling this error elegantly and intuitively. I think you're setting up a false dichotomy.
harms
Wrong answer. In the context of Erlang, for which the question was asked, the more robust approach is to avoid defensive programming and just let the offending process "crash". Another process will take the appropriate actions to recover. In Java, which you appear to have experience, you have no choice but to be defensive because it's an imperative language with a shared-state concurrency model. Since Erlang is a functional language with message-passing concurrency, and because there are mechanisms to communicate faults between processes it is perfectly fine and preferable to fail-fast.
dsmith
So... I have a lot to learn!
frm
You do indeed, frm, but you've taken the first step: accepting input. You didn't let your pride interfere with your growth. Kudos.
JUST MY correct OPINION
+3  A: 

See sections 4.3 and 4.4 of Joe Armstrong's thesis.

dsmith
+7  A: 

Fail-fast programs aren't necessarily shorter than defensive style programs: it depends on the implementation and the measures needed to make your defensive code safe.

In the case of Erlang, the fail-fast programs are usually shorter because of the declarative style and how the VM makes sure to generate error cases for you. As an example, in the function:

day(1) -> sunday;
day(2) -> monday;
day(3) -> tuesday;
day(4) -> wednesday;
day(5) -> thursday;
day(6) -> friday;
day(7) -> saturday;

Any unexpected value passed to the function will result in an error that can be caught and handled by another process (ie.: a supervisor). Such errors will also never endanger the system as a whole and don't require code to be added to the function itself -- it's all done outside of the normal execution path by predetermined behaviors.

In a dynamic language where fail-fast isn't the norm, you would have to manually check the boundaries and throw an exception yourself. Then you must catch the exception locally (top-level try ... catches included) if you don't want the whole system to go down. The error handling code usually has to be inserted throughout the normal execution path.

In a static language where fail-fast isn't the norm, then how long your code will be will highly depend on the type system you have. If the language allows to define types where the edge cases end up checked for you by the compiler, then you usually do not have to handle this inside the code, outside of nondeterministic events (files not working, unexpected user input, etc.) In languages with such type systems, many errors will be caught before runtime and so you won't have as many defensive cases.

When error handling can't be avoided, languages supporting fail-fast idioms (like Erlang) will allow for arguably clearer code than languages that don't (static or not), mainly because the code for special cases isn't mixed in with the code for the ideal execution path.

I GIVE TERRIBLE ADVICE