Defensive programming

Ryan Rawson ryanobjc@REDACTED
Wed Mar 29 01:28:42 CEST 2006


I think Erlang is a wonderful language because it allows you to write
defensively without littering your code with crap that doesn't serve
any real purpose.  When I say "real purpose" I mean if you can remove
code without affecting the functionality or error handling, how can it
be useful?

In erlang you can take advantage of the fact that a unmatched pattern
is a fault, and let the normal Erlang process kill/supervisor
trees/error logging handle it for you.  As an added bonus you know the
exact value which failed to match and which function it failed in. 
Your "defensive" code sample doesn't have those advantages.

So what I'm saying is bringing legacy-C coding style (clearly the
first snippet is inspired by "check every return value if/then/else"
style of C) actually obscures the true meaning of the code, AND it
actually makes your system less defensive and debuggable.

Best to stick with the simple second style.

And this is why I love Erlang - you get to have simple code that is in
fact more robust than the "robustly coded" examples.

-ryan

On 3/28/06, Pupeno <pupeno@REDACTED> wrote:
> Hello,
> I am used to defensive programming and it's hard for me to program otherwise.
> Today I've found this piece of code I wrote some months ago:
>
> acceptor(tcp, Module, LSocket) ->
>     case gen_tcp:accept(LSocket) of
>         {ok, Socket} ->
>             case Module:start() of
>                 {ok, Pid} ->
>                     ok = gen_tcp:controlling_process(Socket, Pid),
>                     gen_server:cast(Pid, {connected, Socket}),
>                     acceptor(tcp, Module, LSocket);
>                 {error, Error} ->
>                     {stop, {Module, LSocket, Error}}
>             end;
>         {error, Reason} ->
>             {stop, {Module, LSocket, Reason}}
>     end;
>
> is that too defensive ? should I write it this way
>
> acceptor(tcp, Module, LSocket) ->
>     {ok, Socket} = case gen_tcp:accept(LSocket),
>     {ok, Pid} = Module:start()
>     ok = gen_tcp:controlling_process(Socket, Pid),
>     gen_server:cast(Pid, {connected, Socket}),
>     acceptor(tcp, Module, LSocket);
>
> ?
>
> Thanks.
> --
> Pupeno <pupeno@REDACTED> (http://pupeno.com)
>
>
>



More information about the erlang-questions mailing list