I'm reading the naming convention for Elixir. It states:
The names of predicate functions that cannot be used within guards should have a trailing question mark (?) rather than the is_ (or similar) prefix.
Hence, what kind of functions can't be used in guard?
All three of those functions contain expressions that are valid in guards; it's just that custom guards must be written as macros, not normal functions:
defmodule User do
defstruct age: 0
defmacro kid?(age) do
quote do
6 < unquote(age) and unquote(age) < 12
end
end
defmacro teen?(age) do
quote do
12 < unquote(age) and unquote(age) < 18
end
end
defmacro elder?(age) do
quote do
60 < unquote(age)
end
end
end
defmodule Greeting do
import User
def greet(%{age: age}) when kid?(age), do: "Hiya"
def greet(%{age: age}) when teen?(age), do: "Whatever"
def greet(%{age: age}) when elder?(age), do: "You kids get off my lawn"
def greet(_), do: "Hello"
end
for age <- [0, 5, 10, 15, 20, 90] do
IO.inspect {age, Greeting.greet(%{age: age})}
end
Output:
{0, "Hello"}
{5, "Hello"}
{10, "Hiya"}
{15, "Whatever"}
{20, "Hello"}
{90, "You kids get off my lawn"}
From the Elixir 1.7.3 documentation: (bold is mine)
As mentioned before, only the expressions listed in this page are allowed in guards. However, we can take advantage of macros to write custom guards that can simplify our programs or make them more domain-specific. At the end of the day, what matters is that the output of the macros (which is what will be compiled) boils down to a combinations of the allowed expressions.
and from Naming Conventions doc,:
Trailing question mark (foo?) Functions that return a boolean are named with a trailing question mark. Examples: Keyword.keyword?/1, Mix.debug?/0, String.contains?/2 However, functions that return booleans and are valid in guards follow another convention, described next.
is_ prefix (is_foo) Type checks and other boolean checks that are allowed in guard clauses are named with an is_ prefix. Examples: Integer.is_even/1, Kernel.is_list/1 These functions and macros follow the Erlang convention of an is_ prefix, instead of a trailing question mark, precisely to indicate that they are allowed in guard clauses. Note that type checks that are not valid in guard clauses do not follow this convention. Examples: Keyword.keyword?/1, Regex.regex?/1
So, using one of the listed expressions that returns a boolean
is ok for write compliant guard macros (if they haven't side effects).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With