Defguardm that can take multiple arguments?

Would having defguardm that can take multiple arguments be useful ? I am writing a small db wrapper and there are multiple functions that take similar sets of arguments but not sure how frequent this use case would be in general.

What would its usage look like? As far as I am aware you can define guards with multiple arguments today.

defguard are_blah(arg1, arg2) when is_atom(arg1) and is_map(arg2)

def foo(arg1, arg2) when are_blah(arg1, arg2) do
...
end

def bar(arg1, arg2) when are_blah(arg1, arg2) do
...
end

You could just pass a tuple to defguard/1 like so:

defguard are_blah(values) when is_tuple(values)
    and elem(values, 0) |> is_atom()
    and elem(values, 1) |> is_map()

def foo(arg1, arg2) when are_blah({arg1, arg2}) do
...
end

def bar(arg1, arg2) when are_blah({arg1, arg2}) do
...
end

I tested this with a tuple but I think you could probably use a map, keyword list, or any other term.

1 Like

thnx good point

This works as is:

iex(1)> defmodule M do
...(1)> defguard g(a1, a2) when is_atom(a1) and is_map(a2)
...(1)> def foo(a1, a2) when g(a1, a2), do: true
...(1)> def foo(_, _), do: false
...(1)> end
{:module, M,
 <<70, 79, 82, 49, 0, 0, 6, 212, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 195,
   0, 0, 0, 22, 8, 69, 108, 105, 120, 105, 114, 46, 77, 8, 95, 95, 105, 110,
   102, 111, 95, 95, 6, 109, 97, 99, 114, ...>>, {:foo, 2}}
iex(2)> M.foo(:atom, %{})  
true
iex(3)> M.foo(:atom, :atom)
false
2 Likes

Dah I guess had some error when was trying it out it does work thanx