0

Why can't I put any code to the guard clauses in the elixir? Like:

def index(a) when is_list(a) && Enum.all?(a, fn(x) -> x >= 0 end) do

Yeah, I know about official guard clauses doc at the elixir website, but there is no explanation why can't I do this. Why these restrictions on what can I place to guard clauses exists?

Could somebody explain it to me, please?

Alex Antonov
  • 14,134
  • 7
  • 65
  • 142

1 Answers1

1

From what I remember reading is that guard clauses are meant to be exactly that - a piece of code that determines whether or not this function is the right one to be envoked based on the given params.

It's not meant to a place to run blocks of code that are computationally heavy, but rather a lightweight check which can resolve a true or false answer relatively quickly.

For example, with the code you gave, what happens if your list is 10 Billion elements long? The compiler would have to check every single element in the list before it even executed the code in method. Now imagine if you had a another one that was

when Enum.all?(a, &(&1 * 2 > 3)).

The compiler would then have to run both guard clauses and check every element of the list for both (if the first one failed), which basically is going to take a long time.

Harrison Lucas
  • 2,829
  • 19
  • 25
  • Well the lightweight argument can easily be refuted because you can use `length/1` in a guard which is `O(n)`. – Dogbert Sep 05 '16 at 04:56
  • @Dogbert yeah I get what you mean, and like I said, I'm not 100% certain if thats the reason why, I just remember reading it somewhere. However -> isn't length still lightweight compared to doing e.g. `Enum.all?(a, &(String.jaro_distance("string", &1) > 0.9 )` ? – Harrison Lucas Sep 05 '16 at 06:15
  • @Dogbert ah, just saw the reasons listed in the duplicated Erlang answer and it makes more sense then what I said. – Harrison Lucas Sep 05 '16 at 06:17