Question: Why I can't to use `String` or other module in guard?

Code:

```
def foo(s1, s2) when String.length(s1) == String.length(s2) do 
   # something
end

```

And how I can elegantly reformat such case, when I wish to use module functions?

Answer: 
From the [erlang docs](http://erlang.org/doc/reference_manual/expressions.html#id83710):

> 
> The set of valid guard expressions (sometimes called guard tests) is a subset of the set of valid Erlang expressions. The reason for restricting the set of valid expressions is that evaluation of a guard expression must be guaranteed to be free of side effects.
> 
> 
> 

The same is also true for Elixir.

The good news is, for your particular use case, there is a guard that will work:

```elixir
def foo(s1, s2) when byte_size(s1) == byte_size(s2) do 

```

Typically when what you want to do can't be used in a guard, you need to check inside the function, for example:

```elixir
def foo(s1, s2) do 
  cond do 
    String.length(s1) == String.length(s2) -> # Do something
    true                                   -> # Do something else
  end
end

```

The following answer explains defining your own guard with macros [Create new guard clause](https://stackoverflow.com/questions/21261696/create-new-guard-clause/21267375#21267375) (the guard must use the valid guard functions documented in <http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses>)
```
byte_size(s1) == byte_size(s2)

```

does not have the same meaning of

```
String.length(s1) == String.length(s2)

```

It only does so for characters composed of a single byte.

```
iex(1)> String.length("hello") == String.length("helló")
true
iex(2)> byte_size("hello") == byte_size("helló")
false

```

For the correct behavior, you have to manually dispatch:

```
def foo_same(s1, s2) do 
   # something
end

def foo_different(s1, s2)do 
   # something
end

def foo(s1, s2) do
  if String.length(s1) == String.length(s2) do
    foo_same(s1, s2)
  else
    foo_different(s1, s2)
  end
end

```