Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Erlang, is there a way to create an empty function?

I'm writing an Erlang function which prints every even number up to a given parameter.

So far, I've written the function with guards like this:

printEven(I,N) when I < N ->
  if
    I rem 2 == 0 -> io:format("~p~n",[I]), printEven(I+1,N);
    I rem 2 == 1 -> printEven(I+1,N)
  end;
printEven(I,N) ->
   io:format("Done").

I'd really like to have the last case just exit automatically and not have to print anything in the function. I've tried just removing it, but then an error occurs since when the recursion is done, an error is thrown.

How can I do this? Is there something like a 'pass' or 'yield' keyword in erlang?

like image 793
samoz Avatar asked Jul 14 '09 17:07

samoz


1 Answers

OK, first define the function:

printEven(I,N) when I >= N -> ok;
printEven(I,N)             -> 
   if
    I rem 2 == 0 -> io:format("~p~n",[I]), printEven(I+1,N);
    I rem 2 == 1 -> printEven(I+1,N)
  end.

Erlang is a functional programming language and (by definition) functions 'have' a value so you are going to get 'something' back. By convention the thing you get back on completion of a function that you are using for side-effects is the atom 'ok', that's the best to use here.

You can 'silently discard' the return value if you want. You do that when you invoke the function by pattern matching to the 'don't care' variable (which is underscore):

_ = printEven(3,9),

or by calling the function without a pattern match:

printEven(3,9),

However, you are much better to always check return values by pattern matching when you invoke a function:

ok = printEven(3,9),

This is a a really good habit to get into because you will be using a lot of library functions that return error codes as you can see from their specs:

@spec funky(X) -> [ok | {error, bad_op} | {error, wig_out}]

If funky has side effects you want to know it has failed now by invoking it with a pattern match so it will crash here and now if funky fails:

ok = funky(99),

If you match it to '_' or ignore the return value it will crash 268 lines later when your mojo expects funky to have done his thang, and then it is much harder to find.

This is happy path programming which is the done thing in Erlang. "Let it crash" is the motto. If you are new to Erlang you will find this very disconcerting - like walking about naked. Don't worry embrace it, it is a good thing. It leads to lots of code 'not being written'.

(You should also get in the habit of putting the clause that ends the recursion as the top clause as shown here - it makes reading the code sooo much easier when you have a multi-clause function.)

like image 182
Gordon Guthrie Avatar answered Oct 10 '22 05:10

Gordon Guthrie